Skip to main content

Error Codes

Error Codes

All XCROP API errors follow a consistent JSON format. The HTTP status code indicates the error category, and the response body provides details for debugging.

Error Response Format

JSON
{
  "error": "Human-readable description of the error"
}

Some error responses include an additional code field (e.g. AUTH_REQUIRED) for programmatic handling.

HTTP Status Codes

StatusTypeDescriptionAction
200OKRequest succeededProcess the response data
400BAD_REQUESTInvalid parameters or missing fieldsCheck request body and query params
401UNAUTHORIZEDMissing or invalid API keyVerify your Authorization header
403FORBIDDENAccess denied (e.g. no X account connected)Connect X account or check permissions
404NOT_FOUNDResource does not existVerify the username, tweet ID, or endpoint
409CONFLICTDuplicate resource or state conflictCheck for existing pending operations
422UNPROCESSABLERequest understood but cannot be processed. REPOSTS_UNREADABLE (check-retweet), REPLIES_UNREADABLE (check-reply) and POSTS_UNREADABLE (check-quote) usually mean the account is protected, suspended or withheld, so that tab cannot be read at all; X returning nothing for it is a rarer second cause. None of them are billedCheck the error code. The *_UNREADABLE codes are about the account, not your parameters. Do not retry immediately: for five minutes that handle is answered from memory without calling X. If you believe the account is readable, try again after that
429RATE_LIMIT_EXCEEDEDCredit or per-minute limit reachedWait for reset or upgrade plan
500INTERNAL_ERRORServer-side errorRetry after a short delay; contact support if persistent
503UPSTREAM_BUSYThe upstream read could not be completed: capacity temporarily exhausted, the read timed out, or the data backend was restarting. ENDPOINT_NOT_DEPLOYED means that endpoint is not live on the backend yetRetry after the Retry-After header (30 seconds; 600 for ENDPOINT_NOT_DEPLOYED). Not billed

Common Error Examples

401: Missing or invalid API keyJSON
{
  "error": "Authentication required. Please provide an API key or log in.",
  "code": "AUTH_REQUIRED"
}
400: Missing required fieldJSON
{
  "error": "Missing required field: query"
}
429: Monthly credits used upJSON
{
  "error": "Monthly credit limit reached",
  "code": "CREDITS_EXHAUSTED"
}

Retry Strategy

For 429 and 5xx errors, implement exponential backoff:

Retry with backoffJAVASCRIPT
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const res = await fetch(url, options);

    if (res.ok) return res.json();

    if (res.status === 429 || res.status >= 500) {
      const delay = Math.min(1000 * Math.pow(2, i), 30000);

      console.log("Retrying in " + delay + "ms...");
      await new Promise(r => setTimeout(r, delay));
      continue;
    }

    throw new Error("API error: " + res.status);
  }
  throw new Error("Max retries exceeded");
}
⚠
Do not retry 400, 401, 403, 404, or 422 errors: these indicate issues with your request, or with the account you asked about, that won't be resolved by retrying. None of them are billed.

More in Guides

Full documentation with search: xcrop.io/docs