Guides
Errors & retries
Every error — at the request level or per target — uses one normalised shape, so you (or an agent) can handle failures the same way everywhere.
The error envelope
Errors return { "error": { … } } with a stable type, a human message, an optional platform, and a retryable boolean.
{
"error": {
"type": "entitlement_exceeded",
"message": "Not enough credits: this post costs 5, you have 2.",
"platform": null,
"retryable": false
}
}Two levels of error
- Request-level — the whole call is rejected (bad auth, malformed body, out of credits). Returned with a
4xxstatus and the envelope above. - Per-target — the call succeeds but one platform fails (over a limit, invalid option). The post is
partial, and the failingtargets[].errorcarries the same envelope. You're not charged for failed targets.
Error types
| Type | HTTP | Meaning | Retry? |
|---|---|---|---|
invalid_request | 400 | Malformed body or invalid field/option. | Fix & resend |
unauthorized | 401 | Missing or invalid API key. | No |
entitlement_exceeded | 402 | Out of credits, or your plan doesn't allow this (e.g. X/TikTok on free). | After topping up / upgrading |
rate_limited | 429 | Too many requests. | Yes, after a short back-off |
| platform errors | — | A specific network rejected the target (see platform). | Depends on the message |
Retrying safely
When retryable is true (e.g. rate_limited), back off and retry. Always send the same Idempotency-Key on retries so a post that actually went out isn't duplicated. On 429, honour any Retry-After header. Non-retryable errors (unauthorized, invalid_request) need a fix, not a retry.