WWaSparks Social Developers

Guides

Errors, limits and idempotency

The error format, how to retry safely, and what rate limits, plan limits and pagination look like.

Errors

Every error has the same body:

json
{
  "error": {
    "code": "account_needs_reauth",
    "message": "The Facebook Page connection has expired. Reconnect the account.",
    "request_id": "6b1f0c2e-3d4a-4b5c-8d9e-0f1a2b3c4d5e",
    "details": { "account_id": "0192a7c1-6a10-7b22-8e31-4c5d6e7f8a01" }
  }
}

What details holds:

Code details
validation_failed fields: a list of { field, code, message, account_id }. field is the path in your request, such as account_ids[1]. account_id is set when the problem is for one account.
media_not_ready media_id
quota_exceeded limit, used, max
platform_rejected platform, platform_code, platform_subcode, platform_message. All four are always there, and null when unknown.

Every code, with its status and what to do, is in Error codes.

What to retry

Status Retry?
400, 401, 402, 403, 404 No. Fix the request, the key or the plan first.
409 idempotency_conflict No. You reused an idempotency key with a different request.
409 invalid_state No. The resource is not in a state that allows this. Read it and decide.
422 account_needs_reauth No. Reconnect the account.
422 reply_window_closed, 422 platform_rejected No. The platform said no.
429 Yes, after the Retry-After header says.
500, 503 Yes, with backoff. Use an idempotency key where the call supports one.
Network error or timeout Yes, with the same idempotency key.

Idempotency

On POST /v1/posts, POST /v1/comments/{commentId}/replies and POST /v1/conversations/{conversationId}/messages, send an Idempotency-Key header: any unique string, such as a UUID you generate per action.

Generate the key before the first attempt and reuse it on every retry of that action. A new key for each retry defeats the purpose.

Rate limits

Calls are limited per key and per org. Responses carry:

Header Meaning
X-RateLimit-Limit Calls allowed in the current window.
X-RateLimit-Remaining Calls left.
X-RateLimit-Reset When the window resets.

Over the limit you get 429 rate_limited and a Retry-After header. Wait that long, then continue. With a partner key in operator mode, a call counts against both the partner key and the org it acts on.

429 platform_rate_limited is different: the social platform is limiting that account, not us. Back off for that account and try later. See Platform notes for limits that are fixed by the platforms.

Plan limits

Each org is on a plan. A plan can limit social_accounts, posts_per_month, members and workspaces; a limit that is left out is unlimited. A call that would go over returns 402 quota_exceeded, with limit, used and max in details.

GET /v1/org shows the org's plan limits and current use. GET /v1/usage shows counts over time. See Billing and usage.

Pagination

Lists that can grow, such as posts, comments and conversations, take limit (default 25, maximum 100) and cursor, and answer:

json
{ "data": [], "next_cursor": "eyJvIjoyNX0" }

Pass next_cursor as cursor to get the next page, with the same limit and filters. A null next_cursor is the last page. Short lists, such as accounts, workspaces, plans, redirect URIs, API keys and webhook subscriptions, return everything at once with next_cursor: null.

Next: Platform notes