Status: alpha. Every operation may still change before the beta. The version of the contract is in its
info.version,
and the changelog lists what changed. API v2 keeps working unchanged beside v3, and
its documentation stays under v2 in this site’s version selector. If you run on v2 today, see
Move from v2.Base URL
POST /projects means POST https://api.rask.ai/v3/projects. The links
the API returns (the Location header and the links objects) already start with /v3, so resolve them against
https://api.rask.ai.
Where to start
Quickstart
Get a key, make one request, then dub a whole video from upload to download.
Authentication
Keys, scopes, spend caps, and what each 401 and 403 means.
SDKs
Official clients for TypeScript, Python, Go, Java and PHP: the install command for each, and what they do for you.
AI agents
A ready prompt for your agent, how to pass it the key, and how to keep its spending bounded.
MCP server
Ready-made tools for Claude Code, Claude Desktop, Cursor, VS Code and Codex CLI, with a price to confirm before each spend.
Recipes
Dubbing models, your own transcript, voice clones, paid segment generation, lip-sync, on-screen text, one-request runs,
downloads and spend.
Concepts
Jobs, idempotency, ETags, the rule that text is paid by the dub, plan limits and prices.
How the API behaves
- Long work is a job. A call that starts work answers
202with a Job (copying a project answers with a list of jobs). You wait on the job, then read its result. - Spending is explicit. Every paid call has a free estimate, and you send the estimate’s
total_minutesasexpected_cost_minutes, a cap: if the price is now higher, the call fails with409 cost_changedand spends nothing. See Prices and refunds. - Retries are safe. Calls that start work or spend, plus creating a segment and restoring a version, require an
Idempotency-Key. Once a call has succeeded, a retry with the same key and request replays that answer (for a job, its current state) instead of running the work again. - Edits are conditional. Edits of an existing segment and of a speaker’s voice require the segment’s or speaker’s
ETag, in
If-Match(a merge sends one per segment in its body), so two writers cannot overwrite each other. - Errors are data. Every error is
application/problem+jsonwith a stablecodeand ahint. Each code has a page.
Read the contract from code
These routes need no key, and they serve the same contract these pages are built from:
A tag is written exactly as the contract names it, with each space as %20:
GET /openapi/Projects.json,
GET /openapi/Voice%20clones.json. The groups of the API reference on this site have the same names.
There is no sandbox. To try the API without spending, use a key without credits:spend and call the estimates (each
shows the price, with eligible: false and the reason insufficient_scope), or run a mock of the contract:
/v3, so its base URL is http://127.0.0.1:4010. Set RASK_BASE_URL to that, and the
SDKs and the programs of these docs call the mock. It checks each request against the contract and answers from the
contract’s examples, and a header such as Prefer: code=402, example=insufficient_balance on POST /projects asks for that
error. It stores nothing, and the presigned upload URL it gives is a placeholder, so an upload stops at sending the bytes.