Credits & limits
What each request costs, what is free, the limits, and every error code with what to do.
Credits
New accounts get 100 free credits, no card. After that, buy a pack in the dashboard; credits are valid for 12 months and add to your balance.
| Pack | Credits | Price | Per credit |
|---|---|---|---|
| Starter | 1,000 | $10 | 1¢ |
| Builder | 5,000 | $40 | 0.8¢ |
| Pro | 25,000 | $150 | 0.6¢ |
What a request costs
- Transcript: 1 credit per started 10 minutes of video: an 11-minute video is 2 credits.
- Fields (
/v1/extract): 3 credits per started 10 minutes, the transcript included. - Posts without captions: transcribed for 1 credit per started minute instead: a 45-second Reel is 1 credit.
- A translation the platform doesn't provide (into
language): 1 credit more per started 10 minutes. - On-screen text alongside speech: 1 credit more. For a post without speech it is the transcript.
- Creator posts (
/v1/posts): 1 credit per call. - Account (
/v1/account): free.
| Post | Transcript | Transcript and fields |
|---|---|---|
| A 45-second TikTok or Reel, with or without captions | 1 credit | 3 credits |
| A 10-minute YouTube video | 1 credit | 3 credits |
| A 15-minute video without captions | 15 credits | 19 credits |
| A 1-hour podcast | 6 credits | 18 credits |
A creator's post list (/v1/posts) |
1 credit |
Free, always: any request that fails. Asking again for the same thing within 6 hours is free. If you got this post's transcript in that time, asking for its fields costs only the fields. Asking again after a result with an incomplete or uncorrected warning runs the request again in full and is charged again. Every response says what it used in X-Credits-Used and what is left in X-Credits-Remaining. With no credits left, every request except /v1/account is insufficient_credits, even a free repeat.
Limits
- Requests a minute: set per account, 10 for new accounts; yours is
rate_limit_per_minuteinGET /v1/account. Over it you getrate_limitedwithRetry-After. Need more? Write to mohamed@messaad.dev. - Unavailable posts and profiles: 30 an hour. Requests that end in
video_unavailable,author_not_foundorsource_unavailableare free, but past 30 in an hour you getrate_limiteduntil the hour is up. Asking again within 30 minutes for a post or profile that doesn't exist returns the same 404 and doesn't count. - Post length: up to 2 hours. Posts without captions are transcribed up to 15 minutes.
- Time: a request answers within 120 seconds, or returns
timeout. - Size: request body up to 128 KB, schema up to 32 KB, response up to 8 MB.
- Creator posts: up to 30 per call on YouTube (videos, not Shorts), 35 on TikTok, 12 on Instagram.
Errors
Every error has the same shape. code is stable; message says what happened in words you can show; param names the field at fault; details carries data you can act on. Quote request_id when you contact us.
{
"error": {
"code": "insufficient_credits",
"message": "This request needs 1 credit and the account has 0 left. Buy more at https://cleanscript.ai/pricing.",
"details": {
"credits_remaining": 0,
"credits_required": 1,
"top_up_url": "https://cleanscript.ai/pricing"
}
},
"request_id": "5f0c7d1e-0b7a-4a39-9c1e-3c1f2b8f6a10"
}| Code | Status | What to do |
|---|---|---|
invalid_request |
400 | Fix the field named in param; the message says how. Also 404 or 405 for an unknown route or method, and 413 for a body over 128 KB or a result over 8 MB. |
invalid_url |
400 | Send a link to one post: a YouTube watch, Shorts or youtu.be link, a TikTok video link, an Instagram /p/ or /reel/ link. |
unsupported_platform |
400 | Only YouTube, TikTok and Instagram posts work. |
invalid_schema |
400 | Fix the JSON Schema; the message names the problem. |
unauthorized |
401 | Send Authorization: Bearer <key> with a key from the dashboard that isn't revoked. |
insufficient_credits |
402 | Top up at details.top_up_url. details also has credits_required and credits_remaining. |
video_unavailable |
404 | details.reason is private, removed, age_restricted or live on YouTube, and unavailable on TikTok and Instagram. A live stream works once it has ended. |
author_not_found |
404 | Check the profile link or handle; details.reason is not_found or private. |
idempotency_conflict |
409 | The Idempotency-Key was used for a different request (use a new key), or the first request is still running (retry after Retry-After). |
no_captions |
422 | The post has no captions and can't be transcribed: it is over 15 minutes, or its audio isn't available. |
language_unavailable |
422 | Choose a language from details.available, or leave language out. |
video_too_long |
422 | The post is over 2 hours. |
rate_limited |
429 | Wait for Retry-After seconds, then retry. |
source_unavailable |
503 | The platform didn't answer. Retry after Retry-After. |
processing_failed |
503 | Something failed on our side. Retry after Retry-After. |
timeout |
504 | Retry; the result is often ready by then. |