Install
Authenticate
new XTwitterScraperClient() reads X_TWITTER_SCRAPER_API_KEY, X_TWITTER_SCRAPER_BEARER_TOKEN, and X_TWITTER_SCRAPER_BASE_URL.
Basic Example
Search tweets and write durable JSON Lines handoff rows:Workflow: Search Tweets to JSON Lines, CSV, or XLSX
Use this workflow when a .NET worker, console job, or ASP.NET background service needs tweet search results in a durable handoff format for a queue, data lake, analyst CSV export, XLSX workbook, or CRM enrichment step.client.X.Tweets.Search calls GET /x/tweets/search. Build a TweetSearchParams object with the same query parameters the REST API accepts: Q, Limit, Cursor, SinceTime, UntilTime, and QueryType.
Request Mapping
Q
C# property
Q maps to REST q. Use it for an X search query such as from:username, a keyword, hashtag, or boolean operator query.Limit
C# property
Limit maps to REST limit. Use it as a 1 to 200 upper bound for a bounded pull. If page.HasNextPage is true, keep the same Q, filters, QueryType, and Limit when you continue with page.NextCursor.Cursor
C# property
Cursor maps to REST cursor. Pass the opaque cursor from page.NextCursor to request the next page.SinceTime
C# property
SinceTime maps to REST sinceTime. Use it as the ISO 8601 lower bound for tweet creation time.UntilTime
C# property
UntilTime maps to REST untilTime. Use it as the ISO 8601 upper bound for tweet creation time.QueryType
C# property
QueryType maps to REST queryType. Use QueryType.Latest for chronological search or QueryType.Top for engagement-ranked search.Returned Data & Handoff
client.X.Tweets.Search returns PaginatedTweets. Use page.Tweets for the tweet array, page.HasNextPage to decide whether another page exists, and page.NextCursor as the checkpoint for the next request. For bounded pulls that return fewer tweets than Limit, pass page.NextCursor back as Cursor with the same query, filters, QueryType, and Limit.
Each SearchTweet includes typed properties such as ID, Text, Author, CreatedAt, LikeCount, ReplyCount, RetweetCount, QuoteCount, ViewCount, BookmarkCount, and IsNoteTweet when available. Project page.Tweets into JSON Lines and CSV rows with tweet_id, author_username, engagement counts, page_index, page_cursor, next_cursor, and has_next_page so workers can resume safely or load the same records into XLSX, CRM, warehouse, or agent workflows.
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. The SDK retries connection errors, 408, 409, 429, and 5xx responses 2 times by default. For explicit Limit pulls, resume with the same query, filters, QueryType, and Limit; only Cursor changes.
Workflow: Follower Export to CSV, JSON, or XLSX
Use this workflow when a .NET worker, console job, or ASP.NET background service needs an owned follower list for a CRM import, warehouse load, analyst CSV file, XLSX workbook, or resumable JSON handoff.client.Extractions.EstimateCost and client.Extractions.Run map to the extraction workflow. For follower exports, use ExtractionEstimateCostParamsToolType.FollowerExplorer and ExtractionRunParamsToolType.FollowerExplorer; follower_explorer requires TargetUsername. client.Extractions.Retrieve returns Results, HasMore, and NextCursor for pagination. client.Extractions.ExportResults returns an HttpResponse; read CSV and JSON as strings, and copy XLSX from the response stream.
client.Extractions.Run returns the queued 202 Accepted receipt from POST /extractions: REST id, toolType, and status: "running" as C# job.ID, job.ToolType, and job.Status. Store job.ID immediately, then poll client.Extractions.Retrieve before reading pages or calling client.Extractions.ExportResults. Credit reservation happens after the job starts. If available credits changed since EstimateCost, the run can fetch only the affordable count before export or mark the job failed with insufficient_credits.job.ID, targetUsername, estimate.EstimatedResults, and estimate.Source before polling so a queue retry, Windows service restart, or worker restart can resume the same follower export. Keep page.NextCursor as the checkpoint when you stream followers to JSON Lines, and map exported User ID or row xUserId as the CRM unique key. Use 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. Exports are free after the extraction job exists.
Workflow: Tweet Replies to CSV, JSON, or XLSX
Use this workflow when a .NET worker needs every reply on a public tweet in a durable file for moderation review, customer support triage, analyst export, or a warehouse loader.client.Extractions.EstimateCost and client.Extractions.Run map to the extraction workflow. For tweet replies, use ExtractionEstimateCostParamsToolType.ReplyExtractor and ExtractionRunParamsToolType.ReplyExtractor; reply_extractor requires TargetTweetID. client.Extractions.Retrieve returns Results, HasMore, and NextCursor for pagination. client.Extractions.ExportResults returns an HttpResponse; read CSV and JSON as strings, and copy XLSX from the response stream.
Reuse the follower export loop above. Change only the required target, tool type, and output names:
estimate.Allowed credit branch from the follower export workflow before calling Run. Store job.ID on the queue job, ticket, or warehouse batch before polling so another worker can resume with client.Extractions.Retrieve. Keep page.NextCursor as the checkpoint when you stream replies to JSON Lines. Pass it back as After on the next ExtractionRetrieveParams call.
Repeat the export with new ExtractionExportResultsParams { Format = Format.Json } and File.WriteAllTextAsync("xquik-replies.json", await jsonResponse.ReadAsString()). For XLSX, use new ExtractionExportResultsParams { Format = Format.Xlsx }, File.Create("xquik-replies.xlsx"), and stream-copy the response body. Use xquik-replies.jsonl for queue replay or warehouse loads, xquik-replies.json for app ingestion, xquik-replies.csv for CRM import, and xquik-replies.xlsx for analyst handoff. Cost: 1 credit per reply extracted or returned.
Workflow: Post Media Tweets and DM Attachments
Use this workflow when a .NET worker needs to publish a media tweet, reply with media, or send a direct message with an uploaded local file.client.X.Tweets.Create maps to POST /x/tweets; pass public media URLs through Media. Send up to 4 image URLs or exactly 1 MP4 video URL up to 100 MB, and do not mix video with other media. For replies, set ReplyToTweetID to the parent tweet ID. client.X.Media.Upload maps to POST /x/media; use media.MediaID only for the one-item MediaIds handoff on client.X.Dm.Send.
client.X.Tweets.WithRawResponse.Create when a write worker must branch on the REST 202 x_write_unconfirmed response. Store chargedCredits as charged_credits for both confirmed and pending responses. If the API returns pending confirmation, store writeActionId as write_action_id and poll Get Write Action Status before scheduling follow-up work. Do not retry-send the same write while status is pending. Store confirmed tweet_id values on the CMS, queue job, or agent state, and store dm.MessageID plus media.MediaID on the support ticket or CRM note. Keep DM body text in private systems. Shared logs, public artifacts, queue status, and agent handoffs should store message_id, optional media_id, account, user_id, and send status instead of full DM bodies. Leave the generated ReplyToMessageID property unset even if SDK params expose it; the REST endpoint rejects DM reply threading. Text-only tweet and reply writes cost 10 credits. Tweet media adds 2 credits per started MB across attached files. Uploading media costs 10 credits, and sending the DM costs 10 credits. Do not pass uploaded media.MediaID values to client.X.Tweets.Create; that method uses Media with public media URLs.
Error Handling
The C# SDK throws generated exception types for non-success responses and connection failures.400 Bad Request
Throws
XTwitterScraperBadRequestException.401 Unauthorized
Throws
XTwitterScraperUnauthorizedException.403 Forbidden
Throws
XTwitterScraperForbiddenException.404 Not Found
Throws
XTwitterScraperNotFoundException.422 Validation Error
Throws
XTwitterScraperUnprocessableEntityException.429 Rate Limited
Throws
XTwitterScraperRateLimitException.5xx Server Error
Throws
XTwitterScraper5xxException.Pagination
Paginated responses expose generated fields such asHasNextPage. Pass cursor parameters from the previous response when an endpoint supports cursor pagination.