Error types
Each type has one status. Branch on error.type; the message is for people.
Error body
{
"success": false,
"error": { "type": "rate_limited", "message": "Too many requests. Retry in 42 seconds." }
}| Type | Status | Meaning and fix |
|---|---|---|
invalid_input | 400 | The request body or query failed validation. Read error.message, fix the field it names, and send the request again. Retrying unchanged will fail identically. |
unauthorized | 401 | No key, an unreadable key, or a key that is no longer valid. Check the Authorization header. Every authentication failure collapses to this one type on purpose, so the message will not say which part was wrong. |
forbidden_scope | 403 | The key is valid but does not carry the scope this endpoint requires. Issue a key with the scope named in the message. Scopes cannot be added to an existing key. |
not_found | 404 | No resource with that id inside the team the key belongs to. Check the id and the workspace. A resource in another team is a 404, not a 403. |
conflict | 409 | The resource is not in a state that allows this call, or an idempotency key was replayed with a different body. Read the current state first. Cancelling a published post and editing a launched automation both land here. |
insufficient_credits | 402 | The team does not have enough credits for the media this call would generate. Top up, or use a Turbo format, which costs nothing. Nothing is charged and nothing is queued. |
usage_limit_reached | 429 | A plan quota is exhausted: saved posts, automations, content pieces, connected accounts or workspaces. Wait for the period to roll over or move to a plan with a higher limit. Retrying sooner returns the same error. |
rate_limited | 429 | Too many requests in the sliding window for this endpoint group. Wait for the number of seconds in Retry-After, then retry. X-RateLimit-Reset carries the same moment as a timestamp. |
internal_error | 500 | Something failed on our side. Retry with backoff. If the call spends credits, send the same Idempotency-Key so a partial success is not repeated. |
Retries
- Never retry
invalid_input,forbidden_scope,usage_limit_reachedorconflictunchanged. - Retry
rate_limitedafterRetry-Afterseconds. - Retry
internal_errorwith backoff, and send the sameIdempotency-Keyon calls that spend credits or publish.
Rate limits
Counted per key on a sliding window.
| Group | Requests | Window | Applies to |
|---|---|---|---|
| Generations | 10 | 300s | Every endpoint under /generations. |
| Posts | 60 | 300s | Every endpoint under /posts. |
| Content studio | 30 | 300s | Every POST /content/* render endpoint. |
| Everything else | 600 | 300s | Reads, workspaces, accounts, automations, influencers, assets, analytics and webhooks. |
Headers
X-RateLimit-Limit: Requests allowed in the window for this endpoint group.X-RateLimit-Remaining: Requests left in the current window.X-RateLimit-Reset: Unix seconds at which the window rolls over.Retry-After: Seconds to wait. Sent on a 429 only.
Read the headers instead of counting calls. The CLI and the MCP server follow these rules for you.