On this page
Errors
Error format
Every non-200 response has the same JSON shape:
{
"message": "The content has been deleted or does not exist",
"code": "content_deleted",
"retryable": false
}| Field | Description |
|---|---|
message | Human-readable, localized by the Accept-Language header. Do not branch on it; the wording may change. |
code | Machine-readable error code. Every extraction failure (400) carries one and 429 is always too_many_requests; 401, 402, 422 and 500 carry no code and are identified by the status itself. A request whose body is not valid JSON returns message only. |
retryable | Whether retrying the same URL later might succeed. Sent together with code. |
detail | Only on 422: the list of request body validation issues |
HTTP status codes
| Status | Meaning | Common cause | What to do |
|---|---|---|---|
200 | Success | - | The body is the extraction result. This is the only case that is charged. |
400 | Extraction failed | Invalid link, unreachable content, platform restrictions. A body that is not valid JSON is also 400, with message only | Handle by code (table below). Not charged. |
401 | Authentication failed | Missing Authorization header or a non-Bearer scheme, or the API key is wrong or has been reset | Check your key in the Developer Console |
402 | Out of credits | Remaining credits are 0 | Top up in the Developer Console |
422 | Invalid request body | Missing url, url not a string, Content-Type not JSON (the body is then validated as an empty object) | Read detail and fix the request |
429 | Rate limited | Over 1,200 requests per minute per key; code is too_many_requests | Back off and retry. MCP shares this quota with REST. |
500 | Server error | Internal failure | Retry later; contact us if it persists |
Extraction error codes
Extraction failures return HTTP 400 with one of the 18 codes below. These are business failures and are not charged.
| Code | Meaning | Common cause | What to do | retryable |
|---|---|---|---|---|
invalid_url | Malformed link | Not a URL, or no recognizable link in the input | Fix the URL | false |
unsupported_url | Not a post/video link | A valid URL that is not a content page, such as a site home page or search page | Use the share link of a single post or video | false |
unsupported_site | Site not supported | The platform is not on the supported list | Contact us to request it | false |
invalid_playlist_url | Not a profile/channel/playlist link | The playlist endpoint received a single post or a non-list page | Use a public profile, channel or playlist URL | false |
playlist_not_supported | A list URL was sent to the post endpoint | /extract/post received a profile or playlist link | Call /extract/playlist, or pass a single post URL | false |
content_deleted | Content deleted or never existed | The post was removed, the link is wrong, or it never existed | Nothing to extract | false |
user_not_found | User not found | Account deleted, renamed or restricted by the platform | Verify the handle | false |
no_story | No active stories | Stories expire after 24 hours | Try again when there are new stories | false |
private_content | Private content | Private account or follower-only content | Not extractable | false |
members_only_content | Paid or members-only content | Requires a subscription, payment or membership | Not extractable | false |
age_restricted | Age-restricted | The platform requires a signed-in age check | Not extractable (see note below) | false |
region_restricted | Region-restricted | Content visible only in certain regions | Not extractable (see note below) | false |
not_premiered | Not published yet | A scheduled premiere or timed release has not gone live | Retry after the publish time | false |
live_stream_not_supported | Live streams on this site not supported | The stream is currently live | Retry once it is archived as a normal video (see note below) | false |
extract_failed | Extraction failed | Site changes, or the content is currently unreachable | Retry later | true |
retryable | Transient failure | A momentary error during extraction | Retry after a short delay | true |
timeout | Extraction timed out | The extraction exceeded the time limit | Retry after a short delay | true |
unknown | Unclassified failure | An unexpected error | Retry once; if it keeps happening, contact us with the request time | true |
age_restricted, region_restricted and live_stream_not_supported only come up on a small number of platforms. Age- and region-restricted media usually extracts fine, and live streams are supported on many platforms (Twitch and TikTok among them). Getting one of these three means we cannot reach that kind of media on that particular platform; it does not mean the kind itself is unsupported.
What retryable means
retryable answers one question: is there any point in retrying the same URL later? It is sent alongside the error code.
true: a transient failure; the same URL may succeed a little later. Use exponential back-off starting at a few seconds, and give up and log after two or three attempts.false: a settled conclusion about the content itself (deleted, private, unsupported, and so on). Retrying will not change the outcome, so do not retry.- Field missing: treat as
false.
Codes get added over time. When you see a code that is not in the table above, treat it as permanent and log it rather than retrying in a loop. If one platform keeps returning extract_failed, or unknown shows up repeatedly, contact us with the request time.
retryable means "a retry is allowed", not "a retry will succeed". The values in the table are the typical value for each code; always use the value actually sent in the response.