Skip to main content
The Xquik REST API v1 provides programmatic access to monitors, events, webhooks, integrations, draws, extractions, trends, X data lookups, media downloads, tweet styles, drafts, account management, X account connections, and write actions (posting tweets, liking, retweeting, following, DMs, profile updates, media uploads, and community management).

Base URL

https://xquik.com/api/v1
All endpoints are served over HTTPS only. Plain HTTP requests receive a 301 redirect to HTTPS. Always use the full base URL - there is no shorthand or versioned subdomain.

OpenAPI Spec

The full API specification is available as an OpenAPI 3.1 document:
https://xquik.com/openapi.json
Use this with any OpenAPI-compatible tool (Postman, Insomnia, Swagger UI) or to generate client libraries. The spec follows RFC 9727 service discovery conventions.

Authentication

Pass your API key via the x-api-key header:
x-api-key: xq_YOUR_KEY_HERE
Generate keys from your dashboard. See Authentication for full details on key format, dual auth endpoints, and security best practices.

Rate Limits

ScopeLimitBurst
API endpoints (/api/v1/*)10 req/s20
General requests60 req/s100
Exceeding limits returns 429 Too Many Requests with a Retry-After header. Implement exponential backoff to handle rate limits gracefully:
#!/bin/bash
MAX_RETRIES=5
RETRY_DELAY=1

for i in $(seq 1 $MAX_RETRIES); do
  RESPONSE=$(curl -s -w "\n%{http_code}" \
    https://xquik.com/api/v1/account \
   -H "x-api-key: xq_YOUR_KEY_HERE")

  HTTP_CODE=$(echo "$RESPONSE" | tail -1)
  BODY=$(echo "$RESPONSE" | sed '$d')

  if [ "$HTTP_CODE" -ne 429 ]; then
    echo "$BODY"
    exit 0
  fi

  echo "Rate limited. Retrying in ${RETRY_DELAY}s..."
  sleep $RETRY_DELAY
  RETRY_DELAY=$((RETRY_DELAY * 2))
done

echo "Max retries exceeded."
exit 1
For a complete guide on handling rate limits, see Rate Limits.

Conventions

All IDs are returned as strings representing bigint values. Always treat IDs as opaque strings - never parse them as numbers:
{ "id": "123456789" }
All timestamps use ISO 8601 format in UTC. Store and compare timestamps as strings or parse them into proper date objects:
{ "createdAt": "2026-02-24T10:30:00.000Z" }
All errors return a JSON body with an error field containing a machine-readable error code:
{ "error": "error_code" }
StatusCodeMeaning
400invalid_inputRequest body failed validation
400invalid_idPath parameter is not a valid ID
400invalid_tweet_urlTweet URL format is invalid
400invalid_tweet_idTweet ID is empty or invalid
400invalid_usernameX username is empty or invalid
400invalid_tool_typeExtraction tool type is not recognized
400invalid_formatExport format is not csv, xlsx, or md
400invalid_paramsExport query parameters are missing or invalid
400missing_queryRequired query parameter is missing
400missing_paramsRequired query parameters are missing
400webhook_inactiveWebhook is disabled (test-webhook only)
403api_key_limit_reachedAPI key limit reached (100 max)
401unauthenticatedMissing or invalid API key
402no_subscriptionNo active subscription
402subscription_inactiveSubscription is not active
402usage_limit_reachedMonthly usage limit exceeded
402no_addonNo monitor addon on subscription
403monitor_limit_reachedPlan monitor limit exceeded
404not_foundResource does not exist
404user_not_foundX user not found
404tweet_not_foundTweet not found
409monitor_already_existsDuplicate monitor for same username
429-Rate limited - retry with backoff
429x_api_rate_limitedX data source rate limited - retry
500internal_errorServer error - contact support if persistent
502stream_registration_failedStream registration failed - retry
502x_api_unavailableX data source temporarily unavailable - retry
502x_api_unauthorizedX data source authentication failed - retry
400no_x_accountNo connected X account found for this user
400x_account_not_foundSpecified X account not connected
502x_write_failedX write action failed - check error message
See Error Handling for strategies on handling each error type.
Events, draws, extractions, and drafts use cursor-based pagination. When more results exist, the response includes hasMore: true and a nextCursor value:
{
  "events": [],
  "hasMore": true,
  "nextCursor": "MjAyNi0wMi0yNFQxMDozMDowMC4wMDBa..."
}
Pass nextCursor as the after query parameter to fetch the next page:
curl "https://xquik.com/api/v1/events?after=MjAyNi0wMi0yNFQxMDozMDowMC4wMDBa..." \
 -H "x-api-key: xq_YOUR_KEY_HERE"
Cursors are opaque strings - do not decode or construct them manually. Monitors, webhooks, and API keys return up to 200 items without pagination.

Event Types

Used across monitors, webhooks, and events:
TypeDescription
tweet.newOriginal tweet posted by the monitored account
tweet.quoteQuote tweet posted by the monitored account
tweet.replyReply posted by the monitored account
tweet.retweetRetweet posted by the monitored account
follower.gainedNew follower gained by the monitored account
follower.lostFollower lost by the monitored account

Next Steps