error code to choose recovery.
Getting 400?
Getting 401 or 402?
Getting 429?
Quick reference
Start with HTTP status. Retry only when stated.400 request validation
invalid_input,
invalid_json, invalid_id, invalid_tweet_url, invalid_tweet_id,
invalid_username, invalid_user_id, invalid_tool_type,
invalid_format, invalid_params, missing_query, missing_ids,
missing_params, too_many_ids, unsupported_field, and
invalid_coverage_cursor.401 authentication
x-api-key, regenerate revoked keys, or re-authenticate
the connected X account. Covers unauthenticated and x_auth_failure.402 billing and credits
payment_options, then get explicit user confirmation.
Covers no_subscription, subscription_inactive, payment_failed,
no_credits, and insufficient_credits.403 permissions and account health
api_key_limit_reached, dm_not_permitted,
account_needs_reauth, and account_restricted.404 missing resource
not_found,
account_not_found, user_not_found, tweet_not_found, no_media,
article_not_found, draft_not_found, style_not_found, and
no_cached_style.409 or 410 cursor state
Retry-After and retry once. Gone cursor: restart
cursorless and deduplicate IDs.422 write validation
x_account_feature_required,
x_account_suspended, x_account_protected, x_duplicate_action,
x_dm_not_allowed, x_target_not_found, x_content_too_long,
x_rejected, and media_download_failed.202 active write
statusUrl while terminal is
false. Follow Retry-After, pollAfterMs, and nextAction.429 rate limit or cooldown
rate_limit_exceeded and x_rate_limited after
Retry-After or exponential backoff. Wait out login_cooldown via
retryAfterMs. Do not retry x_daily_limit on the same X account for 24
hours.500, 502, and 503 transient failures
internal_error, x_api_rate_limited,
x_api_unavailable and x_api_unauthorized. For writes, retry only when
safeToRetry is true, using a new Idempotency-Key.Common error codes
This section covers common recovery paths. The OpenAPIError schema lists every public code.
Default response.
xquik-api-contract: 2026-04-29 for a structured error object. Some
responses also include message, reason, retryAfter, or retryAfterMs.
Validation errors (400)
Validation errors (400)
invalid_input
invalid_json
invalid_id
invalid_tweet_url
https://x.com/user/status/ID.invalid_tweet_id
invalid_username
@ prefix, or send a numeric user ID where supported.invalid_user_id
invalid_tool_type
invalid_format
csv, json, md, md-document,
pdf, txt, or xlsx.invalid_params
format and type
values for that export endpoint.missing_query
q parameter before calling
search or community endpoints.missing_ids
ids parameter.missing_params
too_many_ids
unsupported_field
media, not uploaded media IDs.invalid_coverage_cursor
Authentication errors (401)
Authentication errors (401)
unauthenticated
x-api-key or
regenerate a revoked key.x_auth_failure
Anonymous paid-read authentication (401)
Anonymous paid-read authentication (401)
401 with WWW-Authenticate: Bearer and a guest wallet action. This is not a Payment challenge. Authenticate or get confirmation before calling the action.Billing & credit errors (402)
Billing & credit errors (402)
402 creates no checkout. Account and OAuth responses advertise account billing actions. Guest responses advertise only POST /api/v1/guest-wallets/topups. Direct MPP responses include a Payment challenge and guest option. Get confirmation before calling any action.subscription_inactive
payment_failed
no_credits
insufficient_credits
Permission errors (403)
Permission errors (403)
api_key_limit_reached
dm_not_permitted
account_needs_reauth
account_restricted
Not found errors (404)
Not found errors (404)
not_found
account_not_found
user_not_found
tweet_not_found
no_media
article_not_found
draft_not_found
style_not_found
no_cached_style
Conflict and cursor errors (409/410)
Conflict and cursor errors (409/410)
monitor_already_exists
coverage_cursor_unavailable
Retry-After seconds. Retry the same cursor once.coverage_cursor_gone
Retry-After. Restart cursorless and deduplicate IDs.Validation errors (422)
Validation errors (422)
x_account_feature_required
x_account_suspended
x_account_protected
x_duplicate_action
x_dm_not_allowed
x_target_not_found
x_content_too_long
x_rejected
media_download_failed
Active write lifecycle (202)
Active write lifecycle (202)
accepted, dispatching,
or pending_confirmation.Poll
id, request.hash, account, target, and billing. Poll
statusUrl after Retry-After or pollAfterMs.Recovery
terminal is true. Retry only when safeToRetry is true,
using a new key. Verify the result when nextAction.type is
verify_result.Rate limit errors (429)
Rate limit errors (429)
rate_limit_exceeded
Retry-After seconds
from the response; JSON also includes retryAfter when available.login_cooldown
retryAfterMs or the
Retry-After header before reconnecting or reauthenticating.x_rate_limited
Retry-After, then retry with backoff.x_daily_limit
Server & service errors (500/502/503)
Server & service errors (500/502/503)
internal_error
x_api_rate_limited
x_api_unavailable
Retry-After
when present, otherwise retry with backoff.x_api_unauthorized
x_write_failed
safeToRetry and
nextAction. Contact support if the action remains unsafe to retry.x_write_ambiguous
x_transient_error
safeToRetry is true.Write lifecycle recovery
Every write can return a durable action. Inspect the JSON lifecycle fields before generic success or error handling.Store the action
id, status, request.hash, account, target, billing, and
statusUrl.Poll the write action
statusUrl while terminal is false. Respect Retry-After and
pollAfterMs.Persist the outcome
result and settled billing after terminal becomes true.Follow retry safety
safeToRetry is true, using a new Idempotency-Key.
Verify the result when nextAction.type is verify_result.Retry with exponential backoff
For reads, retry only on429 and 5xx responses. Use Retry-After, then
exponential backoff with jitter. For writes, follow the durable action’s
safeToRetry and nextAction fields instead.
Formula. delay = baseDelay * 2^attempt + random(0, jitter)
Rate limit handling
When a request is rate limited, Xquik returns429 Too Many Requests with a
Retry-After header. Some JSON bodies also include retryAfter in seconds or
retryAfterMs in milliseconds for login cooldowns.
HTTP status
429 Too Many Requests means the request is rate limited or waiting on an
account cooldown.Retry-After header
Retry-After header gives seconds to wait before sending the same
request again.Check the status
response.status === 429 before normal success handling.Prefer the header
Retry-After as seconds. If it is missing, read retryAfter or retryAfterMs from the JSON body.Wait the full duration
Back off after another 429
Best practices
Distinguish client errors from server errors
Distinguish client errors from server errors
4xx response unchanged. Fix authentication, billing,
permissions, or input first. Retry 429 and 5xx only as described above.Log error codes for debugging
Log error codes for debugging
Handle 409 gracefully
Handle 409 gracefully
monitor_already_exists. For a busy cursor, follow Retry-After and
retry once.Set request timeouts
Set request timeouts
Use idempotent operations
Use idempotent operations
409. Deleting a non-existent resource returns 404. Both are safe to retry.