openapi: 3.2.0 info: title: Xquik Draws API version: '1.0' description: "Xquik is an independent third-party service. Not affiliated with X Corp. \"Twitter\" and \"X\" are trademarks of X Corp. Look up tweets, users, and X trends. Search tweets, check follow relationships, download media, and monitor accounts. 33 paid-read endpoints accept prepaid credits without a subscription. 7 fixed-price lookups also accept direct MPP payments. Write and automation endpoints require an API key or OAuth 2.1 bearer token.\n\n## Xquik SDKs\n\nStainless generates each SDK from this OpenAPI schema. Pick a language:\n\n- TypeScript / Node.js: `npm i x-twitter-scraper` -\n [Xquik-dev/x-twitter-scraper-typescript](https://github.com/Xquik-dev/x-twitter-scraper-typescript)\n\n- Python: `pip install x-twitter-scraper` -\n [Xquik-dev/x-twitter-scraper-python](https://github.com/Xquik-dev/x-twitter-scraper-python)\n\n- Go: `go get github.com/Xquik-dev/x-twitter-scraper-go` -\n [Xquik-dev/x-twitter-scraper-go](https://github.com/Xquik-dev/x-twitter-scraper-go)\n\n- Ruby: `gem install x-twitter-scraper` -\n [Xquik-dev/x-twitter-scraper-ruby](https://github.com/Xquik-dev/x-twitter-scraper-ruby)\n\n- Java (source build; Maven Central pending) -\n [Xquik-dev/x-twitter-scraper-java](https://github.com/Xquik-dev/x-twitter-scraper-java)\n\n- Kotlin (source build; Maven Central pending) -\n [Xquik-dev/x-twitter-scraper-kotlin](https://github.com/Xquik-dev/x-twitter-scraper-kotlin)\n\n- C# / .NET: `dotnet add package XTwitterScraper` -\n [Xquik-dev/x-twitter-scraper-csharp](https://github.com/Xquik-dev/x-twitter-scraper-csharp)\n\n- PHP: `composer require xquik/x-twitter-scraper` -\n [Xquik-dev/x-twitter-scraper-php](https://github.com/Xquik-dev/x-twitter-scraper-php)\n\n- CLI: `go install github.com/Xquik-dev/x-twitter-scraper-cli/cmd/x-twitter-scraper@latest` -\n [Xquik-dev/x-twitter-scraper-cli](https://github.com/Xquik-dev/x-twitter-scraper-cli)\n\n- Terraform Provider (Terraform Registry) -\n [Xquik-dev/terraform-provider-x-twitter-scraper](https://github.com/Xquik-dev/terraform-provider-x-twitter-scraper)\n\n\nOpenClaw plugin: [Xquik-dev/tweetclaw](https://github.com/Xquik-dev/tweetclaw) (`openclaw plugins install clawhub:@xquik/tweetclaw`)." x-guidance: '## Common tasks **Find a tweet** - GET /x/tweets/{id} with a numeric tweet ID. Returns full tweet data: text, author, metrics (likes, retweets, replies, views), media URLs, and creation timestamp. Cost: $0.00015 per lookup. **Search tweets** - GET /x/tweets/search?q={query}&limit={n}. Supports X search operators, structured filters like fromUser, mediaType, minFaves, hashtags, and verifiedOnly, plus exact lookup for a pasted Tweet ID or X status URL. Plain from:user date windows are optimized for timeline completeness. Returns up to 200 tweets per page with cursor-based pagination. Cost: $0.00015 per tweet returned. **Find a user** - GET /x/users/{id} where {id} is a numeric user ID or @username. Returns profile data: name, bio, follower/following counts, verification status, join date. Cost: $0.00015 per lookup. **Check if A follows B** - GET /x/followers/check?source={a}&target={b} where source and target are usernames, @usernames, or X or Twitter profile URLs. Cost: $0.00075. **Get trending topics** - GET /trends?woeid={region}&count={n}. WOEID 1 = worldwide, 23424977 = US, 23424975 = UK, 23424969 = Turkey. Cost: $0.00045. **Download media** - POST /x/media/download with {"tweetIds": ["123", "456"]} body. Returns download URLs for images and videos. Cost: 1 credit per fresh tweet processed with media; cached repeat downloads are free. **Read an article** - GET /x/articles/{tweetId} for long-form X Articles. Returns full article HTML, cover image, and metadata. Cost: $0.00075. ## Pagination Default v1 responses keep their existing pagination fields for compatibility. Platform list endpoints return `hasMore` and `nextCursor`; X data endpoints return `has_next_page` and `next_cursor`. Send `xquik-api-contract: 2026-04-29` to receive the unified best-practice fields `has_more` and `next_cursor`. Pass the cursor back as `?cursor={cursor}`; legacy `?after={cursor}` still works. Dynamic-priced endpoints charge per item returned, not per request. ## Authentication Eligible paid read endpoints accept accountless prepaid credit wallets. Fixed-price lookups also accept direct MPP payments. Media downloads, write endpoints, and automation features require authentication. Send an Xquik API key through `x-api-key`, `Xquik-Api-Key`, or `Authorization: Bearer xq_...`. Send an OAuth 2.1 access token through `Authorization: Bearer`. ## Best-Practice Response Contract v1 keeps its original response contract by default so existing integrations do not break. Send `xquik-api-contract: 2026-04-29` to opt in to the best-practice contract: snake_case response fields, Unix timestamps in seconds, structured error objects, `has_more` and `next_cursor` pagination fields, `object` resource identifiers, and prefixed IDs where available. Dependency failures that returned 502 in default v1 return 424 in the opt-in contract. Future major API versions should make this contract the default.' contact: name: Xquik url: https://xquik.com email: support@xquik.com servers: - url: https://xquik.com security: - apiKey: [] - oauthBearer: [] tags: - name: Draws description: Giveaway draws from tweet replies paths: /api/v1/draws: get: operationId: listDraws summary: List draws tags: - Draws security: - apiKey: [] - oauthBearer: [] parameters: - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/After' responses: '200': description: Draw list content: application/json: schema: type: object required: - draws - hasMore properties: draws: type: array items: $ref: '#/components/schemas/DrawListItem' example: [] hasMore: type: boolean example: false nextCursor: type: string example: abc123 example: draws: [] hasMore: false '401': $ref: '#/components/responses/Unauthenticated' '429': $ref: '#/components/responses/RateLimitExceeded' default: content: application/json: example: error: internal_error message: Unexpected error. Try again. schema: $ref: '#/components/schemas/Error' description: Unexpected error. description: List draws. post: operationId: createDraw summary: Run giveaway draw description: Runs a giveaway draw from a source tweet. The draw first checks the minimum credits needed to inspect the source tweet and at least one candidate. Remaining credits cap how many replies and retweeters can be inspected before filters and winner selection run. tags: - Draws security: - apiKey: [] - oauthBearer: [] requestBody: required: true description: Tweet URL, winner count, and optional eligibility filters (retweet, follow, keywords, hashtags, account age). content: application/json: schema: type: object required: - tweetUrl properties: tweetUrl: type: string format: uri example: https://x.com/elonmusk/status/1234567890 winnerCount: type: integer default: 1 example: 3 backupCount: type: integer example: 2 uniqueAuthorsOnly: type: boolean example: true mustRetweet: type: boolean example: true mustFollowUsername: type: string example: elonmusk filterMinFollowers: type: integer example: 50 filterAccountAgeDays: type: integer example: 30 filterLanguage: type: string example: en requiredHashtags: type: array items: type: string example: - '#giveaway' requiredKeywords: type: array items: type: string example: - entered requiredMentions: type: array items: type: string example: - '@elonmusk' example: tweetUrl: https://x.com/elonmusk/status/1234567890 winnerCount: 3 mustRetweet: true responses: '201': description: Draw completed content: application/json: schema: type: object required: - id - tweetId - totalEntries - validEntries - winners properties: id: type: string example: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetId: type: string example: '1234567890' totalEntries: type: integer description: Candidate entries inspected for this draw after the credit-derived cap. This may be lower than the source tweet's full reply count. example: 250 validEntries: type: integer description: Entries from the inspected candidate set that passed all filters. This is not necessarily every valid reply on the source tweet when credits cap inspection. example: 200 winners: type: array items: $ref: '#/components/schemas/Winner' example: [] example: id: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetId: '1234567890' totalEntries: 250 validEntries: 200 winners: [] '400': $ref: '#/components/responses/InvalidInput' '401': $ref: '#/components/responses/Unauthenticated' '402': description: Insufficient usable credits. Draws can fail before execution when the available balance cannot cover the minimum draw cost. A draw can also fail after execution when its final computed cost cannot be deducted. content: application/json: schema: $ref: '#/components/schemas/Error' example: error: insufficient_credits message: Insufficient credits '404': $ref: '#/components/responses/NotFound' '424': $ref: '#/components/responses/XApiError' '429': $ref: '#/components/responses/RateLimitExceeded' '502': $ref: '#/components/responses/XApiError' default: content: application/json: example: error: internal_error message: Unexpected error. Try again. schema: $ref: '#/components/schemas/Error' description: Unexpected error. /api/v1/draws/{id}: get: operationId: getDraw summary: Get draw details tags: - Draws security: - apiKey: [] - oauthBearer: [] parameters: - $ref: '#/components/parameters/DrawId' responses: '200': description: Draw with winners content: application/json: schema: type: object required: - draw - winners properties: draw: $ref: '#/components/schemas/DrawDetail' example: id: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetUrl: https://x.com/elonmusk/status/1234567890 tweetId: '1234567890' tweetText: Giving away 3 Tesla Model 3s! tweetAuthorUsername: elonmusk status: completed totalEntries: 250 validEntries: 200 tweetLikeCount: 50000 tweetRetweetCount: 25000 tweetReplyCount: 10000 tweetQuoteCount: 5000 createdAt: '2025-01-15T12:00:00Z' winners: type: array items: $ref: '#/components/schemas/Winner' example: [] example: draw: id: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetUrl: https://x.com/elonmusk/status/1234567890 tweetId: '1234567890' tweetText: Giving away 3 Tesla Model 3s! tweetAuthorUsername: elonmusk status: completed totalEntries: 250 validEntries: 200 tweetLikeCount: 50000 tweetRetweetCount: 25000 tweetReplyCount: 10000 tweetQuoteCount: 5000 createdAt: '2025-01-15T12:00:00Z' winners: [] '401': $ref: '#/components/responses/Unauthenticated' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimitExceeded' default: content: application/json: example: error: internal_error message: Unexpected error. Try again. schema: $ref: '#/components/schemas/Error' description: Unexpected error. description: Get draw details. /api/v1/draws/{id}/export: get: operationId: exportDraw summary: Export draw data tags: - Draws security: - apiKey: [] - oauthBearer: [] parameters: - $ref: '#/components/parameters/DrawId' - name: format in: query required: true description: Export output format schema: type: string enum: - csv - json - md - md-document - pdf - txt - xlsx - name: type in: query schema: type: string enum: - winners - entries default: winners description: Export winners or all entries responses: '200': description: Exported draw file content: application/octet-stream: schema: type: string format: binary '400': $ref: '#/components/responses/InvalidInput' '401': $ref: '#/components/responses/Unauthenticated' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimitExceeded' default: content: application/json: example: error: internal_error message: Unexpected error. Try again. schema: $ref: '#/components/schemas/Error' description: Unexpected error. description: Export draw data. components: responses: XApiError: description: 'Dependency unavailable, unauthorized, or rate limited. Default v1 returns 502. The best-practice response contract returns 424 for transparent dependency failures. ' content: application/json: schema: $ref: '#/components/schemas/Error' example: error: x_api_unavailable message: X data source temporarily unavailable. Try again later. NotFound: description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: not_found message: Resource not found. InvalidInput: description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' example: error: invalid_input message: Invalid input. Check the request body. Unauthenticated: description: Unauthenticated headers: Cache-Control: description: Prevents storage of authentication responses. schema: type: string const: no-store WWW-Authenticate: description: Bearer authentication challenge. schema: type: string const: Bearer realm="xquik" content: application/json: schema: $ref: '#/components/schemas/Error' example: error: unauthenticated message: Authentication required. Provide a valid API key or bearer token. RateLimitExceeded: description: 'Xquik tier rate limit exceeded. The response includes a `Retry-After` header with the number of seconds to wait before retrying. ' content: application/json: schema: allOf: - $ref: '#/components/schemas/Error' - type: object properties: retryAfter: type: integer example: 60 example: error: rate_limit_exceeded message: Too many requests. Try again later. retryAfter: 60 headers: Retry-After: description: Seconds until the next permitted request. schema: example: 60 minimum: 1 type: integer parameters: Limit: name: limit in: query description: 'Maximum number of items to return (1-100, default 50). For paid per-result endpoints, the returned count may be lower when remaining credits cannot cover the requested page. If zero paid results are affordable, the endpoint returns 402 insufficient_credits. ' schema: type: integer minimum: 1 maximum: 100 default: 50 After: name: cursor in: query schema: type: string description: Cursor for keyset pagination from prior response next_cursor DrawId: name: id in: path required: true schema: type: string example: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 description: Draw public ID returned by create and list draw responses. schemas: DrawDetail: description: Full giveaway draw with tweet metrics, entries, and timing. type: object required: - id - tweetUrl - tweetId - tweetText - tweetAuthorUsername - status - totalEntries - validEntries - tweetLikeCount - tweetRetweetCount - tweetReplyCount - tweetQuoteCount - createdAt properties: id: type: string description: Draw public ID. example: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetUrl: type: string format: uri tweetId: type: string tweetText: type: string tweetAuthorUsername: type: string status: type: string totalEntries: type: integer validEntries: type: integer tweetLikeCount: type: integer tweetRetweetCount: type: integer tweetReplyCount: type: integer tweetQuoteCount: type: integer createdAt: type: string format: date-time drawnAt: type: string format: date-time Winner: description: Giveaway draw winner with position and backup flag. type: object required: - authorUsername - tweetId - position - isBackup properties: authorUsername: type: string tweetId: type: string position: type: integer isBackup: type: boolean DrawListItem: description: Giveaway draw summary with entry counts and status. type: object required: - id - tweetUrl - status - totalEntries - validEntries - createdAt properties: id: type: string description: Draw public ID for detail responses. example: f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345 tweetUrl: type: string format: uri status: type: string totalEntries: type: integer validEntries: type: integer createdAt: type: string format: date-time drawnAt: type: string format: date-time Error: description: 'Error response. Default v1 returns a legacy string error code. Send `xquik-api-contract: 2026-04-29` to receive the structured best-practice error object. ' type: object required: - error properties: error: x-stainless-naming: python: type_name: ErrorValue java: type_name: ErrorValue example: invalid_input oneOf: - type: string title: LegacyErrorCode enum: - internal_error - account_already_connected - account_needs_reauth - account_not_found - account_required - account_restricted - api_key_limit_reached - article_not_found - dm_not_permitted - invalid_format - invalid_id - invalid_input - invalid_params - invalid_tool_type - invalid_tweet_id - invalid_tweet_url - invalid_user_id - invalid_user_ids - invalid_username - invalid_json - insufficient_credits - login_cooldown - login_failed - media_download_failed - missing_params - missing_query - monitor_already_exists - no_media - no_credits - no_subscription - not_found - payment_failed - rate_limit_exceeded - service_unavailable - style_not_found - subscription_inactive - tweet_not_found - unauthenticated - unsupported_field - user_not_found - body_too_large - checkout_unavailable - connection_challenge_expired - connection_challenge_inactive - draft_not_found - favoriters_unavailable - forbidden - guest_wallet_unavailable - guest_wallets_disabled - guest_wallets_unavailable - idempotency_conflict - idempotency_key_conflict - invalid_community_id - invalid_idempotency_key - invalid_list_id - invalid_payment_amount - invalid_range - login_rate_limited - missing_idempotency_key - missing_ids - no_cached_style - passkey_required - rate_limited - read_request_timeout - replies_incomplete - support_media_rate_limit - support_request_rate_limit - too_many_ids - unknown_field - unsupported_media_type - webhook_inactive - write_tracking_unavailable - x_write_unconfirmed - x_account_feature_required - x_account_protected - x_account_suspended - x_api_rate_limited - x_api_unavailable - x_api_unauthorized - x_auth_failure - x_content_too_long - x_daily_limit - x_dm_not_allowed - x_duplicate_action - x_login_auth_failed - x_login_challenge - x_login_denied - x_login_failed - x_login_proxy_error - x_login_rate_limited - x_login_service_unavailable - x_login_suspended - x_rate_limited - x_rejected - x_target_not_found - x_transient_error - x_user_lookup_failed - x_write_ambiguous - x_write_failed example: invalid_input - type: object title: StructuredError required: - message - type - code properties: message: type: string example: Invalid input. Check the request body. type: type: string enum: - api_error - authentication_error - billing_error - dependency_error - invalid_request_error - permission_error - rate_limit_error example: invalid_request_error code: type: string title: ErrorCode enum: - internal_error - account_already_connected - account_needs_reauth - account_not_found - account_required - account_restricted - api_key_limit_reached - article_not_found - dm_not_permitted - invalid_format - invalid_id - invalid_input - invalid_params - invalid_tool_type - invalid_tweet_id - invalid_tweet_url - invalid_user_id - invalid_user_ids - invalid_username - invalid_json - insufficient_credits - login_cooldown - login_failed - media_download_failed - missing_params - missing_query - monitor_already_exists - no_media - no_credits - no_subscription - not_found - payment_failed - rate_limit_exceeded - service_unavailable - style_not_found - subscription_inactive - tweet_not_found - unauthenticated - unsupported_field - user_not_found - body_too_large - checkout_unavailable - connection_challenge_expired - connection_challenge_inactive - draft_not_found - favoriters_unavailable - forbidden - guest_wallet_unavailable - guest_wallets_disabled - guest_wallets_unavailable - idempotency_conflict - idempotency_key_conflict - invalid_community_id - invalid_idempotency_key - invalid_list_id - invalid_payment_amount - invalid_range - login_rate_limited - missing_idempotency_key - missing_ids - no_cached_style - passkey_required - rate_limited - read_request_timeout - replies_incomplete - support_media_rate_limit - support_request_rate_limit - too_many_ids - unknown_field - unsupported_media_type - webhook_inactive - write_tracking_unavailable - x_write_unconfirmed - x_account_feature_required - x_account_protected - x_account_suspended - x_api_rate_limited - x_api_unavailable - x_api_unauthorized - x_auth_failure - x_content_too_long - x_daily_limit - x_dm_not_allowed - x_duplicate_action - x_login_auth_failed - x_login_challenge - x_login_denied - x_login_failed - x_login_proxy_error - x_login_rate_limited - x_login_service_unavailable - x_login_suspended - x_rate_limited - x_rejected - x_target_not_found - x_transient_error - x_user_lookup_failed - x_write_ambiguous - x_write_failed example: invalid_input message: type: string description: Human-readable error guidance. example: Invalid input. Check the request body. reason: type: string description: Machine-readable reason for a login cooldown. example: temporary_issue retryAfter: type: integer minimum: 1 description: Seconds until the next permitted request. example: 60 retryAfterMs: type: integer minimum: 1 description: Required wait in milliseconds. example: 60000 securitySchemes: apiKey: type: apiKey in: header name: x-api-key description: 'Xquik API key passed through the x-api-key header. Xquik-Api-Key is a vendor-prefixed alias. API keys beginning with xq_ can also use Authorization: Bearer.' oauthBearer: type: http scheme: bearer description: 'OAuth 2.1 access token passed through Authorization: Bearer. Values beginning with xq_ remain Xquik API-key credentials, not OAuth tokens.' cookieSession: type: apiKey in: cookie name: __Host-xquik_session description: Secure Xquik browser session cookie. x-service-info: categories: - data docs: homepage: https://xquik.com apiReference: https://docs.xquik.com llms: https://docs.xquik.com/llms.txt x-discovery: ownershipProofs: - dns:xquik.com