Solutions · Research
Collecting X (Twitter) data for research
The free academic access to the Twitter API ended in 2023. TwittrAPI is a third-party API for public X data, billed per call: $0.065 to $0.09 per 1,000, prepaid, with a balance that does not expire. This page shows how to build a dataset with it, what it costs and how long it takes.
Before you collect
Terms, ethics and scope
TwittrAPI is not affiliated with X Corp. X's terms restrict automated collection of its content; our article How to scrape Twitter (X) data summarizes them with sources. Whether your project should use the official API or a third-party source is a decision for your institution, not for us.
- Public data only: protected accounts, DMs and deleted tweets are not available.
- Tweets are personal data under GDPR and similar laws, even when public. Ethics boards usually want a data management plan: what you collect, how you pseudonymize authors, how long you keep it, who has access.
- Collect less. The simple format already drops most of X's payload; store
id,createdAt,text,langand the author ID if that is all the analysis needs. - Many venues accept datasets of tweet IDs rather than full text. Check your venue's policy.
Endpoints
Which endpoint for which dataset
Every row is a GET with your key. Paginated endpoints return one page per call and a nextCursor in the simple format.
Tweets matching a query in a time window
/search?category=Latest
One page; since: and until: in the query
What an account posted (recent)
/user/{userId}/tweets, /user/{userId}/tweetsAndReplies
One page
Reply trees
/tweet/{tweetId}
One page of reply threads
Quote networks
/tweet/{tweetId}/quotes
One page
Follower graphs
/user/{userId}/followers, /user/{userId}/followings
One page
Profiles for a list of IDs
/user/users/by/ids
Up to 100 profiles
Handles to IDs
/user/usernames/to/ids
Up to 100 handles
Does this handle still exist?
/user/usernames/status
Up to 500 handles
A community or a curated list
/communities/{communityId}/tweets, /lists/tweets
One page
The right column is what one call returns. Profile timelines end where X stops showing older tweets. For older tweets of one account, search from:username since:… until:… in windows. Every endpoint: reference.
Python
A search window to JSON Lines
With the simple format every page carries nextCursor and hasNextPage, so the loop has a clear end. The SDK's paginate follows the cursor for you and retries 429 and 5xx with backoff.
countis a hint (1 to 100); X decides the real page size.- Cursors are X's and can expire after a while. If a run can be interrupted, store the last cursor with your progress and resume soon.
- Calls that fail with 400, 408, 409 or a 5xx error are refunded; 429 is not charged.
- 01
Pick a query and one day
The search window is the query plus a since: and until: date.
- 02
Page through it with the SDK
Up to 100 tweets per page; the SDK follows the cursor until the last page.
- 03
Write one line per tweet
ID, time, language, author ID and text to a JSON Lines file. Deleted or protected tweets are skipped.
- 04
Count the pages
Pages fetched are the calls you pay for, so every run reports its own cost.
Throughput
Going faster: split the time range
Pagination is sequential: page 2 needs the cursor from page 1. At roughly a second per response, one cursor chain gives about one page per second, however high your rate limit is. Split the range into windows (a day, an hour) and run the windows in parallel.
With the 30 requests/s included after the first top-up, 25 workers stay under the limit. Higher limits up to 1,000 requests/s are monthly add-ons you can book for the month of the crawl and cancel after. Rate limits
Thirty days of one query become thirty independent windows. With 25 workers, 25 cursor chains run at once, and each writes its own file.
Cost
What a dataset costs
Calls = items you need ÷ items per call. The page sizes below are assumptions for illustration; measure yours with a few pages first.
1,000,000 tweets via search
$4.50at Standard
- Assumption
- 20 tweets per page
- Calls
- 50,000
- At Scale
- $3.25
1,000,000 tweets via search
$0.90at Standard
- Assumption
- 100 tweets per page
- Calls
- 10,000
- At Scale
- $0.65
1,000,000 profiles by ID
$0.90at Standard
- Assumption
- 100 per call (batch endpoint)
- Calls
- 10,000
- At Scale
- $0.65
Followers of an account with 500,000 followers
$0.45at Standard
- Assumption
- 100 per page
- Calls
- 5,000
- At Scale
- $0.33
Reply threads of 10,000 tweets
$0.90at Standard
- Assumption
- 1 page each
- Calls
- 10,000
- At Scale
- $0.65
Prices per 1,000 calls: Standard $0.09, Scale $0.065. Refunded calls (400, 408, 409 or a 5xx error) are not in these numbers; empty pages at the end of a window are. Time: 50,000 sequential pages at about one per second is about 14 hours; in 25 parallel windows it is well under an hour.
Budgeting a funded project. Top up once: $100 gets Volume ($0.075 per 1,000) for 30 days, $500 within 30 days gets Scale ($0.065). The balance stays until you use it. Crypto has no surcharge; card top-ups carry a 9 % card fee plus VAT. If your institution needs an invoice, request card payment with invoice in the dashboard; it is enabled after a short review.
Methods
Reproducibility
- Log the exact query, the window, the format and the date of collection with each file. Simple-format responses carry
X-Response-Format: simple, so you can record which format you got. - Simple-format fields are stable: new fields may be added, existing ones are not renamed or removed.
- Search results depend on X's index on the day you ask. Two runs a month apart can differ; record when you collected.
- Keep a raw-format sample if you may need fields the simple format leaves out (cards, polls, edit history, community notes).
FAQ
Research questions
Is there an academic tier?
There is no separate tier. New accounts get $0.10 free credit (about 1,100 calls at Standard), enough to measure page sizes and costs for your own queries before you budget.
Can I get historical tweets from years ago?
Search accepts since: and until:, so you can query past windows. How much X returns for older periods varies; test your window with a few pages first.
Can I share the dataset?
Check your venue's policy and X's terms. Sharing tweet IDs instead of full text is common practice; others can look the tweets up again.
Is it legal to use this for research?
TwittrAPI provides public data and is not affiliated with X Corp. Whether a third-party source fits your project is for your institution's legal and ethics offices to decide; our scraping guide summarizes X's terms with sources.
How do I pay from a grant?
Top up once and spend over time; the balance does not expire. Crypto has no surcharge. If you need an invoice, request card payment with invoice in the dashboard; it is enabled after a short review.
Does it work in Jupyter or R?
Yes. In Jupyter use the Python SDK; the collector recipe in the docs runs there unchanged. From R or any other language it is plain HTTPS: GET with the X-API-KEY header and format=simple in the query string.
Related
Read next
- Pagination and cursors →How cursors work, when they expire/docs/helpful-infos/cursor
- Simple format →Fields, schema and stability/docs/simple-format
- Search reference →Operators, since:/until:, filters/docs/reference/search
- How to scrape Twitter (X) data →Options and X's terms, with sources/blog/how-to-scrape-twitter-x-data
- TwittrAPI vs the official X API →When the official API fits better/compare/official-x-api
- AI agents →LLM coding of tweets with tool calls/use-cases/ai-agents
Measure your dataset before you budget it
Run a few pages of your query with the $0.10 free credit, count the tweets per page, and the cost table above becomes your own.