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_...orAuthorization: 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 return401 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/accountand 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
401 or 402.
Monitor Credits
Monitor slots are unlimited. Active instant monitors cost 21 credits per hour and require available credits while enabled.- 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}orDELETE /api/v1/monitors/keywords/{id} - Check current monitor billing:
GET /api/v1/accountshowsmonitorsUsedandmonitorBilling
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.- Respect
Retry-After; otherwise start at 1 second, add jitter, and stop after 3 retries. - Requests sent before the fixed window resets keep returning
429untilRetry-Afterelapses. - Check the
Retry-Afterheader 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.
502/503 Read Service Busy or Unavailable
The read service is temporarily unavailable or busy. This is usually transient. Solutions:- Respect
Retry-Afterwhen present, then retry the request - If no
Retry-Afterheader 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
/api/v1/x/*).
Common questions
Webhooks not arriving?
Webhooks can fail silently. Walk through this checklist:- Webhook is active: Verify
isActive: trueanddeliveryStatus: "active"viaGET /api/v1/webhooks. Paused webhooks do not receive deliveries. - HTTPS required: HTTP endpoints are rejected. Your URL must start with
https://. - Response time: We recommend responding with
2xxwithin 10 seconds. Slow responses may be treated as failures. - Check deliveries: Call
GET /api/v1/webhooks/{id}/deliveriesto see delivery status, attempt count, and error messages. - Correlate source events: Call
GET /api/v1/events/{id}with the storedstreamEventId. - Local testing: If using ngrok or a tunnel, verify it’s running and the URL is current. Ngrok URLs change on restart (free plan).
- Needs attention: If
deliveryStatusisneeds_attention, fix the receiver and callPOST /api/v1/webhooks/{id}/resume. The receiver must pass a signed test before delivery resumes. - Event type mismatch: Your webhook must subscribe to the event types your monitors produce. A webhook listening for
tweet.newwon’t receivetweet.replyevents.
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 viaGET /api/v1/monitors/{id}thatisActiveistrue. 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
eventTypesarray 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
hasMorein the response. Older events may be on subsequent pages.
How do I replay stored monitor events?
CallGET /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 returns202 x_write_unconfirmed, the send was dispatched
but final confirmation is pending.
- Store
writeActionId,status,charged, andchargedCredits - 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
tweetIdonly after the status response confirms success
How do I check my usage?
CallGET /api/v1/account. The creditInfo object shows your balance:
creditInfo.balance: Remaining credits available for metered calls- When
balancereaches0, metered calls are rejected until credits are topped up or auto top-up triggers
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 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.
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.- For docs search, add
https://docs.xquik.com/mcp. - For account actions, use a full API key or OAuth login. Prefer OAuth when the client supports browser authorization.
- For guest reads, activate a guest key through direct REST, then authenticate MCP with that key.
- 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
MCP OAuth does not open or shows an unknown application
Use this checklist:- Enter the exact server URL:
https://xquik.com/mcp. - Remove any manually entered client ID or client secret unless your client requires preregistration.
- Remove and re-add the connector to restart OAuth discovery.
- Start login from the MCP client. Do not open
/api/auth/googledirectly. - Allow the browser to return to the client’s exact callback URL.
- 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
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: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:
~/.codex/config.toml or a trusted project’s .codex/config.toml:
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:
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:
bearer_token_env_var, and run codex mcp login xquik again.
How do I export extraction results?
CallGET /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
Still stuck?
- Authentication: API key format, header requirements, and dual auth details.
- Error Handling: Error codes, retry strategies, and graceful degradation.
- Billing & Usage: Pricing, credits, and per-operation costs.