Errors
Every error response uses the shape below. Once a code ships, its meaning is frozen. New behavior gets a new code; old codes never get repurposed.
{
"error": {
"code": "machine_readable_slug",
"message": "Human-readable message",
"details": "optional extra context"
}
}All codes
| HTTP | Code | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_url | URL is not a valid Meta or TikTok Ad Library URL. | Check the URL format. The API accepts full Ad Library URLs only. |
| 400 | missing_url | Request body did not include a `url` field. | Add `{"url": "https://..."}` to your POST body. |
| 400 | invalid_body | Request body could not be parsed as JSON. | Send a Content-Type: application/json header and a valid JSON body. |
| 400 | not_acceptable | Accept header requests a format we do not support. | Use application/json, text/markdown, or application/pdf. |
| 400 | missing_name | Token name was empty when creating one. | Provide a label. |
| 400 | name_too_long | Token name exceeded 80 characters. | Shorten the label. |
| 400 | too_many_tokens | 25-token-per-user cap reached. | Revoke an unused token in /settings. |
| 401 | unauthorized | Bearer token missing, malformed, invalid, or revoked. | Create a new token in /settings → Developers. |
| 402 | insufficient_credits | Account has zero credits left. | Refill at /settings → Credits. |
| 403 | forbidden | The analysis belongs to a different user. | Use the token that belongs to the analysis owner. |
| 404 | not_found | Analysis id does not exist. | Check the id from your previous response. |
| 429 | rate_limited | Per-token rate limit exceeded. | Wait the seconds shown in Retry-After, then retry. |
| 500 | internal_error | Something on our side broke. | Open an issue with the request timestamp; we look at every one. |
Tips
- →Always parse
error.codeprogrammatically. Themessageis for humans and can change. - →Backoff on 429. The
Retry-Afterheader tells you how long to wait. - →Don't retry 4xx automatically. Those are client errors. Fix the request first.