VlogMe

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
  1. How the API works
  2. API keys and access
  3. Discover jobs and routes
  4. Quote, start and track a job
  5. Make a Director video
  6. Lab files: upload, import and download
  7. Projects, templates and voices
  8. News Videos and social publishing
  9. Waiting: long-poll and webhooks
  10. MCP server
  11. Limits and rules

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:

  1. Create an API key in Account → API & MCP.
  2. Upload the photo, video or audio a job needs, or reuse a file from Lab.
  3. Quote the job: VlogMe returns its exact credit price.
  4. Start the job with that quote. It never runs at a different price.
  5. 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 403 and code: scope_missing. GET /api/me shows the key’s own token.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/catalog lists every job kind (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=video or ?kind=video&workflow=fal_veo31_i2v narrows the list. It also holds the Director’s schemas: a new project, an edit command, a chat turn and a preparation.
  • GET /api/openapi.json is the OpenAPI 3.1 description of the REST API. Each operation’s x-scope names 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.

RequestWhat it does
POST /api/jobs/quoteReturns credits, the priced parts and a quote_fingerprint for a kind and input
POST /api/jobsStarts 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/jobsYour 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:

  1. POST /api/director/projects with {"version": 2, "concept": "…"} creates the project.
  2. POST /api/director/projects/{id}/turns with a new client_request_id and the project’s base_revision asks the Director to plan it. GET /api/director/turns/{turn id}?wait=30 waits until the plan is ready or the Director asks a question; answer it with POST /api/director/turns/{turn id}/answer.
  3. POST /api/director/projects/{id}/prepare makes the free pictures, voices and music, and GET /api/director/projects/{id}/view shows what is ready. They take a while: read /view again until each of its materials is ready.
  4. POST /api/director/projects/{id}/render/quote prices the video (remake_scene_numbers makes chosen scenes again), and POST /api/director/projects/{id}/render with that revision, quoted_credits, quote_fingerprint and an Idempotency-Key starts it. If the plan changed since the quote, the start is refused with 409 (code: revision_conflict) and nothing is charged.
  5. GET /api/jobs/{job id}?wait=30 until the job ends; then GET /api/director/projects/{id}/result gives 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/assets lists your Lab files, newest first. section=main is Files (finished videos, results and uploads), working the files a project uses while it is made, archived the archive, and all (the default) every file that is not archived. Filter with kind, project_id (or none) and q; fields=compact leaves the metadata out; page with limit and the returned next_offset. GET /api/assets/working-projects groups Working files by project.
  • POST /api/assets/intent with mime_type, bytes and title reserves 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 is 200 with reused: true and that file, and there is nothing to upload. Send allow_duplicate: true as well to keep a second copy.
  • POST /api/assets/{id}/complete checks the upload and makes the file ready to use in a job's input.
  • With an API key, the intent also returns put_url: one signed address that takes the whole file in a single PUT (curl -T clip.mp4 -H "Content-Type: video/mp4" "$put_url"), instead of tus. An Idempotency-Key header (a UUID) makes a retry return the same file.
  • POST /api/assets/import with {"url": "https://…"} and an Idempotency-Key fetches a file from a public HTTPS address in the background. The answer is 202 with the new file’s id; GET /api/assets/{id} then shows import.status until the file is ready, or failed with an error_code. Addresses of VlogMe itself, private networks and IP addresses are refused.
  • PATCH /api/assets/{id} with title renames a file, and with archived: true moves it to Archived (false restores 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 with 409.
  • GET /api/assets/working-projects/{id}/cleanup shows what Clean up would delete in one project (earlier takes, unused pictures, leftovers), with the reason for each file. POST to the same address with asset_ids from that preview deletes up to five of them per request (the delete scope). Nothing is ever deleted automatically.
  • GET /api/assets/{id}/download returns a private link that lasts 60 seconds; ttl asks for up to an hour, and redirect=1 answers with a redirect to the file, so curl -L downloads 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/projects lists 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 with kind; page with limit and the returned next_cursor.
  • POST /api/projects with kind, title and data saves a new draft; an Idempotency-Key header makes a retry return the same draft. PUT /api/projects/{id} with the draft’s current revision saves a change, and an older revision is refused with 409. 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/templates lists the published Aisma templates (category, q, limit, cursor), GET /api/templates/{id} shows one, and POST /api/templates/{id}/open with an Idempotency-Key opens it as a new project.
  • GET /api/voices lists the voices a job or a Director cast can use: premade voices and your ready voice clones. GET /api/voice-clones lists your clones with their status, and DELETE /api/voice-clones/{id} deletes one, also at the voice provider (the delete scope).

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.failed or job.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 its error_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 as reassembly_failures.
  • Each delivery carries X-VlogMe-Event-Id, X-VlogMe-Timestamp and X-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.

ToolScopeWhat it does
vlogme_accountreadAccount and credit balance
vlogme_get_catalogreadJob catalogue
vlogme_list_assetsreadList Lab files
vlogme_get_assetreadLab file and download link
vlogme_list_working_projectsreadWorking files by project
vlogme_create_uploadwriteStart an upload
vlogme_complete_uploadwriteFinish an upload
vlogme_import_assetwriteImport a file from a URL
vlogme_update_assetwriteRename or archive a file
vlogme_delete_assetdeleteDelete a Lab file
vlogme_share_assetshareShare link on or off
vlogme_preview_cleanupreadPreview Clean up
vlogme_cleanup_working_filesdeleteClean up working files
vlogme_list_jobsreadList jobs
vlogme_get_jobreadRead a job
vlogme_wait_jobreadWait for a job
vlogme_quote_jobreadQuote a job
vlogme_create_jobwriteStart a paid job
vlogme_reassemble_jobwriteAssemble a partial job again
vlogme_list_projectsreadList projects
vlogme_save_projectwriteSave a draft
vlogme_delete_projectdeleteDelete a project
vlogme_director_createwriteNew Director project
vlogme_director_getreadRead a Director project
vlogme_director_messagewriteAsk the Director
vlogme_director_turnreadRead or wait for a turn
vlogme_director_answerwriteAnswer the Director
vlogme_director_turn_actionwriteStop, apply or discard a turn
vlogme_director_editwriteEdit the plan
vlogme_director_undowriteRestore an earlier revision
vlogme_director_preparewritePrepare pictures, voices and music
vlogme_director_quote_renderreadQuote the video
vlogme_director_renderwriteRender the video
vlogme_director_resultreadThe finished video
vlogme_list_templatesreadList templates
vlogme_get_templatereadRead a template
vlogme_open_templatewriteOpen a template
vlogme_list_voicesreadList voices
vlogme_delete_voice_clonedeleteDelete a voice clone
vlogme_trends_searchreadSearch the news
vlogme_trends_discoverreadNews suggestions
vlogme_news_read_articlewriteRead a complete news article
vlogme_news_get_articlereadSaved article and citation paragraphs
vlogme_trends_scriptwriteWrite a News Videos script
vlogme_trends_verifywriteCheck a News Videos script
vlogme_news_tasksreadNews tasks and shared budget
vlogme_news_create_taskwriteCreate a news task
vlogme_news_update_taskwriteChange a news task
vlogme_news_delete_taskdeleteStop and delete a news task
vlogme_news_run_taskwritePrepare a manual news story
vlogme_news_task_runsreadNews task run journal
vlogme_social_statusreadSocial accounts and posts
vlogme_publish_videopublishPublish a video
vlogme_cancel_publicationpublish / writeCancel a publication
  • Tools that only read carry readOnlyHint. Tools that delete carry destructiveHint, 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: true and code: invalid_input.
  • Every list tool takes limit (1 to 50, 20 by default) and cursor, and answers next_cursor (null on the last page).
  • vlogme_wait_job and vlogme_director_turn wait up to 30 seconds per call; call them again while the answer has retry_after_s.
  • Resources: resources/read serves vlogme://docs/agents (a guide for agents: from an idea to a video, the money rules, waiting and errors), vlogme://catalog (the job catalogue) and vlogme://openapi (the OpenAPI document). initialize returns short instructions with the same flows.

To start a job through MCP:

  1. Call vlogme_quote_job with kind and input, then review the returned credits.
  2. Call vlogme_create_job with the same kind and input, a new UUID idempotency_key, quoted_credits set to the returned credits, and the unchanged quote_fingerprint. For Aisma, also pass the unchanged quote_proof from the quote.
  3. 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_key to 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-Key is a UUID. Reusing one for a different request is refused.
  • Aisma jobs need the quote_proof their quote returns. It expires: quote again when it does.
  • Errors are JSON {"error": "…", "code": "…"} with the HTTP status: 400 invalid input (invalid_input), 403 a request the key’s scopes do not allow (scope_missing, session_required), 404 not found, 409 the price, inputs or plan changed, 429 too many requests, 503 the service or a provider is temporarily unavailable.
  • Requests are rate limited. Past a limit the answer is 429 with code: rate_limited and a Retry-After header: 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: true whose content is the same JSON (error, status and, when there is one, code). Only a missing or invalid key (401), an account without API access or a foreign Origin (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.