jq, Python, a warehouse loader, or a queue worker.
Install
PATH:
Authenticate
--api-key per command or use X_TWITTER_SCRAPER_BEARER_TOKEN for OAuth 2.1 access tokens.
Basic Example
--help at any level:
Workflow: Search Tweets to JSON Lines, CSV, or XLSX
Use this workflow when an analyst, data engineer, or growth operator needs tweets from an X search query in a JSON Lines handoff, analyst CSV file, XLSX workbook, warehouse load, CRM enrichment job, or queue. The CLI command below callsGET /x/tweets/search. It maps the same REST API query parameters to flags: --q, --limit, --cursor, --since-time, --until-time, and --query-type.
.tweets[], .has_next_page, and .next_cursor. Each tweet can include id, text, createdAt, engagement counts, bookmarkCount, isNoteTweet, author, media, quoted_tweet, and retweeted_tweet, depending on what X returns for the result.
Project .tweets[] into xquik-tweet-search.jsonl and xquik-tweet-search.csv rows with tweet_id, author_username, engagement counts, page_index, page_cursor, next_cursor, and has_next_page so scripts can resume safely or load the same records into XLSX, CRM, warehouse, or agent workflows.
--limit as a 1 to 200 upper bound for a bounded pull. When .has_next_page is true, keep the same --q, filters, --query-type, and --limit; only --cursor changes.
Tweet search costs 1 credit per tweet returned. If remaining credits cannot cover a bounded --limit request, the API can return fewer tweets; if 0 paid results are affordable, it returns 402 insufficient_credits. For bounded pulls that return fewer tweets than the requested --limit, pass .next_cursor back as --cursor with the same query, filters, --query-type, and --limit. Use --format-error json so batch jobs can branch on status and code, and retry 429 or temporary 5xx responses with backoff.
For XLSX handoff, keep xquik-tweet-search.jsonl as the source of truth and convert the same projected rows in your pipeline when account managers need a workbook.
Workflow: Follower Export to CSV, JSON, or XLSX
Use this workflow when sales, support, research, or marketing teams need an owned follower list in a CRM import, warehouse load, analyst CSV file, XLSX workbook, or resumable JSON handoff.follower_explorer requires targetUsername. The CLI flag is --target-username.
POST /extractions/estimate and returns allowed, estimatedResults, creditsRequired, creditsAvailable, and source. For follower exports, source is usually followers.
POST /extractions and returns the queued 202 Accepted receipt: id, toolType, and status: "running". Persist follower-run.json, job_id, the source username, and the estimate before polling. Credit reservation happens after the job starts. If available credits changed since the estimate, the run can fetch only the affordable count before export or mark the job failed with insufficient_credits.
.job, .results, .hasMore, and .nextCursor. When .hasMore is true, pass .nextCursor back as --after to fetch the next saved page.
--format json --output xquik-followers.json for app ingestion or --format xlsx --output xquik-followers.xlsx for XLSX handoff. Map User ID or result xUserId as the CRM unique key. Keep xquik-followers.jsonl for queue replay or warehouse loads, xquik-followers.json for app ingestion, xquik-followers.csv for CRM import, and xquik-followers.xlsx for analyst handoff.
Cost: 1 credit per follower extracted or returned. Exports are free after the
extraction job exists.
Workflow: Tweet Replies to CSV, JSON, or XLSX
Use this workflow when moderation, support, giveaway, research, or AI review needs every reply under one tweet as CSV, JSON, XLSX, or JSONL. Estimate, runreply_extractor, poll the stored job, then export the file.
reply_extractor requires targetTweetId. The CLI flag is --target-tweet-id.
POST /extractions/estimate and returns allowed, estimatedResults, creditsRequired, creditsAvailable, and source. For replies, source is usually replyCount.
POST /extractions. Persist job_id before polling so a shell restart, queue retry, or CI rerun can resume the same extraction. Reuse the follower export polling loop above with reply filenames:
GET /extractions/{id} and returns .job, .results, .hasMore, and .nextCursor. Append .results[] to your queue, CRM import, or warehouse load. While .hasMore is true, pass .nextCursor back as --after "$next_cursor".
GET /extractions/{id}/export and writes bytes to --output. Use --format csv, --format json with --output xquik-tweet-replies.json, or --format xlsx with --output xquik-tweet-replies.xlsx. Cost: 1 credit per reply extracted or returned. Exports are free after the extraction job exists.
Workflow: Post Media Tweets, Replies, and DM Attachments
Use this workflow when an operator, support queue, or agent needs to publish a media-backed tweet, reply with media, or send one media attachment in a DM from a connected X account. Tweet and reply media posts use public media URLs directly onx:tweets create. Pass repeated --media flags for up to 4 image URLs, or pass exactly 1 MP4 video URL up to 100 MB. Do not mix video with other media. Do not upload first when you already have public media URLs.
--reply-to-tweet-id flag maps to reply_to_tweet_id, and --media maps to the public URL array on POST /x/tweets.
tweetId, success, charged, and chargedCredits. If the API returns 202 x_write_unconfirmed, store writeActionId, chargedCredits, and poll GET /x/write-actions/{id} before sending another write. Keep one JSON Lines handoff shape for both outcomes:
x:media upload when you need an uploaded media ID for a DM attachment. The CLI upload command accepts a local file through --file; --transform mediaId extracts the upload response ID for scripts.
--media-id flag maps to the REST media_ids body field. DMs accept exactly 1 uploaded media ID. Store messageId from the DM response on the support ticket, CRM record, queue job, or agent memory. Keep DM body text in private systems. Shared logs, public artifacts, queue status, and agent handoffs should store message_id, optional media_id, recipient/account identifiers from your job context, and send status instead of full DM bodies. Uploading media costs 10 credits, and sending the DM costs 10 credits.
Do not pass --reply-to-message-id to x:dm send; the REST endpoint rejects reply_to_message_id. Start a new DM with --user-id, --account, --text, and optional one-item --media-id instead.
Do not pass uploaded mediaId values to x:tweets create; that command uses --media with public media URLs.
Useful Commands
Search tweets or scrape tweets
Run
x-twitter-scraper x:tweets search to return tweet objects, author objects, metrics, media, has_next_page, and next_cursor.Fetch one tweet
Run
x-twitter-scraper x:tweets retrieve to return the full tweet text, author, metrics, media, quoted tweet, and retweeted tweet.Get tweet replies
Run
x-twitter-scraper x:tweets get-replies to return reply tweets plus cursor fields.Export followers
Run
x-twitter-scraper x:users retrieve-followers to return user profiles, follower counts, and cursor fields.Post a tweet or reply
Run
x-twitter-scraper x:tweets create to return tweetId, success, charged, and chargedCredits, or writeActionId when confirmation is pending.Upload media for a DM attachment
Run
x-twitter-scraper x:media upload to return mediaId for one-item DM media_ids and mediaUrl for tweet media URL handoff.Send a direct message
Run
x-twitter-scraper x:dm send to return messageId and success.--format json for scripts, --format yaml for readable operations output, and --transform with GJSON syntax when you only need one field from the response.
Error Handling
The CLI writes API errors to stderr and exits non-zero for failed requests. Use--format-error json when scripts need machine-readable errors.