EveryFrameAPI

Quickstart

Make a 5-second video from a prompt: get a key, check the price, start the render, wait for it, and download the MP4. Every request goes to https://api.everyframe.studio/v1.

Make an API key

In the console, choose Create key. Copy the key when it appears, because it is shown only once, and keep it in an environment variable on your server.

export EVERYFRAME_API_KEY=ef_live_...

Then add API credits on the Billing page. Check that the key works; the reply names it and shows your API credit balance:

curl https://api.everyframe.studio/v1/key \
  -H "Authorization: Bearer $EVERYFRAME_API_KEY"

Check the price

A quote takes the same body as a render and charges nothing. Use it to show your users a price, or to stop before an expensive request.

curl https://api.everyframe.studio/v1/render/quote \
  -H "Authorization: Bearer $EVERYFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modelId":"seedance-2-0-fast","duration":5,"resolution":"720p"}'
200 OK
{ "modelId": "seedance-2-0-fast", "mode": "video", "duration": 5, "resolution": "720p", "credits": 130 }

Start the render

Send the prompt with the same settings. The credits are taken now and you get the render back straight away, with its id.

curl https://api.everyframe.studio/v1/render \
  -H "Authorization: Bearer $EVERYFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "modelId": "seedance-2-0-fast",
    "prompt": "A lighthouse keeper climbs the stairs at dusk, handheld",
    "duration": 5,
    "resolution": "720p",
    "aspect": "16:9"
  }'
202 Accepted
{ "render": { "id": "rnd_Qm3vX8pL2kNc7RtY", "status": "queued", "credits": 130, ... },
  "credits": 4865 }

The top-level credits is your API credit balance after the charge.

Wait for it

Ask for the render every 5 to 10 seconds. Its status moves from queued to running, then ends as succeeded or failed. While it runs, progress (0 to 1) and stage say how far along it is.

curl https://api.everyframe.studio/v1/render/rnd_Qm3vX8pL2kNc7RtY \
  -H "Authorization: Bearer $EVERYFRAME_API_KEY"
200 OK
{ "render": { "id": "rnd_Qm3vX8pL2kNc7RtY", "status": "succeeded", "width": 1280, "height": 720,
    "videoUrl": "/render/rnd_Qm3vX8pL2kNc7RtY/video?t=...",
    "posterUrl": "/render/rnd_Qm3vX8pL2kNc7RtY/poster?t=...", ... },
  "credits": 4865 }

A failed render gives its credits back automatically, and its error says what went wrong.

Download the video

The videoUrl and posterUrl are relative to the API base and carry their own access token, so they work without the key, in a browser or a <video> tag. Add &full=1 to the video URL for the full-quality master rather than the lighter streaming copy.

curl -L "https://api.everyframe.studio/v1/render/rnd_Qm3vX8pL2kNc7RtY/video?t=...&full=1" -o clip.mp4

Treat these URLs like the files themselves: anyone with the link can watch the clip.

API keys and scopes

A key acts as you and spends your credits. Send it on every request as Authorization: Bearer ef_live_.... Keep keys on a server: never put one in a web page or a mobile app. When you make a key you choose what it can do:

ScopeAllows
renderQuotes and new renders. This is the scope that spends credits.
readReading renders, listing them, and downloading files.
uploadUploading reference images, video and audio, and listing uploads.

Any key can call GET /v1/key and GET /v1/render/models. A key can also have a monthly credit limit, which resets on the 1st of each month (UTC), and an expiry date. Keys can't manage other keys or change your account: do that in the console.

API credits

Renders made with an API key are paid from your API credits. They are a separate balance from your EveryFrame Studio credits: Studio credits never pay for API calls, and API credits never pay for Studio work. Buy them on the Billing page with TAO or other crypto, at 500 API credits to the dollar.

A render is charged when it starts, at the price its quote gave, and a failed render gives its credits back to your API balance.

List models

GET/v1/render/models

Every model with its id, maker, the lengths and resolutions it makes, its prices (credits by "resolution:seconds", or "image"), the reference inputs it takes (inputs, referenceModes, referenceLimits) and its longest prompt (maxPrompt). No key needed. The same list is on the models page.

Quote a render

POST/v1/render/quote

Takes modelId, duration, resolution and referenceMode, and returns them as the render would use them (the length and resolution snapped to what the model makes) with the exact credits. An unknown model is a 404.

Start a render

POST/v1/render

FieldWhat it is
modelIdRequired. A model id from the list.
promptRequired. What to make. Each model publishes its own maximum length.
durationSeconds, for video. Snapped to the nearest length the model makes. Default 5.
resolutionFor video, for example "480p", "720p" or "1080p". Default 480p.
aspect"16:9" (default), "9:16", "1:1", "4:5" or "21:9".
attachmentIdsReference files you uploaded, in order. See reference files.
referenceModeHow the references are used: "first-frame", "first-last" (opening and closing frames), or "omni" (characters, motion and sound). Each model lists the modes it takes.
negativeWhat to avoid, up to 500 characters, where the model supports it.
seedA number, to repeat a result where the model supports it.

Returns 202 with the render and your new balance. The render's credits is what was charged.

Get a render

GET/v1/render/:id

The render's status, progress, stage, settings, credits, error when it failed, and once it has succeeded its width, height, bytes, videoUrl, videoFullUrl and posterUrl.

List renders

GET/v1/renders

Your account's recent renders, newest first, including ones made in the Studio.

Download files

GET/v1/render/:id/video?t=…

GET/v1/render/:id/poster?t=…

Use the URLs from the render, which carry their token. Video is MP4 and supports range requests; the poster is a JPEG still. Copy files you need to keep long-term to your own storage.

Reference files

POST/v1/render/attachment

Send the file itself as the request body, with its content type: JPEG, PNG, WebP or AVIF images, MP4, MOV or WebM video, or MP3, WAV, M4A, AAC or OGG audio. You get back an attachment with its id, which you pass in attachmentIds.

curl https://api.everyframe.studio/v1/render/attachment \
  -H "Authorization: Bearer $EVERYFRAME_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @first-frame.jpg

Then render from it, for example "attachmentIds": ["att_..."], "referenceMode": "first-frame". GET /v1/attachments lists your uploads.

Errors and limits

Errors come back as JSON with a sentence you can show people, a code to branch on, and the field at fault when there is one.

StatusCodeWhat to do
400prompt_too_long, bad_attachmentFix the field named in the reply.
401invalid_api_key, api_key_expiredThe key is missing, wrong, revoked or past its end date.
402insufficient_creditsNot enough API credits. Add some on the Billing page.
402key_limit_reachedThe render would pass the key's monthly limit. Raise it in the console, or wait for the 1st.
403insufficient_scopeThe key isn't allowed to do that. Make a key with the scope you need.
404not_foundNo such model, or no such render on this account.
422blockedThe prompt was refused by the content policy. Nothing was charged.
429rate_limitedUp to 40 new renders per 15 minutes per account. Wait and retry.
503provider_unavailableThe model is down for now. Nothing was charged; try another model.

Claude Code and MCP

To let an agent make videos for you, add the EveryFrame MCP server to Claude Code. It signs in through your browser, and each call has a credit cap.

claude mcp add everyframe -- npx -y https://app.everyframe.studio/mcp/everyframe-mcp-0.1.0.tgz

There is also a skill: npx skills add https://app.everyframe.studio. See EveryFrame for agents.