SigFollow
Sign in

Public API

Errors

Every error response shares the Meta Graph API body shape, so existing Cloud API clients keep their error handlers intact when migrating.

Body shape

{
  "error": {
    "message": "Invalid or expired API key",
    "type": "OAuthException",
    "code": 190,
    "error_subcode": 460,
    "error_data": { "details": "..." },
    "fbtrace_id": "abc123"
  }
}
  • message — human-readable description (English)
  • type OAuthException for auth-class errors, GraphMethodException for everything else
  • code — machine-readable error code (see table below)
  • error_subcode — optional finer-grained code
  • error_data — optional structured payload (e.g. for recipient-blacklist rejections)
  • fbtrace_id — echoes the request's X-Request-Id header when present, for cross-system correlation
HTTP status drives client behavior
Treat the HTTP status as the source of truth for retry / backoff decisions; the Meta error code is for observability and human troubleshooting. Multiple Meta codes can map to the same HTTP status.

Common codes

CodeTypeHTTPMeaning
190OAuthException401Invalid token — key is wrong, revoked, expired, or HMAC failed
200OAuthException403Permission denied — key valid but missing scope, IP rejected, etc.
4OAuthException429Rate limit exceeded — backoff using the Retry-After header
100GraphMethodException400 / 404 / 409Parameter error, resource not found, or conflict (e.g. tag limit reached)
131000GraphMethodException400 / 409 / 422 / 500Generic send / processing failure. HTTP status disambiguates: 422 = blacklist hit, 409 = idempotency in-flight or resource limit (e.g. contact tag cap), 500 = downstream Meta or transient.
131026GraphMethodException40024-hour customer service window expired — send via a template instead

Retry guidance

  • 5xx and 429 are retryable. Use exponential backoff (e.g. 1s, 2s, 4s, 8s) capped at 30 seconds. Combine with an Idempotency-Key to make retries safe for write endpoints.
  • 4xx (excluding 429) is notretryable — the request is malformed or the resource doesn't exist. Fix the request before retrying.
  • Network errors (TLS, DNS, connection reset) before a status is received are retryable with the same idempotency key.

The recipient_blacklisted error

When you send with ?filter_blacklist=true and the target is on the tenant blacklist, the API returns 422 with a Meta-style body whose error_data.reason is recipient_blacklisted. No message row is created and Meta is not called. Treat this as a final state, not a retry target.

{
  "error": {
    "message": "Recipient is on the tenant blacklist",
    "type": "GraphMethodException",
    "code": 131000,
    "error_data": { "reason": "recipient_blacklisted" }
  }
}