Published May 17, 2026. Updated September 23, 2026: rewritten around X's current full-archive rules, with backfill cost math, exact since/until semantics, researcher access under the EU DSA, and free routes re-checked. Official X API pay-per-use rates verified September 2026.
Key Takeaway: Nearly every undeleted public tweet since March 2006 is still searchable, but no complete archive can be downloaded. In 2026 the official X API sells full-archive search at $0.005 per post with a 3 million post monthly cap, while third-party APIs, report services, and EU researcher access offer cheaper or narrower routes.
Historical Twitter data is anything older than the 7-day window that X's recent search covers, and nearly all of it is still there: X has indexed every public post since the first one on March 21, 2006. What changed is the cost of getting it out. The official full-archive endpoint bills $0.005 for every post it returns, a month of backfill stops at 3 million posts, and the free routes researchers relied on (the Academic Research track, snscrape, Nitter) are gone.
This guide covers every route that still works in September 2026: what each one costs for a real backfill, the since/until rules that decide whether a date window is complete, what no archive can return, and working code for collecting and exporting old tweets. It is published by Sorsa Editorial, and Sorsa API, a read-only X data API, is one of the routes; where another route fits a job better, the guide says so.
Contents
- Historical Twitter data at a glance
- What you can and cannot get from the X archive
- How to get historical tweets from the official X API
- How much does a historical backfill cost?
- How to search historical tweets with Sorsa API
- How to get one account's full tweet history
- Free and no-code routes to historical tweets
- Historical Twitter data for academic research
- Best practices for large historical collections
- FAQ
- Getting started
Historical Twitter data at a glance
The search-based routes below all query X's own index; archives and datasets are copies made at the time, with their own coverage. They differ in price, effort, and what comes back, as of September 2026:
| Route | How far back | Cost | Best for |
|---|---|---|---|
| X Advanced Search (x.com) | March 2006 | Free with an X login, no export | Finding a few old posts by hand |
| Your own X data archive | Your whole account | Free | Your own posts, DMs, and media |
| Official X API full-archive search | March 2006 | $5.00 per 1,000 posts, capped at 3 million posts a month | First-party data for funded teams |
| Sorsa API | March 2006 | From $0.02 per 1,000 tweets on ID lookups, about $0.10 per 1,000 through search (Pro) | Backfills and research pipelines |
| Scraper services (Apify actors, Bright Data) | Varies by tool | $0.12 to $2.00 per 1,000 records | One-off extractions |
| No-code report services | March 2006 (TrackMyHashtag) | From $50 per report | Marketing reports without code |
| Published tweet-ID datasets | Event windows | Free IDs, rehydration billed per lookup | Replicating published studies |
| EU researcher access (DSA Article 40) | Depends on the request | Free for eligible researchers, rolling out | Research on systemic risks in the EU |
| Open-source scrapers (twscrape) | Varies | Free, needs logged-in X accounts | Short experiments |
The short version:
- A handful of old posts: X Advanced Search with since: and until:, walked through in the guide to searching Twitter by date.
- Your own history: request your X data archive.
- A dataset of any size: an API; the cost comparison below shows where each one wins.
- A marketing report with no code: a report service such as TrackMyHashtag or Keyhole.
- Academic research: EU researcher access if your project qualifies, or research pricing from a third-party API.
What you can and cannot get from the X archive
X's search has covered every public post since 2006 ever since its engineers finished a complete tweet index in November 2014. Every search-based route in this guide queries that same index, so they all share the same blind spots:
- Deleted posts. Deletion removes a post from X, so no API can return it afterward. Only copies made earlier survive, such as Wayback Machine snapshots, cached copies on other sites, or data you stored yourself.
- Protected and suspended accounts. Their posts are excluded from public search and timelines.
- Filtered posts. X filters some posts out of search, mainly spam-like behavior such as duplicate posts, and its counts documentation warns that counts can exceed search results because search applies extra compliance filtering.
- Retweets in keyword search (official API). Since X moved search to a new index on May 4, 2026, keyword queries on the official API no longer return retweets.
- Engagement as it was. Likes, reposts, replies, and views are today's totals, not the numbers on the day of posting. Public view counts began in December 2022, and older posts have none.
- Profiles as they were. A 2014 post comes back with the author's current handle, bio, and follower count. At most, account metadata shows how many times a handle has changed and when it last changed, not the old names.
For point-in-time metrics, the only fix is to record them yourself: backfill the history once, then keep a real-time monitor running so new posts are stored with the numbers they had when collected.
How to get historical tweets from the official X API
Full-archive search (GET /2/tweets/search/all) is open to any pay-per-use developer in 2026; it no longer requires the Academic Research track or a legacy Pro subscription. It reaches back to March 2006, returns up to 500 posts per request, and allows 1 request per second and 300 per 15 minutes. Queries are limited to 1,024 characters, and the time window is set with the start_time and end_time parameters rather than since: and until:; leave them out and you get only the last 30 days. Setup means an X developer account, an app with a bearer token, and prepaid credits.
What it costs, per X's pricing documentation:
- Posts: $0.005 each, so a full 500-post page is $2.50 and 1 million posts is $5,000. Expanding author profiles adds $0.010 per user, and the same post fetched twice in one UTC day is billed once.
- The cap: pay-per-use accounts stop at 3 million post reads per monthly billing cycle. Beyond that, X points you to Enterprise, which X does not price publicly and which was reported in 2023 to start around $42,000 a month.
- Volume checks: the counts endpoint (GET /2/tweets/counts/all) returns post volume per minute, hour, or day back to 2006 for $0.010 per request, covering up to 31 days per request at daily granularity. Sizing five years of a query takes about 60 requests, or $0.60, before you pay for a single post.
- Timelines: GET /2/users/:id/tweets returns only an account's 3,200 most recent posts, so anything older has to come through full-archive search with from:.
At those limits, 1 million posts means 2,000 full pages and about 100 minutes of paging at 300 requests per 15 minutes. A 10 million post backfill exceeds the monthly cap, so it takes four billing cycles or an Enterprise contract. The endpoint-by-endpoint breakdown is in our Twitter API pricing guide.
How much does a historical backfill cost?
For a keyword backfill over a date range, at published list rates in September 2026 and normalized to tweets returned:
| Backfill size | Official X API | Sorsa API | TrackMyHashtag |
|---|---|---|---|
| 100,000 tweets | $500 | $49 (Starter, 5,000 of 10,000 requests) | $449.99 |
| 1 million tweets | $5,000 | $199 (Pro, 50,000 of 100,000 requests) | Custom quote |
| 10 million tweets | $50,000 over four billing cycles, or Enterprise | $899 (Enterprise, all 500,000 requests at full pages) | Custom quote |
Pay-as-you-go APIs cost less than a Sorsa plan at the smaller sizes. TwitterAPI.io lists $0.15 per 1,000 tweets ($15 for 100,000 and $150 for 1 million), and Apify actors that support date-range search list from about $0.12 to $0.40 per 1,000 (a dedicated historical actor lists $2.00). On search alone, at full pages, TwitterAPI.io costs less than the Sorsa plan you would need except between about 1.3 and 2 million tweets a month, where Pro is cheaper, and between about 6 and 10 million, where Enterprise is.
Sorsa figures assume full 20-tweet search pages; a sparse window returns fewer tweets per request, so leave headroom or plan for a custom tier near the top of a plan. Official figures exclude author profiles, which can add up to $10.00 per 1,000 posts. Bright Data sells X records at $1.50 per 1,000 but collects by post URL, profile, or hashtag rather than keyword and date range, so it is left out of the table.
If you already hold tweet IDs, from a published dataset or an earlier pull, rehydrating them is cheaper than searching on a per-request API: the official API still charges $0.005 per post returned, while a per-request batch endpoint returns 100 tweets per request, from $0.02 per 1,000 on Sorsa's Pro plan. For a wider view of providers, see the Twitter API alternatives comparison, and to model your own volumes against the official API, the X API cost calculator.
How to search historical tweets with Sorsa API
Sorsa API covers the public archive back to March 2006 through its regular endpoints. There is no separate archive tier: you authenticate with one ApiKey header and need no X developer account. Three endpoints cover historical work:
| Endpoint | Use it for | Per request |
|---|---|---|
POST /v3/search-tweets | Any date window, keyword, or account, with X search operators | Up to 20 tweets |
POST /v3/user-tweets | Paging back through one account's timeline, newest first | Up to 20 tweets |
POST /v3/tweet-info-bulk | Rehydrating a list of tweet IDs | Up to 100 tweets |
Every tweet comes back with its full text, all six engagement counts, media links, conversation IDs, and the author's profile embedded, so there is no second call for user data.
Since, until, and exact time windows
Date filters live inside the query string. These are the ones that matter for historical work:
| Operator | Example | What it does |
|---|---|---|
since: | since:2020-01-01 | On or after this date (inclusive) |
until: | until:2020-02-01 | Before this date (exclusive) |
since: and until: with a time | since:2020-01-01_12:00:00_UTC | From or before an exact time and time zone |
since_time: and until_time: | since_time:1577836800 | Unix seconds, for hourly or minute-level windows |
since_id: and max_id: | max_id:ID | After a post, or at and before a post, by ID |
within_time: | within_time:2d | A rolling recent window, not for history |
So since:2020-01-01 until:2020-02-01 returns all of January 2020. The most common mistake is until:2015-12-31 for a full year, which silently drops December 31; use until:2016-01-01 instead. X does not document which time zone date-only values use, so when a boundary has to be exact, add a time and zone (since:2020-01-01_00:00:00_UTC until:2020-02-01_00:00:00_UTC) or use since_time: and until_time: with Unix seconds.
Post IDs also help. IDs created since November 4, 2010 encode their creation time (milliseconds since the Unix epoch equal (ID >> 22) + 1288834974657); older IDs are sequential and carry no timestamp, so use created_at for 2006 to 2010. IDs rise over time in both eras, which makes since_id: and max_id: reliable bookmarks for resuming a crawl. The full list is in the Twitter search operators cheat sheet, and the free search query builder writes date-based since: and until: strings for you without an account.
Backfill a date range month by month (Python)
Long ranges belong in monthly windows, or weekly windows for busy events: each window paginates to a clean end, a failure costs one window instead of the whole run, and per-window totals make gaps easy to spot. Set order to "latest" for chronological coverage of everything search returns; the default, "popular", ranks results by engagement. The script below retries rate limits and server errors with backoff, stops if a cursor repeats, and appends each finished window to a JSONL file, so a failed month can be rerun on its own.
import json
import time
from datetime import date, datetime, timezone
import requests
API_KEY = "YOUR_API_KEY"
BASE = "https://api.sorsa.io/v3"
HEADERS = {"ApiKey": API_KEY, "Content-Type": "application/json"}
def post(path, body, max_retries=5):
"""POST with exponential backoff on rate limits and server errors."""
for attempt in range(max_retries + 1):
r = requests.post(f"{BASE}/{path}", headers=HEADERS, json=body, timeout=30)
if r.status_code == 429 or r.status_code >= 500:
time.sleep(2 ** attempt)
continue
r.raise_for_status()
return r.json()
r.raise_for_status()
def month_windows(start, end):
"""Yield (since, until) date strings covering [start, end) one month at a time."""
cur = start
while cur < end:
nxt = date(cur.year + (cur.month == 12), cur.month % 12 + 1, 1)
yield cur.isoformat(), min(nxt, end).isoformat()
cur = nxt
def search_window(query, since, until):
tweets, cursor, seen_cursors = [], None, set()
while True:
body = {"query": f"{query} since:{since} until:{until}", "order": "latest"}
if cursor:
body["next_cursor"] = cursor
data = post("search-tweets", body)
tweets.extend(data.get("tweets", []))
cursor = data.get("next_cursor")
if not cursor or cursor in seen_cursors:
return tweets
seen_cursors.add(cursor)
seen = set()
with open("backfill.jsonl", "a", encoding="utf-8") as out:
for since, until in month_windows(date(2019, 1, 1), date(2020, 1, 1)):
try:
window = search_window('"electric vehicles" lang:en -filter:nativeretweets', since, until)
except requests.RequestException as err:
print(f"{since} to {until}: failed ({err}), rerun this window")
continue
stamp = datetime.now(timezone.utc).isoformat()
new = [t for t in window if t["id"] not in seen]
seen.update(t["id"] for t in new)
for t in new:
out.write(json.dumps({**t, "collected_at": stamp}, ensure_ascii=False) + "\n")
print(f"{since} to {until}: {len(window)} tweets, {len(new)} new")
A year of a topic running 5,000 tweets a month is 60,000 tweets, or about 3,000 requests, which fits inside a Starter month. Retries, async collection, and other patterns are in the Twitter API Python guide.
Rehydrate tweet IDs from a published dataset
Research datasets are usually shared as tweet IDs rather than full tweets. The batch endpoint turns up to 100 IDs into full tweets per request, so a 50,000-ID file takes about 500 requests. Expect to recover only part of an old list, because deleted posts and suspended or protected accounts drop out.
ids = [line.strip() for line in open("tweet_ids.txt") if line.strip()]
hydrated = []
for i in range(0, len(ids), 100):
data = post("tweet-info-bulk", {"tweet_links": ids[i:i + 100]})
hydrated.extend(data.get("tweets", []))
print(f"Recovered {len(hydrated)} of {len(ids)} tweets")
The guide to building a Twitter dataset covers cleaning, labeling, and the redistribution rules for ID datasets.
Export to CSV
The backfill already stamps each row with its collection time, which matters because engagement numbers are only true as of the pull. Loading the JSONL into pandas keeps that column:
import json
import pandas as pd
rows = [json.loads(line) for line in open("backfill.jsonl", encoding="utf-8")]
df = pd.DataFrame([{
"id": t["id"],
"created_at": t["created_at"],
"username": (t.get("user") or {}).get("username"),
"text": t.get("full_text", ""),
"likes": t.get("likes_count", 0),
"retweets": t.get("retweet_count", 0),
"views": t.get("view_count"), # empty for posts older than view counts
"lang": t.get("lang"),
"collected_at": t["collected_at"],
} for t in rows])
df.to_csv("historical_tweets.csv", index=False)
How to get one account's full tweet history
Pulling one account is a different job from searching a topic. X's own timeline endpoint stops at an account's 3,200 most recent posts, so older posts have to come through full-archive search with from:handle, at $0.005 each.
On Sorsa, /user-tweets pages back through an account's timeline newest first, 20 posts per request. For an exact date window, or to make sure nothing is skipped on a very active account, run /search-tweets with from:handle month by month instead. Either way the cost stays small: a 50,000-post account is about 2,500 requests at full pages, which fits in the $49 Starter plan (about $5 worth of a Pro plan's allowance). For your own account, the free X archive download is simpler. The guide to downloading all tweets from a user compares all four methods.
Free and no-code routes to historical tweets
X Advanced Search. Free and reaches back to 2006, but X requires a logged-in account to search, results cannot be exported, and scrolling a long window by hand does not scale. It is the right tool for finding a few specific posts.
Your X data archive. On the web, open Settings and privacy, then Your account, then Download an archive of your data. X says preparing it may take a few days. The file holds your posts, DMs, media, followers, and lists, but only for your own account.
No-code report services. TrackMyHashtag sells historical datasets back to 2006, from $149.99 for 25,000 tweets to $449.99 for 100,000 (about $4.50 to $6.00 per 1,000), delivered as CSV or Excel with a PDF report. Keyhole's one-time historical reports start at $50 depending on volume and arrive within one business day. Tweet Binder offers historical reports too; its PRO service is sold as a single annual plan, priced on request. These suit marketers who want a report, not a data pipeline.
Scraper services. Apify actors that support date-range search list from about $0.12 to $0.40 per 1,000 tweets, and a dedicated historical actor $2.00 per 1,000; quality and upkeep depend on each actor's author. Bright Data sells X records at $1.50 per 1,000 on pay-as-you-go, collected by post URL, profile, or hashtag.
Archives. The Wayback Machine holds snapshots of individual posts and profiles, useful as evidence but not as a dataset. The Internet Archive's Twitter Stream Grab, a roughly 1% sample from 2011 to early 2023, is now access-restricted.
Open-source scrapers. twscrape still works but needs logged-in X accounts and breaks when X changes its front end, and its own documentation warns that X's terms discourage using multiple accounts, so the accounts you run are at risk. snscrape's Twitter module has been broken since mid-2023, twint was archived in March 2023, and GetOldTweets3 stopped working years ago. Nitter and XCancel, which many scripts used to read X without an account, went offline in late August 2026 after cease-and-desist letters from X and, after a brief return, shut down again in mid-September. The breakdown of Twitter scrapers tracks what still runs.
Historical Twitter data for academic research
Researchers lost their main route in 2023, when X closed the free Academic Research track that had allowed 10 million posts a month. Four routes replace it in 2026:
- EU researcher access under the DSA. Article 40 of the Digital Services Act gives vetted researchers access to platform data for studying systemic risks in the EU. The delegated act took effect on October 29, 2025, together with a DSA Data Access Portal through which researchers apply to a Digital Services Coordinator; requests for public data under Article 40(12) go through X's own application form. In December 2025 the European Commission fined X €120 million, partly for failing to give researchers access to public data, and in July 2026 it accepted X's action plan, which promises free access for eligible researchers and faster screening, with about six months to implement.
- Institutional collections. Wharton Research IT's Dataset of Historical Tweets holds a roughly 1% sample from April 2012 to November 2022, open only to Wharton and Annenberg researchers. GW Libraries' TweetSets offers about 806 million tweets as ID exports. The Library of Congress archive of 2006 to 2017 (text only) has been embargoed since the Library's December 2017 update, with no access timetable announced.
- Published ID datasets plus rehydration. Many studies publish tweet IDs. Rehydrating them on the official API costs $0.005 per post returned (up to $5.00 per 1,000 IDs) and counts toward the monthly cap, while a per-request batch endpoint does the same for about $0.02 per 1,000.
- Research pricing from a third-party API. Sorsa offers free or discounted access to verified non-commercial researchers, with full-archive search to 2006 and a data-use letter for ethics review on request; the terms are on the academic research page.
Best practices for large historical collections
- Size the job first. Run X's counts endpoint at $0.010 per request, or pull a one-month sample, before buying a plan.
- Chunk by month, and by week for busy events. Smaller windows paginate to a clean end and can be retried on their own.
- Use chronological order.
"latest"returns matches in time order;"popular"ranks by engagement and suits top-post research, not completeness. - Decide on reposts explicitly.
include:nativeretweetskeeps native retweets,-filter:nativeretweetsremoves them, and-filter:retweetsalso drops old-style RT posts and quote tweets. - Deduplicate by tweet ID across windows and reruns.
- Check every window. A month that returns zero tweets for a busy topic is usually a failed request, not an empty month, so rerun it.
- Store raw JSON with a collection timestamp, since engagement numbers are only true as of the pull.
- Backfill once, then monitor forward instead of re-pulling history.
FAQ
How far back does historical Twitter data go?
To March 21, 2006, the date of the first public tweet. X has indexed every public post since 2006, and both the official full-archive search and third-party search APIs cover that range. Deleted posts, protected accounts, and suspended accounts are excluded, and some filtered posts never appear in search.
Can you get historical tweets from the official X API in 2026?
Yes. Full-archive search is available on pay-per-use at $0.005 per post returned, up to 500 posts per request, back to March 2006. It needs an X developer account and prepaid credits, and pay-per-use accounts are capped at 3 million post reads per month, beyond which X requires an Enterprise contract.
How much does historical Twitter data cost?
On the official API, $5.00 per 1,000 posts before author profiles. Third-party search APIs charge roughly $0.09 to $0.25 per 1,000 tweets depending on provider and plan, and no-code report services charge about $4.50 to $6.00 per 1,000. A 1 million tweet backfill costs $5,000 on the official API and fits inside a $199 monthly plan on Sorsa API.
Is there a free way to get historical tweets?
For small jobs, yes: X Advanced Search is free with a login, and you can download your own account's archive at no cost. For datasets there is no free route that still works reliably. The Academic Research track closed in 2023, open-source scrapers break often, and API trials such as Sorsa's 100 free requests cover testing, not full backfills.
Do GetOldTweets, snscrape, or twint still work?
No. GetOldTweets3 stopped working years ago, snscrape's Twitter module has been broken since mid-2023, and twint was archived in March 2023. twscrape still works but needs logged-in X accounts, and Nitter and XCancel went offline in August and September 2026 after legal action by X.
Can you retrieve deleted tweets?
No. Deleting a post removes it from X, so no official or third-party API can return it afterward. Only copies made before deletion survive, such as Wayback Machine snapshots, cached copies on other sites, or data someone stored at the time.
How do since: and until: work in Twitter search?
since: includes the given date and until: excludes it, so since:2020-01-01 until:2020-02-01 returns all of January 2020. X does not document the time zone of date-only values, so for exact boundaries add a time and zone, such as since:2020-01-01_00:00:00_UTC, or use since_time: and until_time: with Unix timestamps. The official X API v2 does not support these operators and uses start_time and end_time parameters instead.
Is the Twitter Academic Research API still available?
No. X closed the free Academic Research track in 2023. In 2026, researchers use pay-per-use full-archive search, apply for data access under Article 40 of the EU Digital Services Act, work from institutional or published ID datasets, or use research pricing from third-party APIs such as Sorsa's free or discounted academic access.
Getting started
The quickest test is one historical window. Create an account, spend a few of the 100 free requests (no card, no expiry) on a single month of your topic, and check how many tweets it returns before scaling to the full range; the quickstart gets you to a first call in minutes, and the historical data documentation walks through the full workflow.
When the numbers look right, the per-request pricing plans run from $0.02 per 1,000 tweets on batch lookups and about $0.10 per 1,000 through search on Pro, every plan holds 20 requests per second, and you do not need an X developer account or wait in an approval queue.
Reviewed by Keksich, founder of Sorsa, marketer and X API researcher.
This guide draws on primary sources checked in September 2026: X's developer documentation for full-archive search, counts, timelines, pricing, and the May 2026 search index change; the European Commission's announcements on DSA data access; the Library of Congress and Wharton pages on institutional collections; each service's own pricing page for third-party rates; and Sorsa's API documentation. Costs are normalized to tweets returned at list prices on full pages. More on our team is on the about page. Verified September 2026.