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.

$0.10 free credit after sign-up: run a few pages of your query before you budget.

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, lang and 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.

  • count is 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.
  1. 01

    Pick a query and one day

    The search window is the query plus a since: and until: date.

  2. 02

    Page through it with the SDK

    Up to 100 tweets per page; the SDK follows the cursor until the last page.

  3. 03

    Write one line per tweet

    ID, time, language, author ID and text to a JSON Lines file. Deleted or protected tweets are skipped.

  4. 04

    Count the pages

    Pages fetched are the calls you pay for, so every run reports its own cost.

Python collector

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.

Parallel example

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.

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.