{"errors":[{"code":"MISSING_TOKEN","status":401,"category":"auth","message":"No API token was provided.","fix":"Include Authorization: Bearer <token> or X-API-Key: <token>."},{"code":"INVALID_TOKEN","status":401,"category":"auth","message":"The token does not match any issued key.","fix":"Double-check the prefix and confirm the key has not been rotated."},{"code":"TOKEN_REVOKED","status":401,"category":"auth","message":"The token was revoked in the dashboard.","fix":"Create a new key or rotate an existing one."},{"code":"TOKEN_EXPIRED","status":401,"category":"auth","message":"The token passed its expiration date.","fix":"Rotate the key or issue a new one without an expiry."},{"code":"OWNER_MISSING","status":401,"category":"auth","message":"The account that owns the key no longer exists.","fix":"Contact support — this should never happen."},{"code":"IP_NOT_ALLOWED","status":403,"category":"auth","message":"The caller IP is outside the key's allowlist.","fix":"Add the caller IP/CIDR in the dashboard or remove the restriction."},{"code":"SCOPE_MISSING","status":403,"category":"scope","message":"The token does not hold the scope required by this endpoint.","fix":"Edit the key in the dashboard and add the scope shown in the error detail."},{"code":"BRAND_NOT_ALLOWED","status":403,"category":"scope","message":"The token is restricted to a subset of brands that does not include the target.","fix":"Broaden the brand restriction on this key."},{"code":"RATE_LIMITED","status":429,"category":"quota","message":"Per-minute request cap exceeded.","fix":"Respect Retry-After, throttle calls, or upgrade your tier."},{"code":"DAILY_LIMIT_EXCEEDED","status":429,"category":"quota","message":"Per-day request cap exceeded.","fix":"Wait until midnight UTC or upgrade your tier."},{"code":"MONTHLY_QUOTA_EXCEEDED","status":429,"category":"quota","message":"Monthly publishes/replies/reads/webhooks quota exceeded for the current tier.","fix":"Wait until the 1st of next UTC month (see resets_at in the body) or upgrade your tier. The body includes `quota`, `limit`, `used` and `upgrade_url`."},{"code":"BRAND_PUBLISH_GUARDRAIL","status":429,"category":"quota","message":"Brand-level runaway safety-net hit (max 500 publishes / brand / 24h across all pages/platforms).","fix":"This cap only fires on runaway loops. Audit your integration for retries or duplicate jobs."},{"code":"PAGE_PUBLISH_GUARDRAIL","status":429,"category":"quota","message":"Platform-aware per-page publish guardrail hit (e.g. FB 10/h 40/24h, IG 8/h 30/24h, LN 3/h 15/24h, TT 10/h 50/24h, TW 50/h 300/24h).","fix":"Slow down posts to that specific page or spread them across more accounts. See retry_after_seconds in the body."},{"code":"SANDBOX_EXHAUSTED","status":402,"category":"quota","message":"Legacy sandbox tokens are capped at 100 lifetime requests.","fix":"Create a live token from the dashboard to continue. Sandbox tokens are deprecated for new signups."},{"code":"STORAGE_EXCEEDED","status":413,"category":"quota","message":"Account storage limit reached.","fix":"Delete unused uploads or upgrade your tier."},{"code":"MISSING_FIELD","status":400,"category":"validation","message":"A required body or query parameter is missing.","fix":"Check the error message for the field name."},{"code":"INVALID_FIELD","status":400,"category":"validation","message":"A parameter has an unsupported value or type.","fix":"Consult /openapi.json for the field contract."},{"code":"MESSAGE_TOO_LONG","status":400,"category":"validation","message":"Post or comment text exceeds the platform limit.","fix":"Shorten the message and retry."},{"code":"INVALID_IDEMPOTENCY_KEY","status":400,"category":"validation","message":"Idempotency-Key header is missing or too long.","fix":"Provide a unique string 1–120 characters long."},{"code":"IDEMPOTENCY_KEY_MISMATCH","status":409,"category":"validation","message":"The same Idempotency-Key was previously used with a different request body.","fix":"Use a fresh key for a different payload."},{"code":"PAGE_NOT_FOUND","status":404,"category":"platform","message":"The requested page does not exist or is not linked to your account.","fix":"List pages via /pages to confirm the id."},{"code":"PAGE_EXPIRED","status":400,"category":"platform","message":"The platform access token for this page expired.","fix":"Reconnect the page from the dashboard."},{"code":"PLATFORM_ERROR","status":502,"category":"platform","message":"The underlying platform rejected the request.","fix":"Inspect the error detail; often transient — retry after a short wait."},{"code":"MEDIA_TOO_LARGE","status":413,"category":"media","message":"Upload exceeds the per-file byte limit for your tier.","fix":"Compress the asset or upgrade your tier."},{"code":"UNSUPPORTED_MEDIA_TYPE","status":415,"category":"media","message":"MIME type is not accepted by the API.","fix":"Send a supported image/video format (jpg/png/webp/mp4)."},{"code":"INSUFFICIENT_CREDITS","status":402,"category":"credits","message":"The account does not have enough AI credits for this action.","fix":"Buy a credit pack or enable auto-refill at https://outreply.com/account/billing (the body includes `required`, `available` and `billing_url`), or upgrade the plan."},{"code":"PLAN_REQUIRED","status":403,"category":"credits","message":"This AI feature is only available on a higher plan (e.g. video generation on Elite).","fix":"Upgrade at https://outreply.com/pricing or use the default model."},{"code":"INVALID_REFERENCE_MEDIA","status":400,"category":"validation","message":"A reference image URL or media_id could not be used (unreachable, not an image, or not yours).","fix":"Pass a public http(s) image URL or a media_id from /media."},{"code":"AI_GENERATION_FAILED","status":502,"category":"ai","message":"The AI provider failed to generate the asset. Credits were refunded.","fix":"Retry, simplify the prompt, or contact support if it persists."},{"code":"AUTH_ERROR","status":500,"category":"server","message":"Unexpected error validating the token.","fix":"Retry; if persistent, contact support."},{"code":"SERVER_ERROR","status":500,"category":"server","message":"Generic unhandled server error.","fix":"Retry; if persistent, contact support."},{"code":"SPEC_ERROR","status":500,"category":"server","message":"Failed to build the OpenAPI spec.","fix":"Retry; contact support if the issue persists."}]}