VlogMe / For developers
REST API and MCP workflows
Connect Director and Studio workflows through REST API and MCP, pass prompts and media references, track jobs, and keep results in the shared Lab — the same workflows you run in the VlogMe app.
On this page
How the API works
The REST API and the MCP server run the same jobs as the VlogMe app — Director, Video, Image and Audio Studio, Aisma, DUB and News Videos — on the same account, the same credit balance and the same Lab.
Access: API and MCP are available to every registered VlogMe account. Create a key in Account → API & MCP; no support approval is needed. For volume or an integration for your team, write to sales@vlogme.ai.
An integration then follows five steps:
- Create an API key in Account → API & MCP.
- Upload the photo, video or audio a job needs, or reuse a file from Lab.
- Quote the job: VlogMe returns its exact credit price.
- Start the job with that quote. It never runs at a different price.
- Track it by polling or with a webhook; the results are saved to Lab.
Agents can do the same through the MCP server: its tools cover jobs, the Director, Lab files, projects, templates, voices, News Videos and social publishing, with the same key, balance and checks as REST.
Changes to the API and MCP are announced in the development journal.
API keys and access
Every request carries a key in the Authorization header:
Authorization: Bearer vma_…
- A key can do what you ticked when you made it in Account → API & MCP:
- read: list your Lab files, jobs and balance, and ask for a quote. Every key has it.
- write: upload and import files, rename and archive them, save projects, plan and prepare with the Director, and start paid jobs at their quoted price.
- delete: delete files, projects, voice clones and news monitors. Deleting cannot be undone.
- share: create and revoke public share links.
- publish: publish or schedule videos on your connected social accounts.
- Keys made before these choices keep what they could do: a “Read” key reads, and a “Read and create jobs” key also deletes and shares, as before.
- A request the key may not make is refused with
403andcode: scope_missing.GET /api/meshows the key’s owntoken.scopes. - A key expires after 1 to 365 days (90 by default). Revoke it at any time in Account → API & MCP: integrations that use it stop at once.
- A key cannot change your plan, create other keys, delete your account or open the admin tools; those need a signed-in session (
code: session_required).
Keep keys secret: they act for your account and spend its credits (Terms of Service).
Discover jobs and routes
Two public addresses describe everything an integration can send. They need no key.
GET /api/cataloglists every jobkind(with its workflow or model): its input as JSON Schema, the Lab files it takes, its durations, aspect ratios and qualities, its price rule, an example input with the example’s price in credits, and whether it is available now.?kind=videoor?kind=video&workflow=fal_veo31_i2vnarrows the list. It also holds the Director’s schemas: a new project, an edit command, a chat turn and a preparation.GET /api/openapi.jsonis the OpenAPI 3.1 description of the REST API. Each operation’sx-scopenames the key scope it needs.
Fields an entry lists under server_fills, such as the length of a video, are measured by VlogMe from your file, so you can leave them out.
Quote, start and track a job
A job is one piece of work: a clip, an avatar, an image, a voice track, an edit, a dub, an Aisma change, a News Videos video or a Director render. Its kind is one of video, avatar, image, audio, video_edit, dub, trend, aisma, voice_clone, director, and its input holds the settings of the matching screen in the app.
Ordinary Image Editor changes export in the browser and are not a server job. For AI image generation and edits, use kind: image with the matching workflow.
| Request | What it does |
|---|---|
POST /api/jobs/quote | Returns credits, the priced parts and a quote_fingerprint for a kind and input |
POST /api/jobs | Starts the job with the quoted_credits and quote_fingerprint of its quote; an Idempotency-Key header (a UUID) makes a retry return the same job instead of starting a second one |
GET /api/jobs | Your jobs, newest first. Filter with kind, status and project_id; page with limit (up to 100) and the returned next_cursor; fields=compact leaves the inputs out |
GET /api/jobs/{id} | The job's status, its results (the Lab files it made) and any warnings. Add ?wait=30 to wait up to that many seconds for the job to end |
For example, quote an image and then start it:
curl https://vlogme.ai/api/jobs/quote \
-H "Authorization: Bearer $VLOGME_KEY" \
-H "Content-Type: application/json" \
-d '{"kind": "image", "input": {…}}'
curl https://vlogme.ai/api/jobs \
-H "Authorization: Bearer $VLOGME_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2b8e-7d4a-4f0e-9b1a-2c3d4e5f6a7b" \
-d '{"kind": "image", "input": {…}, "quoted_credits": 12, "quote_fingerprint": "…"}'
If the price or the inputs changed since the quote, the start is refused with 409 and nothing is charged: ask for a new quote. A job that fails returns its eligible credits to your balance automatically. A job cannot be cancelled once it starts, because providers cannot always stop one.
Make a Director video
A key with the write scope can take a video from an idea to the finished file:
POST /api/director/projectswith{"version": 2, "concept": "…"}creates the project.POST /api/director/projects/{id}/turnswith a newclient_request_idand the project’sbase_revisionasks the Director to plan it.GET /api/director/turns/{turn id}?wait=30waits until the plan is ready or the Director asks a question; answer it withPOST /api/director/turns/{turn id}/answer.POST /api/director/projects/{id}/preparemakes the free pictures, voices and music, andGET /api/director/projects/{id}/viewshows what is ready. They take a while: read/viewagain until each of itsmaterialsisready.POST /api/director/projects/{id}/render/quoteprices the video (remake_scene_numbersmakes chosen scenes again), andPOST /api/director/projects/{id}/renderwith thatrevision,quoted_credits,quote_fingerprintand anIdempotency-Keystarts it. If the plan changed since the quote, the start is refused with409(code: revision_conflict) and nothing is charged.GET /api/jobs/{job id}?wait=30until the job ends; thenGET /api/director/projects/{id}/resultgives the video and its subtitles with links that last 15 minutes.
Planning, chat and free preparation through a key use the same free allowance as the app on your account: an agent that plans a lot uses it up for the app too. When it is used up for now, the answer says limited: true.
Pictures past the free allowance come back from /prepare under charged, with their price. Quote them with POST /api/jobs/quote (kind director, input {"v": 2, "stage": "materials", "project_id": "…", "revision": 3, "keys": ["…"]}) and start them like any paid job. A new take of a picture that is already made (Try again) sends "regenerate": true in that same input, in both the quote and the start.
To change the plan, send a message to /turns (with scope.block_ids to change some scenes only), or a structured edit to POST /api/director/projects/{id}/edits that follows director.edit_command_schema in GET /api/catalog. POST /api/director/projects/{id}/undo restores an earlier revision. Each change carries the base_revision you read and a new client_request_id: a stale revision is refused with 409, and a repeated client_request_id replays the change instead of making it twice.
Files you attach to a plan need rights_confirmed: true. Sent through a key, it is your own confirmation that you have the rights to use the files and the people in them (Terms of Service).
Lab files: upload, import and download
GET /api/assetslists your Lab files, newest first.section=mainis Files (finished videos, results and uploads),workingthe files a project uses while it is made,archivedthe archive, andall(the default) every file that is not archived. Filter withkind,project_id(ornone) andq;fields=compactleaves the metadata out; page withlimitand the returnednext_offset.GET /api/assets/working-projectsgroups Working files by project.POST /api/assets/intentwithmime_type,bytesandtitlereserves a Lab file and returns a resumable (tus) upload address and token. Images: JPEG, PNG, WebP, BMP. Video: MP4, MOV, M4V, up to 150 minutes. Audio: MP3, M4A, WAV, OGG. Up to 1 GB per file.- Add
content_sha256(the file's SHA-256 as 64 lowercase hex characters) and a file you already uploaded is reused: the answer is200withreused: trueand that file, and there is nothing to upload. Sendallow_duplicate: trueas well to keep a second copy. POST /api/assets/{id}/completechecks the upload and makes the file ready to use in a job'sinput.- With an API key, the intent also returns
put_url: one signed address that takes the whole file in a singlePUT(curl -T clip.mp4 -H "Content-Type: video/mp4" "$put_url"), instead of tus. AnIdempotency-Keyheader (a UUID) makes a retry return the same file. POST /api/assets/importwith{"url": "https://…"}and anIdempotency-Keyfetches a file from a public HTTPS address in the background. The answer is202with the new file’s id;GET /api/assets/{id}then showsimport.statusuntil the file is ready, orfailedwith anerror_code. Addresses of VlogMe itself, private networks and IP addresses are refused.PATCH /api/assets/{id}withtitlerenames a file, and witharchived: truemoves it to Archived (falserestores it); files a project uses while it is made stay in Working files.DELETE /api/assets/{id}deletes a file for good (the delete scope). A file that a running job still needs is refused with409.GET /api/assets/working-projects/{id}/cleanupshows what Clean up would delete in one project (earlier takes, unused pictures, leftovers), with the reason for each file.POSTto the same address withasset_idsfrom that preview deletes up to five of them per request (the delete scope). Nothing is ever deleted automatically.GET /api/assets/{id}/downloadreturns a private link that lasts 60 seconds;ttlasks for up to an hour, andredirect=1answers with a redirect to the file, socurl -Ldownloads it.
Files uploaded through the API stay private in your Lab, like the files you upload in the app.
Projects, templates and voices
GET /api/projectslists your projects, newest first: Director projects (with their idea and a summary) and News Videos, Aisma, DUB and Image Editor drafts (with their saved data). Filter withkind; page withlimitand the returnednext_cursor.POST /api/projectswithkind,titleanddatasaves a new draft; anIdempotency-Keyheader makes a retry return the same draft.PUT /api/projects/{id}with the draft’s currentrevisionsaves a change, and an older revision is refused with409.DELETE /api/projects/{id}deletes a project (the delete scope); its Lab files stay.- Director projects are created with
POST /api/director/projects(see above), not as drafts. GET /api/templateslists the published Aisma templates (category,q,limit,cursor),GET /api/templates/{id}shows one, andPOST /api/templates/{id}/openwith anIdempotency-Keyopens it as a new project.GET /api/voiceslists the voices a job or a Director cast can use: premade voices and your ready voice clones.GET /api/voice-cloneslists your clones with their status, andDELETE /api/voice-clones/{id}deletes one, also at the voice provider (the delete scope).
News Videos and social publishing
GET /api/trends/search?q=…searches recent news (languageisenorru;country,category,domains,sort_by).POST /api/trends/scriptwrites a script for a story, grounded in its sources, andPOST /api/trends/verifychecks a script against them.- News monitors look for new stories on a schedule:
GETandPOST /api/trends/monitors,PUTandDELETE /api/trends/monitors/{id}. GET /api/social/connectionsshows your connected social accounts, andGET /api/social/publicationsyour publications with their status. Connecting an account needs a signed-in session in the app.POST /api/social/publicationswithasset_id(a ready video) andplatform, optionallycaption,headline,visibility,cover_asset_idandscheduled_at, and anIdempotency-Key, publishes or schedules the video. It needs the publish scope, which a key has only when you ticked it. A post is public: an agent should show you the video, the platform and the caption, and publish only after your explicit yes.POST /api/social/publications/{id}/cancelcancels a publication that has not gone out yet (the publish or write scope).- The video editor preview (
POST /api/video-editor/preview) answers an MP4 stream, so it is available through REST only.
Waiting: long-poll and webhooks
There are two ways to know when work is done.
Long-poll. GET /api/jobs/{id}?wait=30 and GET /api/director/turns/{id}?wait=30 wait up to that many seconds (0 to 30) for the job or the turn to end (a turn also stops when it asks a question), then answer it with waited_seconds. While it still runs, retry_after_s says when to ask again. An agent on a laptop, which cannot receive webhooks, waits this way.
Webhooks. Add webhook_url, a public HTTPS address, when you start a job with an API key, and VlogMe posts an event when the job ends:
{"id": "job.<job id>.succeeded", "type": "job.succeeded", "created_at": "…",
"job": {"id": "…", "kind": "image", "status": "succeeded", "result_asset_id": "…", "error_code": null}}
- The type is
job.succeeded,job.failedorjob.partial(some results are in Lab and the credits of the missing parts were returned). A job under review (needs_review) has not ended yet: its event follows when it does. - A partial job whose final assembly failed can be assembled again for free with
POST /api/jobs/{id}/reassemble. When that ends, a new event reports the outcome, also when the assembly fails again and the job stays partial. Each outcome has an event id of its own: a partial one ends with itserror_code(job.<job id>.partial.<error code>), followed by.retry<n>once n free assemblies have failed again;GET /api/jobs/{id}shows that count asreassembly_failures. - Each delivery carries
X-VlogMe-Event-Id,X-VlogMe-TimestampandX-VlogMe-Signature: v1=<hex>: an HMAC-SHA256 of<timestamp>.<body>whose key is the SHA-256 digest of your API key. Check the signature and reject old timestamps. - A delivery that does not get a 2xx answer is retried up to eight times, from 30 seconds apart to once an hour. Revoking the key stops its deliveries.
MCP server
AI agents that speak the Model Context Protocol connect to https://vlogme.ai/mcp (JSON-RPC 2.0 over HTTP POST) with the same Authorization: Bearer key; https://vlogme.ai/api/mcp is the same server at a second address. Supported protocol versions: 2026-07-28 (stateless, with the Mcp-Method and Mcp-Name headers and server/discover), and 2025-11-25, 2025-06-18 and 2025-03-26 (with initialize, which answers with the version the client asked for). A request without the MCP-Protocol-Version header is read as 2025-03-26. A request can be up to 1 MB.
The tools cover what a key can do through REST. Each tool needs the scope in the table. The tool list names every tool whatever the key’s scopes; a call the key may not make comes back as a refusal with code: scope_missing.
| Tool | Scope | What it does |
|---|---|---|
vlogme_account | read | Account and credit balance |
vlogme_get_catalog | read | Job catalogue |
vlogme_list_assets | read | List Lab files |
vlogme_get_asset | read | Lab file and download link |
vlogme_list_working_projects | read | Working files by project |
vlogme_create_upload | write | Start an upload |
vlogme_complete_upload | write | Finish an upload |
vlogme_import_asset | write | Import a file from a URL |
vlogme_update_asset | write | Rename or archive a file |
vlogme_delete_asset | delete | Delete a Lab file |
vlogme_share_asset | share | Share link on or off |
vlogme_preview_cleanup | read | Preview Clean up |
vlogme_cleanup_working_files | delete | Clean up working files |
vlogme_list_jobs | read | List jobs |
vlogme_get_job | read | Read a job |
vlogme_wait_job | read | Wait for a job |
vlogme_quote_job | read | Quote a job |
vlogme_create_job | write | Start a paid job |
vlogme_reassemble_job | write | Assemble a partial job again |
vlogme_list_projects | read | List projects |
vlogme_save_project | write | Save a draft |
vlogme_delete_project | delete | Delete a project |
vlogme_director_create | write | New Director project |
vlogme_director_get | read | Read a Director project |
vlogme_director_message | write | Ask the Director |
vlogme_director_turn | read | Read or wait for a turn |
vlogme_director_answer | write | Answer the Director |
vlogme_director_turn_action | write | Stop, apply or discard a turn |
vlogme_director_edit | write | Edit the plan |
vlogme_director_undo | write | Restore an earlier revision |
vlogme_director_prepare | write | Prepare pictures, voices and music |
vlogme_director_quote_render | read | Quote the video |
vlogme_director_render | write | Render the video |
vlogme_director_result | read | The finished video |
vlogme_list_templates | read | List templates |
vlogme_get_template | read | Read a template |
vlogme_open_template | write | Open a template |
vlogme_list_voices | read | List voices |
vlogme_delete_voice_clone | delete | Delete a voice clone |
vlogme_trends_search | read | Search the news |
vlogme_trends_discover | read | News suggestions |
vlogme_news_read_article | write | Read a complete news article |
vlogme_news_get_article | read | Saved article and citation paragraphs |
vlogme_trends_script | write | Write a News Videos script |
vlogme_trends_verify | write | Check a News Videos script |
vlogme_news_tasks | read | News tasks and shared budget |
vlogme_news_create_task | write | Create a news task |
vlogme_news_update_task | write | Change a news task |
vlogme_news_delete_task | delete | Stop and delete a news task |
vlogme_news_run_task | write | Prepare a manual news story |
vlogme_news_task_runs | read | News task run journal |
vlogme_social_status | read | Social accounts and posts |
vlogme_publish_video | publish | Publish a video |
vlogme_cancel_publication | publish / write | Cancel a publication |
- Tools that only read carry
readOnlyHint. Tools that delete carrydestructiveHint, and their description starts with “Irreversible.”; the description of a tool that makes something public starts with “Public.”, and paid tools say that they charge credits. An agent must confirm these calls with you first. - Arguments are checked against each tool’s schema. A wrong or unknown argument is refused before anything is sent, as a result with
isError: trueandcode: invalid_input. - Every list tool takes
limit(1 to 50, 20 by default) andcursor, and answersnext_cursor(nullon the last page). vlogme_wait_jobandvlogme_director_turnwait up to 30 seconds per call; call them again while the answer hasretry_after_s.- Resources:
resources/readservesvlogme://docs/agents(a guide for agents: from an idea to a video, the money rules, waiting and errors),vlogme://catalog(the job catalogue) andvlogme://openapi(the OpenAPI document).initializereturns short instructions with the same flows.
To start a job through MCP:
- Call
vlogme_quote_jobwithkindandinput, then review the returnedcredits. - Call
vlogme_create_jobwith the samekindandinput, a new UUIDidempotency_key,quoted_creditsset to the returnedcredits, and the unchangedquote_fingerprint. For Aisma, also pass the unchangedquote_prooffrom the quote. - If the quote expires or the price or inputs change, get a new quote and confirm it before trying again. Retry an accepted request with the same
idempotency_keyto receive the same job.
A Director video follows the same rule: vlogme_director_quote_render, show the price, then vlogme_director_render with that quote and an idempotency_key.
An optional webhook_url receives the job events described above. The MCP tools use the same API key, credit balance and price checks as REST.
For Codex, add the server to ~/.codex/config.toml and keep the key in the VLOGME_API_KEY environment variable:
[mcp_servers.vlogme]
url = "https://vlogme.ai/mcp"
bearer_token_env_var = "VLOGME_API_KEY"
tool_timeout_sec = 120
Limits and rules
- Jobs cost the same credits as in the app and come from the same balance; the quote is the price.
- An
Idempotency-Keyis a UUID. Reusing one for a different request is refused. - Aisma jobs need the
quote_prooftheir quote returns. It expires: quote again when it does. - Errors are JSON
{"error": "…", "code": "…"}with the HTTP status:400invalid input (invalid_input),403a request the key’s scopes do not allow (scope_missing,session_required),404not found,409the price, inputs or plan changed,429too many requests,503the service or a provider is temporarily unavailable. - Requests are rate limited. Past a limit the answer is
429withcode: rate_limitedand aRetry-Afterheader: wait that many seconds, then try again. - Through MCP, a refused tool call is not an HTTP error: it comes back as a tool result with
isError: truewhose content is the same JSON (error,statusand, when there is one,code). Only a missing or invalid key (401), an account without API access or a foreignOrigin(403) and a malformed request are HTTP errors there. - Work created through the API follows the Terms of Service like work made in the app.


