Errors
Every error code, what it means and what to do. Errors are never charged.
Every error body on the TikTok routes has the same shape. Branch on error: it is stable. message is for people and may change.
{
"success": false,
"error": "<code>",
"errorStatus": 400,
"message": "<for people>",
"credits_charged": 0
}All codes
The TikTok routes (/v1/tiktok/..., /v3/tiktok/...):
| Status | error | Routes | Meaning | What to do | Charged |
|---|---|---|---|---|---|
| 400 | bad_request | all | A parameter is missing or malformed: no handle, a character TikTok does not allow, a query over 200 bytes, an Idempotency-Key over 255 characters. | Fix the request. | Free |
| 400 | unsupported_parameter | all | A parameter value we cannot honour yet, a user_id not in our index, or a user_id whose handle has changed. | Drop the parameter, or pass handle. | Free |
| 400 | invalid_cursor | search | The cursor is not from a previous answer to the same query with the same API key. | Start again without a cursor. | Free |
| 400 | cursor_expired | search | The cursor is older than 24 hours, or the search session expired. | Start again from page 1. | Free |
| 401 | unauthorized | all | Missing, unknown or revoked key. | Send x-api-key. | Free |
| 402 | insufficient_credits | all | The key cannot cover this request. The body has needed_credits and credits_remaining. | Top up. | Free |
| 404 | not_found | profile videos, followers, following, audience | The account does not exist (account_deactivated: true). | Check the handle. | Free |
| 409 | idempotency_conflict | all | A request with this Idempotency-Key and parameters is still running. Retry-After: 1. | Retry after it finishes. | Free |
| 409 | cursor_region_changed | search | Page 2+ could only be searched from another country than page 1. | Start again from page 1. | Free |
| 409 | cursor_exit_gone | search | The search session behind this cursor is gone. | Start again from page 1. | Free |
| 429 | over_capacity | all | No capacity to answer within the time limit, or the server is restarting. Has Retry-After. | Wait Retry-After seconds and retry. | Free |
| 429 | rate_limited | profile, profile videos, followers, following | The free-answer limit: this answer would have been free, and the key has had 100 free answers in 10 minutes. Has Retry-After. | Wait, or fix the handles you send. | Free |
| 500 | internal | all | Our fault. | Retry. Report the X-Request-Id. | Free |
| 501 | not_yet_available | profile videos | max_cursor asks for page 2+, which is not available in beta. | Call without max_cursor. | Free |
| 502 | upstream_failed | all | TikTok's answer failed or could not be read, including accounts TikTok withholds. | Retry later. | Free |
| 503 | route_not_priced | all | The route has no price yet, so it does not serve. | The route is not open yet. | Free |
| 503 | search_unavailable | search | No search capacity right now. Retry-After: 60. | Retry after 60 seconds. | Free |
| 504 | timeout | all | No answer within the time limit: 180 seconds, 300 for audience. | Retry. | Free |
Job routes
/v1/jobs, /v1/search and export answer errors in their own shape, with the code under error.code:
{
"error": {
"code": "invalid_unit",
"message": "<for people>",
"field": "keywords"
}
}| Status | error.code | Routes | Meaning | What to do | Charged |
|---|---|---|---|---|---|
| 400 | bad_request | jobs | The body or a parameter is malformed, or has an unknown field. | Fix the request. | Free |
| 400 | invalid_unit | submit a job, search | A keyword or handle cannot be used as given. error.field says which list. | Fix that unit. | Free |
| 400 | cursor_expired | get a job | A paging cursor from before the id-order change. | Start again without a cursor. | Free |
| 401 | unauthorized | jobs | Missing, unknown or revoked key. | Send x-api-key. | Free |
| 402 | insufficient_credits | submit a job, search | The key cannot hold the job's credits. error has needed_credits and available_credits. | Top up, or submit fewer units. | Free |
| 404 | not_found | jobs | No such job, another key's job, or no export requested yet. | Check the job id and key. | Free |
| 409 | idempotency_conflict | submit a job, search | This Idempotency-Key was used with a different request. error.job_id is that job. | Use a new Idempotency-Key. | Free |
| 409 | job_not_finished | export | The job is still queued or running, or its results are still being saved. | Poll the job until finished_at is set. | Free |
| 429 | rate_limited | jobs | The key's request rate on the job routes. Has Retry-After. | Wait Retry-After seconds. | Free |
| 429 | concurrency_limit | submit a job, search | The key already has its maximum of jobs queued or running. Retry-After: 10. | Wait for a job to finish, or cancel one. | Free |
| 500 | internal | jobs | Our fault. | Retry. | Free |
| 503 | export_unavailable | export | Export is switched off on this server. | Page the job instead, or retry later. | Free |
Not found on profile videos and followers
The 404 of profile videos and followers carries a few extra keys:
{
"success": false,
"error": "not_found",
"errorStatus": 404,
"message": "Account deactivated",
"account_deactivated": true,
"handle": "no_such_user_123",
"credits_charged": 0,
"credits_remaining": 998
}A profile of an account that does not exist is different: it is a 200 with account_deactivated: true, and it is charged. See Credits and pricing.
Retrying
| status | retry? |
|---|---|
400, 401, 402, 404 | no: fix the request, the key or the balance first |
409 | yes, after Retry-After, or start the search again from page 1 |
429 | yes, after Retry-After seconds |
500, 502, 504 | yes, with backoff. Report the X-Request-Id if it keeps happening. |
501, 503 route_not_priced | no: the feature is not open yet |
503 search_unavailable | yes, after 60 seconds |
Send an Idempotency-Key on every retry.