error code. Use these codes to build reliable integrations with automatic recovery.
Getting 400?
Fix your request body. See validation errors.
Getting 402?
Check your balance or subscription. See billing errors or billing guide.
Getting 429?
Implement backoff. See retry strategy or rate limits.
Quick reference
| Code | HTTP | Retryable | Quick fix |
|---|---|---|---|
invalid_input | 400 | No | Fix request body. Check required fields and types. |
invalid_json | 400 | No | Send valid JSON in the request body. |
invalid_id | 400 | No | Use a numeric string for the ID path parameter. |
invalid_tweet_url | 400 | No | Use full URL format: https://x.com/user/status/ID. |
invalid_tweet_id | 400 | No | Provide a valid numeric tweet ID. |
invalid_username | 400 | No | Provide a valid X username without @. |
invalid_tool_type | 400 | No | Use a valid extraction tool type. |
invalid_format | 400 | No | Use csv, json, md, md-document, pdf, txt, or xlsx. |
invalid_params | 400 | No | Check format and type values. |
missing_query | 400 | No | Include the required q parameter. |
missing_params | 400 | No | Check endpoint docs for required parameters. |
webhook_inactive | 400 | No | Reactivate the webhook before testing. |
unauthenticated | 401 | No | Check x-api-key header. Regenerate if revoked. |
account_needs_reauth | 401 | No | Re-authenticate X account from the dashboard. |
x_auth_failure | 401 | No | Re-authenticate X account from the dashboard. |
no_subscription | 402 | No | Subscribe from the dashboard. |
subscription_inactive | 402 | No | Reactivate subscription from the dashboard. |
usage_limit_reached | 402 | No | Wait for next billing period or enable extra usage. |
no_addon | 402 | No | Add a monitor addon from the dashboard. |
extra_usage_disabled | 402 | No | Enable extra usage from the subscription page. |
extra_usage_requires_v2 | 402 | No | Contact support to migrate pricing plan. |
manual_subscription | 402 | No | Extra usage requires Stripe-managed subscription. |
frozen | 402 | No | Update payment method from the dashboard. |
overage_limit_reached | 402 | No | Wait for current overage invoice to process. |
payment_failed | 402 | No | Update payment method from the dashboard. |
no_credits | 402 | No | Purchase credits or subscribe. |
insufficient_credits | 402 | No | Purchase more credits or wait for next billing period. |
api_key_limit_reached | 403 | No | Delete an existing key before creating a new one. |
monitor_limit_reached | 403 | No | Delete a monitor or add capacity ($5/month). |
not_found | 404 | No | Verify the resource ID. |
user_not_found | 404 | No | Check the username. Account may be suspended. |
tweet_not_found | 404 | No | Check the tweet ID. Tweet may be deleted. |
no_media | 404 | No | Tweet has no media attachments. |
article_not_found | 404 | No | Tweet has no linked article. |
draft_not_found | 404 | No | Verify the draft ID. |
style_not_found | 404 | No | Analyze the user’s style first via POST /api/v1/styles. |
no_cached_style | 404 | No | Analyze the user’s style first via POST /api/v1/styles. |
monitor_already_exists | 409 | No | Use the existing monitor. |
shadow_account | 422 | No | Account may be restricted on X. |
x_account_feature_required | 422 | No | Upgrade to X Premium on the target account. |
x_account_suspended | 422 | No | Check account status on X. |
x_account_protected | 422 | No | Request to follow the protected account first. |
x_duplicate_action | 422 | No | Action already completed. No retry needed. |
x_target_not_found | 422 | No | Verify target ID or username. |
x_content_too_long | 422 | No | Shorten tweet to 280 characters or fewer. |
x_rejected | 422 | No | Check request parameters. Contact support if persistent. |
x_write_unconfirmed | 202 | No | Verify outcome on X before retrying. |
rate_limit_exceeded | 429 | Yes | Retry with exponential backoff. Respect Retry-After. |
x_api_rate_limited | 502 | Yes | Retry in a few minutes. |
x_rate_limited | 429 | Yes | Wait a few minutes and retry. |
x_daily_limit | 429 | No | Wait 24 hours or use a different X account. |
internal_error | 500 | Yes | Retry with backoff. Contact support if persistent. |
x_api_unavailable | 502 | Yes | Retry with backoff. |
x_api_unauthorized | 502 | Yes | Retry later. Contact support if persistent. |
stream_registration_failed | 500 | Yes | Retry the request. |
x_write_failed | 500 | Yes | Retry the request. Contact support if persistent. |
x_write_ambiguous | 500 | No | Verify the action result manually. |
x_transient_error | 503 | Yes | Retry with backoff. |
media_download_failed | 500 | Yes | Retry the request. |
Error codes (detailed)
Response format:limit, retryAfter).
Validation errors (400)
Validation errors (400)
Request body or parameters failed validation. Fix the request before retrying.
| Code | Description | Recommended Action |
|---|---|---|
invalid_input | Request body failed validation | Fix the request body. Check required fields and types. |
invalid_json | Request body contains invalid JSON | Fix the request body to contain valid JSON. |
invalid_id | Path parameter is not a valid ID | Fix the path parameter. IDs are numeric strings. |
invalid_tweet_url | Tweet URL format is invalid | Use the full URL format: https://x.com/user/status/ID. |
invalid_tweet_id | Tweet ID is empty or invalid | Provide a valid numeric tweet ID in the path. |
invalid_username | X username is empty or invalid | Provide a valid X username without the @ prefix. |
invalid_tool_type | Extraction tool type not recognized | Use one of the 23 valid tool types. See Create Extraction. |
invalid_format | Export format is not supported | Use csv, json, md, md-document, pdf, txt, or xlsx. |
invalid_params | Export query parameters are invalid | Check the format and type values. |
missing_query | Required query parameter is missing | Include the required q parameter. |
missing_params | Required query parameters are missing | Check the endpoint docs for required parameters. |
webhook_inactive | Webhook is disabled | Reactivate via Update Webhook before testing. |
Authentication errors (401)
Authentication errors (401)
Missing or invalid credentials. Check your API key or session.
| Code | Description | Recommended Action |
|---|---|---|
unauthenticated | Missing or invalid API key | Check the x-api-key header. Regenerate the key if revoked. |
account_needs_reauth | Connected X account needs re-authentication | Re-authenticate the X account from the dashboard. |
x_auth_failure | X account session expired or invalid | Re-authenticate the X account from the dashboard. |
Billing & subscription errors (402)
Billing & subscription errors (402)
Subscription or payment issue. See Billing & Usage for plan details.
| Code | Description | Recommended Action |
|---|---|---|
no_subscription | No active subscription | Subscribe from the dashboard. |
subscription_inactive | Subscription is not active | Reactivate from the dashboard. |
usage_limit_reached | Monthly usage limit exceeded | Wait for the next billing period or check balance via Get Account. |
no_addon | No monitor addon on subscription | Add a monitor addon from the dashboard. |
extra_usage_disabled | Extra usage not enabled | Enable extra usage from the subscription page. |
extra_usage_requires_v2 | Extra usage requires updated pricing plan | Contact support to migrate to the current pricing version. |
manual_subscription | Extra usage unavailable for this subscription type | Extra usage is only available for Stripe-managed subscriptions. |
frozen | Extra usage paused, outstanding payment required | Update payment method from the dashboard. |
overage_limit_reached | Overage spending limit reached | Wait for the current overage invoice to be processed. See Spending Limits. |
payment_failed | Payment processing failed | Update payment method from the dashboard. |
no_credits | No credits available | Purchase credits or subscribe from the dashboard. |
insufficient_credits | Not enough credits for this operation | Check balance via Get Account. Purchase more credits or wait for next billing period. |
Permission errors (403)
Permission errors (403)
Action not allowed under current plan or limits.
| Code | Description | Recommended Action |
|---|---|---|
api_key_limit_reached | API key limit reached (100 max) | Delete an existing key before creating a new one. |
monitor_limit_reached | Plan monitor limit exceeded | Delete an existing monitor or add capacity ($5/month per extra monitor). |
Not found errors (404)
Not found errors (404)
The requested resource does not exist or has been deleted.
| Code | Description | Recommended Action |
|---|---|---|
not_found | Resource does not exist | Verify the resource ID. It may belong to another account or have been deleted. |
user_not_found | X user not found | Check the username. The account may not exist or may be suspended. |
tweet_not_found | Tweet not found | Check the tweet ID. The tweet may have been deleted or the ID is invalid. |
no_media | Tweet has no downloadable media | The tweet does not contain any media attachments. |
article_not_found | Tweet has no linked article | The tweet does not contain a linked article. |
draft_not_found | Draft does not exist | Verify the draft ID. It may have been deleted. |
style_not_found | No cached writing style | Analyze the user’s style first via POST /api/v1/styles. |
no_cached_style | No cached writing style for username lookup | Analyze the user’s style first via POST /api/v1/styles. |
Conflict errors (409)
Conflict errors (409)
Resource already exists or action outcome is unclear.
| Code | Description | Recommended Action |
|---|---|---|
monitor_already_exists | Duplicate monitor for this X account | Use the existing monitor. Call Update Monitor to change event types. |
Validation errors (422)
Validation errors (422)
| Code | Description | Recommended Action |
|---|---|---|
shadow_account | Account is shadow-banned | The X account may be restricted. Check account status on X. |
x_account_feature_required | X Premium required for this action | Upgrade to X Premium on the target account. |
x_account_suspended | X account suspended or restricted | Check the account status on X. |
x_account_protected | Target account is private | The target account has a protected profile. Request to follow them first. |
x_duplicate_action | Action already performed (liked, retweeted, etc.) | No action needed. The operation was already completed. |
x_target_not_found | Tweet or user target does not exist | Verify the target ID or username. The resource may have been deleted. |
x_content_too_long | Tweet exceeds character limit | Shorten the tweet text to 280 characters or fewer. |
x_rejected | X rejected the write with an unknown reason | Check the request parameters and retry. Contact support if persistent. |
Unconfirmed write (202)
Unconfirmed write (202)
The write action may have completed but confirmation could not be obtained. Do not retry without verifying the outcome first.
| Code | Description | Recommended Action |
|---|---|---|
x_write_unconfirmed | Action may have been completed but could not be confirmed | Check the X account timeline or profile to verify before retrying. Do not retry without checking first to avoid duplicates. Not retryable. |
Rate limit errors (429)
Rate limit errors (429)
Request rate exceeded. See Rate Limits for tier details.
| Code | Description | Recommended Action |
|---|---|---|
rate_limit_exceeded | API rate limited | Retry with exponential backoff. Respect the Retry-After header. Response includes retryAfter (seconds). |
x_api_rate_limited | X data source rate limited | Retry in a few minutes. The data source is experiencing high traffic. |
x_rate_limited | X rate-limited the write request | Wait a few minutes and retry. The platform is throttling write operations. |
x_daily_limit | X account reached daily posting limit | Wait 24 hours before retrying with this account. Use a different X account if available. Not retryable. |
Server & upstream errors (500/502)
Server & upstream errors (500/502)
Transient failures. Retry with exponential backoff (max 3 attempts).
| Code | Description | Recommended Action |
|---|---|---|
internal_error | Server error | Retry with backoff. Contact support if persistent. |
x_api_unavailable | X data source temporarily unavailable | Retry with backoff. |
x_api_unauthorized | X data source authentication failed | Retry later. Contact support if persistent. |
stream_registration_failed | Stream registration failed | Retry the request. |
x_write_failed | Write action failed unexpectedly | Retry the request. Contact support if persistent. |
x_write_ambiguous | Write action completion could not be confirmed | Verify the action result manually. The write may have succeeded. |
x_transient_error | Upstream timeout or temporary failure | Retry with backoff. The platform is experiencing intermittent issues. |
media_download_failed | Media download from source failed | Retry the request. |
Retry with exponential backoff
Retry only on429 and 5xx responses. Use exponential backoff with random jitter to avoid thundering herds. Max 3 retries.
Formula: delay = baseDelay * 2^attempt + random(0, jitter)
Rate limit handling
When you exceed the rate limit, Xquik returns a429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.
Detecting rate limits:
| Signal | Value |
|---|---|
| HTTP status | 429 |
Retry-After header | Seconds until the limit resets (e.g. 60) |
Extracting retryAfter from the response body
Rate limit responses include aretryAfter field in the JSON body (seconds until the limit resets). This is equivalent to the Retry-After header but accessible without parsing headers.
Best practices
Distinguish client errors from server errors
Distinguish client errors from server errors
4xx errors (except 429) indicate a problem with your request. Fix the request before retrying. 5xx errors and 429 are transient. Retry with backoff.
Log error codes for debugging
Log error codes for debugging
Always log the full error response including status code and error body. This makes it easy to diagnose issues in production.
Handle 409 gracefully
Handle 409 gracefully
monitor_already_exists is not a failure. The monitor you need already exists. List monitors to find it instead of treating this as an error.Set request timeouts
Set request timeouts
Set a 30-second timeout on all API requests. If a request hangs, retry it rather than waiting indefinitely.
Use idempotent operations
Use idempotent operations
Creating a monitor for the same username returns
409. Deleting a non-existent resource returns 404. Both are safe to retry.Rate Limits
Detailed rate limit tiers and client-side rate limiting.
API Overview
Base URL, authentication, and API conventions.