# Clipwright > An HTTP API that turns a script into a lip-synced UGC video. It does not publish anywhere: it returns a file and a signed link. Base URL: https://api.clipwright.io Auth: send `Authorization: Bearer cw_…` on every call. Keys are issued once in the dashboard at https://app.clipwright.io/api-keys and are not recoverable afterwards. Price from a plain script: 30 credits per second of finished video; 1000 credits cost $10.00. Price with segments or inserts: 10 credits for every second a face is on screen, and at least 400 credits on a video we delivered. Seconds without a face cost nothing, and a run that delivers no file costs nothing at all, even when the vendor was already paid. Face time is added up across the whole video and rounded up once, not per segment. These fields need long-form qualification on the deployment; where it is off they are refused by name before any charge. Every paid call requires an Idempotency-Key header of your own choosing; without it the call is refused with 400 idempotency_key_required. ## What a call costs Ask the quote endpoint first: it charges nothing. Its answer means something different per skill. - make_ugc: the quote is an estimate read off the words of the script. The charge follows what was measured in the finished video — its duration on the plain-script meter, its face seconds on the face meter — so the bill can land above or below the quote. - make_ugc from a plain script: a run that failed after the delivering work reached the vendor is charged. One that failed before it costs nothing, and so does one we stopped, lost or refused ourselves, even when the vendor was already paid. On the face meter no failure is charged at all. - create_actor: the quote prices every format you asked for, which is the most you can pay. You are charged for the portrait and for the variants actually published; a format that did not come out is named in warnings[] and costs nothing. - create_actor: a failed run costs nothing at all, even when the vendor was already paid, because no actor reached you. ## Endpoints - GET /health — Liveness of the API itself. Answers without a key. - GET /v1/voices — Voices you can name in voice or voice_id. - GET /v1/account — Balance, debt and holds of the account behind the key. - POST /v1/skills/make_ugc/quote — Prices a make_ugc call with this input. Charges nothing. - GET /v1/runs/{id} — State of one run of any skill, its warnings and its video url. - POST /v1/skills/make_ugc/run — Starts a video run and answers at once with a run_id. Poll the run for the result. Costs credits. - GET /v1/public/skills — Catalogue of skills and their input, without a key. - GET /v1/actors — Actors saved on the account, with the id make_ugc takes. - DELETE /v1/actors/{id} — Forgets a saved actor. An actor used by a live run is kept. - GET /v1/actors/{id}/defaults — Reads the saved actor's default policy for people in inserts. - POST /v1/actors/{id}/defaults — Sets the saved actor's default policy for people in inserts. A run can override it. - POST /v1/skills/create_actor/quote — Prices a create_actor call with this input. Charges nothing. - POST /v1/skills/create_actor/run — Starts an actor run and answers at once with a run_id. Poll the run for the result. Costs credits. - POST /v1/uploads — Takes image bytes and returns the https url that make_ugc and create_actor accept. ## Rules an agent needs - make_ugc does NOT wait for the video. It returns a run_id at once; poll GET /v1/runs/{id} until the state is succeeded or failed. - failed is not always final. A run whose paid vendor job we still hold can be reopened: it goes back to queued and may reach succeeded. Every such reopening is named in warnings[], and it never happens more than three times. - Anything we could not honour comes back in warnings[] on the run. Nothing is dropped silently. - Format and resolution follow your request and the source. A mismatch is snapped with a warning or refused before the paid call, never swapped quietly. - Supported formats: 9:16, 1:1, 16:9. Resolutions: 720p, 1080p, 4k. Silence means 1080p in 9:16. - Captions are opt-in: ask the person before turning them on. - Idempotency-Key makes a retry safe: the same key with the same body returns the run already started; the same key with a different body is refused with 409 idempotency_key_reused. - To start a deliberately new run on the same input, send a NEW key. The SDK and the MCP server derive the key themselves and turn attempt=2, 3 … into a new one. - 60 paid and 300 free requests per 60 seconds, per account. - The same contract is served as MCP tools by @clipwright/mcp-server; its tools/list is the machine-readable schema. ## Refusals - rate_limited (429) — repeat the same call after the wait. Back pressure, not an error: the response names the seconds to wait, in Retry-After and in the body. - server_error (500, 502, 503) — repeat the same call after the wait. The failure is on the server side. Do not start a second run with a new idempotency key: the same call is the retry. - insufficient_credits (402) — do not repeat. Stop and tell the person the balance and the price; both are in the body. Repeating cannot change either. - debt_outstanding (402) — do not repeat. Stop. Buying credits clears the debt before anything reaches the balance, and that lifts the block. - not_admitted (403) — do not repeat. Stop. The account has no beta access; neither a retry nor a purchase changes that. Ask the operator. - client_error (400, 401, 404, 409, 413, 415) — do not repeat. Stop. The request itself was refused: read the message, fix the call, then send it again. ## Full documentation - https://clipwright.io/docs - https://clipwright.io/docs.md (this document in full, one file)