Start here
Credits & pricing
Credits come from a weekly or monthly plan and are spent per use. Instant calls charge once; video jobs reserve their quote up front, and the quote is a ceiling. Every number on this page is computed from the live price table and the plan catalog.
Current price table: 2026-10-11. Every quote, estimate, and video response carries it as price_table_version, so you can tell which prices a number was computed with.
Buying credits
Credits come from a plan, with the same plans and prices as the Promoat app. Pick one on the Plans page of your dashboard and pay at checkout. The credits land within seconds.
- Credits are added each time a plan renews, and they never expire. What you don't use rolls over.
- The plan cards count a video as 73 credits, the price of a one-minute video. The price list below has what each video costs.
- Credits you already have stay in your balance.
- What a job costs in credits is the same on every plan. The price list below did not change.
For scale: one Monthly plan covers about 73 fifteen-second talking heads at 768P, or 73 fifteen-second scene videos.
Changing or cancelling a plan
Switch plans on the same Plans page. When a switch starts depends on its direction:
- A bigger plan or a longer interval starts now. You pay the prorated difference for the rest of the period, and the credits for it are added straight away.
- A smaller plan or a shorter interval starts at the end of the period. You keep your current plan until then.
- Cancel in Manage subscription on the dashboard. Your plan runs to the end of the period, then stops. Your credits stay, and you can renew there before the period ends.
| From | To | Starts |
|---|---|---|
| Weekly | Monthly | Now, prorated |
| Weekly | Monthly 3.6× | Now, prorated |
| Monthly | Monthly 3.6× | Now, prorated |
| Monthly | Weekly | At the end of the period |
| Monthly 3.6× | Weekly | At the end of the period |
| Monthly 3.6× | Monthly | At the end of the period |
Manage subscription on the dashboard opens the Promoat billing portal: your plan, card, invoices and billing details. Plan changes and cancelling there follow the same rules.
Credit packs
Need more before your plan renews? Buy credits once. Packs are for subscribers only: they appear on the Plans page once you have a plan.
One-time purchase. Credits you buy never expire.
The signed billing link (/partner/billing?client_id=…&sig=…) and POST /api/partner/v1/billing/checkout-session work as before. They sell credits once, with no plan.
Price list
Flat-rate operations (charged instantly):
| Operation | Credits |
|---|---|
POST /characters | free |
POST /characters/{id}/regenerate | 4 |
POST /images/first-frame | 4 |
POST /voices — clone | free for your first clone (once per account), 30 after that |
POST /voices/{id}/reclone | free if the old voice expired, 30 if it still works |
POST /voices — library (studio) voice | free |
POST /tts | 10 per started 1,000 characters (min 10) |
POST /videos/estimate, POST /videos/scene-plan, status polls, lists | free |
| Dynamic captions add-on (talking head) | 10 |
Video generation, by length
A video's price depends only on its length: the same at every resolution, in both scene modes and with or without scene photos. It includes the opening frame and the speech timing.
| Length | Voiced (talking head or scenes) | Silent scenes |
|---|---|---|
| 5 s | 21 | 18 |
| 10 s | 24 | 21 |
| 15 s | 30 | 27 |
| 20 s | 33 | 30 |
| 30 s | 44 | 38 |
| 45 s | 65 | 56 |
| 60 s | 73 | 65 |
768P is the default. A video's quote is a list of lines; each has a kind:
| Line kind | What it is |
|---|---|
generation | The video itself, by its length (the table above, less the lines below). |
first_frame | The opening frame (12) when the job makes its own — dropped when you pass first_frame_url or first_frame_asset_id. |
transcription | Timing the speech (a few credits, voiced videos only). |
tts | Script mode only: speech for your script, at the /tts price. |
captions | The dynamic captions add-on (10). |
product | A fix-sound swap (0). |
Worked examples
| Request | Lines | Total |
|---|---|---|
| 15 s talking head, 768P, your audio | generation 15 + first_frame 12 + transcription 3 | 30 |
| …with your own first frame | generation 15 + transcription 3 | 18 |
| …with dynamic captions | generation 15 + first_frame 12 + transcription 3 + captions 10 | 40 |
| 5 s talking head, 480P | generation 6 + first_frame 12 + transcription 3 | 21 |
| 15 s scenes, reference mode, 2 scene photos | generation 15 + first_frame 12 + transcription 3 | 30 |
| 15 s scenes, text mode | generation 15 + first_frame 12 + transcription 3 | 30 |
| 15 s silent scenes (voice_mode none) | generation 15 + first_frame 12 | 27 |
| TTS, 600 characters | — | 10 |
Edits are priced the same way — see Video edits.
Billed seconds
- Audio under 1 s is rejected (
AUDIO_TOO_SHORT). - Anything from 1 to 5 s is billed as 5 s.
- Voiced videos are capped at 59.5 s of audio (
AUDIO_TOO_LONG); scripts at 4,000 characters. Silent scenes run 5–60 s (target_seconds).
Know the price before you fire
POST /videos/estimate takes the exact same body as POST /videos and returns the credits that call would reserve (it does not need character_id and checks no ids), your live balance, and the lines. It is free and has no side effects. Estimate equals reserve for the same body.
Lock the price: expected_credits
Send the quoted number back as expected_credits on POST /videos(and on edits). If the server's quote is higher than that, nothing is queued or charged:
{ "error": "QUOTE_MISMATCH", "error_code": "QUOTE_MISMATCH", "code": "quote_mismatch",
"credits_quoted": 30, "message": "…" }Two billing styles
Instant endpoints charge once, immediately
/characters, /characters/{id}/regenerate, /voices, /tts, and /images/first-frame do the work inside the request and return credits_charged. If the work fails, the charge is refunded.
Video jobs reserve a ceiling, then settle
/videos and the edit endpoints reserve the quote before the job starts and return credits_reserved. The quote is a hard ceiling: you are charged min(actual, reserved) — never more than you were quoted. A failed job is refunded once. A job that goes quiet for 75 minutes is failed with STALE_TIMEOUT and refunded.
POST /videos → 200 { "credits_reserved": 30, "price_table_version": "2026-10-11" }
GET /jobs/…/status → { "status": "running", "credits_consumed": null }
GET /jobs/…/status → { "status": "completed", "credits_consumed": 30 }With voice_id + script the speech does not exist yet, so the video lines are quoted on an estimated length (words ÷ 138 per minute, plus 10% headroom; 35% for non-Latin scripts; at most 59.5 s) plus the tts line. The job measures the real speech and charges the lower of the reserve and the real price — the difference goes back to your balance.
credits_consumed on a job is null while queued/running, the actual charge once completed, and 0 on failed (refunded; a recorded partial charge shows instead, if any).
Safe retries: idempotency keys
Send an Idempotency-Key header (1–255 visible ASCII characters) or a client_request_id (uuid) in the body. Optional on /videos, required on the edit endpoints (unless dry_run). Retrying the same body with the same key returns the original job with duplicate: true — nothing is charged twice. Details in Errors & limits.
When you can't afford a call
Every paid endpoint checks your balance first and returns 402 without doing (or charging) anything:
{
"error": "INSUFFICIENT_CREDITS",
"error_code": "INSUFFICIENT_CREDITS",
"credits_required": 30,
"credits_balance": 40,
"message": "…"
}credits_required is the quote for this request. Add credits on the Plans page: subscribe, move to a bigger plan, or buy a credit pack. Then retry.
Watching your balance
GET /usage/summary is free and returns the live balance plus job counts for any date range — details in Usage & history.