Skip to main content
Common issues, error codes, and solutions. If your problem isn’t covered here, contact support@xquik.com.

Error codes

401 Unauthenticated

The API key or OAuth token is missing, invalid, expired, or revoked. Check the following:
  • API key header: Send x-api-key: xq_... or Authorization: Bearer xq_....
  • OAuth header: Send Authorization: Bearer <access_token>. OAuth clients normally manage this automatically.
  • Key format: Must start with xq_. If it doesn’t, you’re using the wrong value.
  • Key revoked: Revoked keys return 401 immediately. Generate a new key from the dashboard.
  • OAuth token expired: Let the MCP client refresh the token. Reconnect Xquik if refresh fails.
  • API key management auth: Listing, creating, and revoking keys require a same-origin dashboard session. API keys and OAuth bearer tokens cannot manage keys.

401 authentication or 402 payment required

Anonymous non-MPP paid reads return 401 with a Bearer challenge and guest wallet action. Direct MPP reads return 402 with a Payment challenge and the same action. Account or guest credit failures also return 402. The failed request creates no checkout. Solutions:
  • For account keys, check GET /api/v1/account and use only the advertised account payment action
  • For guest keys, check guest wallet status and use only the advertised guest top-up action
  • For the 7 direct MPP operations, complete the MPP challenge or ask the user to confirm a guest wallet amount
  • For the other 26 guest-eligible reads, authenticate or ask the user to confirm a guest wallet amount
  • Use Estimate Extraction before running extractions to avoid surprises
Ask the user to choose an option and amount before creating checkout. Never trigger checkout, top-up, or subscription automatically after 401 or 402.

Monitor Credits

Monitor slots are unlimited. Active instant monitors cost 21 credits per hour and require available credits while enabled.
Solutions:
  • Pause an unused account monitor with PATCH /api/v1/monitors/{id} and { "isActive": false }
  • Pause an unused keyword monitor with PATCH /api/v1/monitors/keywords/{id} and { "isActive": false }
  • Delete an unused monitor with DELETE /api/v1/monitors/{id} or DELETE /api/v1/monitors/keywords/{id}
  • Check current monitor billing: GET /api/v1/account shows monitorsUsed and monitorBilling

429 Too Many Requests

You’ve exceeded the API rate limit. The API uses fixed windows per tier:

Read

GET, HEAD, and OPTIONS share a limit of 60 requests per 1 second.

Write

POST, PUT, and PATCH share a limit of 30 requests per 60 seconds.

Delete

DELETE requests are limited to 15 requests per 60 seconds.
Solutions:
  • Respect Retry-After; otherwise start at 1 second, add jitter, and stop after 3 retries.
  • Requests sent before the fixed window resets keep returning 429 until Retry-After elapses.
  • Check the Retry-After header for the server-recommended wait time.
  • Use webhooks instead of polling. Webhooks push events to you in real time, eliminating the need for repeated API calls.
  • Batch your logic. Fetch events once per minute instead of once per second.
See the Rate Limits guide for backoff code examples.

502/503 Read Service Busy or Unavailable

The read service is temporarily unavailable or busy. This is usually transient. Solutions:
  • Respect Retry-After when present, then retry the request
  • If no Retry-After header is present, retry after 5-10 seconds
  • Use exponential backoff (see Error Handling)
  • If the error persists for more than 5 minutes, the read service may be experiencing an outage
The same applies to draws and X data lookup endpoints (/api/v1/x/*).

Common questions

Webhooks not arriving?

Webhooks can fail silently. Walk through this checklist:
  1. Webhook is active: Verify isActive: true and deliveryStatus: "active" via GET /api/v1/webhooks. Paused webhooks do not receive deliveries.
  2. HTTPS required: HTTP endpoints are rejected. Your URL must start with https://.
  3. Response time: We recommend responding with 2xx within 10 seconds. Slow responses may be treated as failures.
  4. Check deliveries: Call GET /api/v1/webhooks/{id}/deliveries to see delivery status, attempt count, and error messages.
  5. Correlate source events: Call GET /api/v1/events/{id} with the stored streamEventId.
  6. Local testing: If using ngrok or a tunnel, verify it’s running and the URL is current. Ngrok URLs change on restart (free plan).
  7. Needs attention: If deliveryStatus is needs_attention, fix the receiver and call POST /api/v1/webhooks/{id}/resume. The receiver must pass a signed test before delivery resumes.
  8. Event type mismatch: Your webhook must subscribe to the event types your monitors produce. A webhook listening for tweet.new won’t receive tweet.reply events.
Tip: See the Webhook Testing guide for a step-by-step local setup with ngrok.

Monitor not tracking events?

If your monitor is active but no events appear:
  • Check isActive: Confirm via GET /api/v1/monitors/{id} that isActive is true. Paused monitors don’t track.
  • Event propagation delay: Events take seconds to minutes to appear depending on X API latency. This is normal.
  • Event types: Verify your monitor’s eventTypes array includes the type you expect. A monitor tracking only ["tweet.new"] won’t capture replies or retweets.
  • Account activity: The monitored X account must actually post content matching your event types. No posts = no events.
  • Pagination: If listing events, check hasMore in the response. Older events may be on subsequent pages.

How do I replay stored monitor events?

Call GET /api/v1/events?monitorId={id}&limit=50 for account monitors, or GET /api/v1/events?keywordMonitorId={id}&limit=50 for keyword monitors, then process each event once. If hasMore is true, store nextCursor and pass it as after on the next request. Add eventType when you need to separate follows, tweets, replies, or keyword matches.

Write action still pending?

If a tweet or reply returns 202 x_write_unconfirmed, the send was dispatched but final confirmation is pending.
  • Store writeActionId, status, charged, and chargedCredits
  • Do not retry-send the same post while status is pending_confirmation
  • Poll GET /api/v1/x/write-actions/{id} before scheduling follow-up work
  • Store tweetId only after the status response confirms success

How do I check my usage?

Call GET /api/v1/account. The creditInfo object shows your balance:
  • creditInfo.balance: Remaining credits available for metered calls
  • When balance reaches 0, metered calls are rejected until credits are topped up or auto top-up triggers
The dashboard also displays usage graphically on the billing page. See Billing & Usage for credit costs and billing.

Can I use the API without a subscription?

Yes. Full account metered operations work while enough available credits remain. Choose the access boundary:
  • Guest wallet: Prepay 33 eligible GET routes through a confirmed 1010-250 USD Stripe-hosted Payment Link.
  • MPP: Pay 7 fixed-price GET operations per request without an account or API key.
  • Full account: Use available account credits for writes, monitors, extractions, draws, and connected-account reads. Webhooks and account management are free.
Subscribe for monthly credits or top up from the dashboard billing page. Remaining credits stay usable after a plan ends.

How do I connect an AI agent?

Xquik has 2 MCP servers. Choose based on what the agent needs to do.

Search docs

Connect https://docs.xquik.com/mcp. It is read-only and requires no auth.

Run API actions

Connect https://xquik.com/mcp. Full credentials expose 118 operations. Guest paid_reads keys expose 33 eligible GET routes.
Setup:
  1. For docs search, add https://docs.xquik.com/mcp.
  2. For account actions, use a full API key or OAuth login. Prefer OAuth when the client supports browser authorization.
  3. For guest reads, activate a guest key through direct REST, then authenticate MCP with that key.
Guest wallet creation, status, and top-up are never executable through MCP. Current client paths are:
  • OAuth 2.1: Claude.ai, Claude Desktop, Claude Code, ChatGPT, Cursor, VS Code, Windsurf, OpenCode, Gemini CLI, GitHub Copilot CLI, Cline, and Qwen Code
  • API-key fallback: affected Codex and Goose releases until their callback implementations preserve the RFC 9207 issuer value
  • API-key only: Roo Code’s archived final release has no MCP OAuth provider
  • No native MCP: Pi requires a separately installed and tested adapter
See Docs MCP server for docs search, MCP Server overview for account actions, and the MCP Tools reference for tool details.

MCP OAuth does not open or shows an unknown application

Use this checklist:
  1. Enter the exact server URL: https://xquik.com/mcp.
  2. Remove any manually entered client ID or client secret unless your client requires preregistration.
  3. Remove and re-add the connector to restart OAuth discovery.
  4. Start login from the MCP client. Do not open /api/auth/google directly.
  5. Allow the browser to return to the client’s exact callback URL.
Xquik publishes all required discovery documents:
  • Protected resource metadata: https://xquik.com/.well-known/oauth-protected-resource/mcp
  • Authorization server metadata: https://xquik.com/.well-known/oauth-authorization-server
  • Agent-readable auth guide: https://xquik.com/auth.md
Xquik supports CIMD and DCR. Let the client use its documented registration flow. Claude selects CIMD when the authorization metadata advertises support and the public none authentication method; otherwise it can use DCR. ChatGPT app creators choose CIMD or DCR during setup. If a URL-form client_id fails, its public HTTPS metadata URL must have a non-root path, return JSON without a redirect, repeat the exact URL in client_id, and list the callback in redirect_uris.

Codex OAuth issuer validation error

This workaround applies to affected Codex and Goose releases. They can stop after browser approval and report:
Affected releases discard the RFC 9207 iss authorization response value before token exchange. Xquik already returns iss=https://xquik.com and advertises authorization_response_iss_parameter_supported: true. Xquik keeps issuer validation enabled. Codex users can track the upstream Codex issue for the fixed release. Retrying OAuth does not restore the discarded value. Export an API key before configuring either fallback:
Add the API MCP server to ~/.codex/config.toml or a trusted project’s .codex/config.toml:
Restart Codex, then run codex mcp list. Do not run codex mcp login xquik while the bearer-token fallback is active. Never commit the key or place its value directly in config.toml. For Goose, add this extension to ~/.config/goose/config.yaml:
Goose substitutes XQUIK_API_KEY before sending the header. Remove the custom header configuration only after your Goose release preserves the authorization response issuer. The Docs MCP server needs no authentication, so Codex and Goose can retrieve these instructions while API MCP OAuth is blocked:
Goose can connect to the same documentation server without OAuth:
When the upstream Codex issue identifies a fixed release, upgrade Codex, remove bearer_token_env_var, and run codex mcp login xquik again.

How do I export extraction results?

Call GET /api/v1/extractions/{id}/export?format=csv (or xlsx or md). The response is a file download. Limits:
  • Maximum 100,000 rows per export (10,000 for PDF)
  • Available formats: CSV, JSON, Markdown, Markdown Document, PDF, TXT, XLSX
See Export Extraction for column details and code examples.

Still stuck?

Last modified on July 16, 2026