Key Takeaway: Historical Twitter/X data, including tweets, replies, and engagement metrics dating back to March 2006, can be retrieved through five main methods: X's free Advanced Search UI, the official X API's full-archive search (pay-per-use or legacy Pro), open-source scrapers, pre-collected academic datasets, and dedicated archive APIs. The right choice depends on data volume, budget, and whether you need programmatic access at scale or one-off lookups.
For most production use cases (event analysis, sentiment backtests, brand reputation audits, academic research, OSINT investigations), the working answer in 2026 is a dedicated archive API. The official path has narrowed sharply. X discontinued the free Academic Research track for new applicants in 2023, eliminated fixed-tier plans for new developers in February 2026, and now operates on pay-per-use credits with rates that make large historical collections expensive. The legacy Pro tier at $5,000/month still includes full-archive search but is closed to new signups.
This guide walks through every working method for accessing historical X data in 2026, with runnable code, real cost numbers, and honest tradeoffs. Where it makes sense, I'll show how Sorsa API handles archive search with a single API key, no tweet count limits, and flat-rate monthly pricing instead of per-request credits.
Disclosure: Sorsa API is our product. I've aimed to keep this comparison balanced, but I recommend testing any solution against your own workload before committing to a vendor.
Table of Contents
- Why Historical Twitter Data Is Harder to Get in 2026
- 5 Ways to Access Historical Twitter Data, Compared
- What "Full Archive" Actually Means (and What Is Not Accessible)
- How to Search Historical Tweets with Sorsa API
- Code Example: Search by Date Range (cURL and Python)
- Code Example: High-Engagement Historical Content (JavaScript)
- Code Example: Export Historical Tweets to CSV and Pandas
- Scraping a Full Account Timeline
- Strategies for Large-Scale Historical Collection
- Real-World Use Cases
- Frequently Asked Questions
- Getting Started
Why Historical Twitter Data Is Harder to Get in 2026
Three platform changes between 2023 and 2026 reshaped how researchers and developers access old tweets.
February 2023: free API tier collapsed. What used to be a generous free quota became a write-only stub. The Basic tier appeared at $100/month (later raised to $200), and Pro jumped to $5,000/month with full-archive search bundled in. The cheap-or-free era ended overnight, and most academic and indie projects had to choose between paying or shutting down.
Mid-2023: Academic Research track closed to new applicants. The free track that had powered most of the published research on Twitter discourse since 2021 stopped accepting new applications. Researchers with existing access kept it. Everyone else got nothing.
February 6, 2026: pay-per-use replaced fixed tiers for new developers. X moved to consumption-based pricing similar to AWS. Credits are deducted per request. Reads cost roughly $0.005 per resource, writes $0.015, and pay-per-use accounts are capped at 2 million reads per month. Owned reads (your own data) dropped to $0.001 per resource as of April 20, 2026. Legacy Basic and Pro plans remain available only to existing subscribers. New signups go straight into pay-per-use.
The net effect: a researcher in 2026 trying to backfill three years of tweets on a specific topic now faces either expensive credit consumption on pay-per-use, a $5,000/month plan they cannot sign up for, or an enterprise contract that starts around $42,000/month. For a deeper breakdown of where each tier lands today, see our Twitter API pricing guide and the explainer on why the X API is so expensive.
That pricing reality is why third-party archive APIs and open-source scrapers absorbed most of the displaced volume.
5 Ways to Access Historical Twitter Data, Compared
| Method | Archive depth | Cost (May 2026) | Setup | Data completeness | Best for |
|---|---|---|---|---|---|
| X Advanced Search (web UI) | Back to 2006 | Free | None | Low (no export, manual scrolling, fuzzy on old dates) | Quick spot checks, finding a single old tweet |
| X API full-archive (pay-per-use) | Back to 2006 | ~$0.005+/read, 2M/mo cap | High (developer account, console credits, OAuth) | High, but per-tweet field selection required | Funded teams with low-volume needs |
| X API full-archive (legacy Pro) | Back to 2006 | $5,000/mo (closed to new) | High (existing subscribers only) | High | Existing Pro subscribers |
| Open-source scrapers | Varies; usually shallow | Free (engineering time) | Medium (Python, proxies, breakage management) | Unreliable, frequent outages | Ad-hoc exploration on a budget |
| Academic datasets (TweetSets, DocNow) | Event-specific snapshots | Free | Medium (rehydration of tweet IDs) | Partial (many tweets dehydrated or deleted by collection time) | Specific historical events with pre-built datasets |
| Sorsa API (archive endpoints) | Back to 2006 | Flat $49/$199/$899 per month | Low (API key only) | High, full field set returned by default | Production pipelines, ongoing research, dataset building |
A few notes on the methods, in order of practical relevance.
X Advanced Search
Advanced Search supports since: and until: operators back to 2006 and works in the web UI for free. It is useful for finding a known tweet or sampling a small window. It does not export, does not return structured data, and is unworkable at any scale. Old date ranges often surface noisy results because X's relevance ranking deprioritizes old content.
Official X API full-archive search
The /2/tweets/search/all endpoint provides the same archive depth as Sorsa but with three major frictions in 2026. First, new developers must use pay-per-use credits with no fixed monthly cost predictability. Second, the v2 API returns minimal fields by default (just id and text); you must explicitly request tweet.fields, user.fields, and expansions to get engagement metrics, author profiles, and media. Third, the 2 million read cap on pay-per-use is a hard ceiling that real research budgets hit fast.
Open-source scrapers
The scraper landscape thinned in 2025-2026. snscrape and twint are effectively dead. twscrape has not received meaningful updates in roughly a year. Still active as of mid-2026: Twikit, TweeterPy, and a few maintained forks. Even the active ones inherit the structural problem: they reverse-engineer X's internal endpoints and break whenever X rotates frontend tokens, with no migration path. For deeper comparison, see our Twitter scrapers breakdown and how to scrape Twitter.
Academic datasets
Pre-built archives like DocNow's catalog and university dataset repositories ship tweet IDs (not full tweets) for specific events. You rehydrate the IDs against the API to retrieve current content. The catch: every year that passes since the dataset was built, more tweets are deleted, more accounts are suspended, and more become protected. The 2006-2009 historical dataset published in 2016 retained about 85% of its original tweets at the time. By 2026, that fraction is lower. Hydration also requires API access, which brings you back to the pricing question.
Sorsa API
Flat-rate plans starting at $49/month for 10,000 requests, scaling to $899/month for 500,000 requests. Same archive depth as the official API (March 2006 onward). All fields returned by default, including author profile embedded in every tweet. Read more in the Sorsa pricing overview or compare against the official X API directly.
What "Full Archive" Actually Means (and What Is Not Accessible)
"Full archive" is the most-abused phrase in the X data space. Every provider claims it. None of them, including the official API itself, can return four categories of data. These are platform-level limits, not implementation gaps.
Deleted tweets. Once a tweet is deleted, it is gone from X's search index. No API can recover it. The Wayback Machine occasionally has screenshots of high-traffic profile pages, but that is a snapshot, not the tweet itself.
Tweets from protected accounts. Accounts with "Protect your posts" enabled are excluded from public search and timeline endpoints. The only way to read those tweets is to be an authenticated approved follower.
Historical profile snapshots. Profile data (bio, username, follower count, location) reflects the current state. A tweet from 2014 returned today shows the author's 2026 username and bio, not what they had in 2014. If the user changed their handle three times since posting, you'll see the current one.
Historical engagement snapshots. This one trips up sentiment and influence researchers constantly. A tweet from 2018 retrieved today shows its current like count, not the count it had in 2018. If you need point-in-time engagement, you have to collect it at that point in time. There is no time-machine endpoint anywhere in the X ecosystem.
If your research design depends on point-in-time engagement, plan to ingest tweets through real-time monitoring at the time of posting and store the metrics on your side. The real-time monitoring documentation covers patterns for this.
How to Search Historical Tweets with Sorsa API
Sorsa exposes two endpoints relevant to historical work, depending on whether you're searching by keyword or scraping a specific account's full timeline.
| Endpoint | What it does | Pagination | Page size |
|---|---|---|---|
POST /v3/search-tweets | Keyword search across the full archive with all X search operators including since:, until:, from:, min_faves: | next_cursor | ~20 tweets |
POST /v3/user-tweets | A user's complete posting history in reverse chronological order | next_cursor | ~20 tweets |
Authentication is a single ApiKey header. No OAuth, no callback URLs, no bearer tokens. Every response is flat JSON with the full tweet object including embedded author profile, media entities, and engagement metrics.
A minimal request:
curl -X POST https://api.sorsa.io/v3/search-tweets \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "\"climate change\" since:2015-06-01 until:2015-12-31 lang:en min_faves:10",
"order": "latest"
}'
That returns English tweets matching the phrase "climate change" between June and December 2015, with at least 10 likes, sorted chronologically. Cursor-based pagination handles the rest. The full operator dictionary (from:, to:, filter:, min_retweets:, geocode:, exact phrases, Boolean) is in our Twitter search operators reference.
Code Example: Search by Date Range (cURL and Python)
The most common historical workflow is event analysis: pull every English tweet matching a topic in a defined window. Here is the cURL version for a quick test, and then the same logic in Python with pagination.
cURL one-liner
curl -X POST https://api.sorsa.io/v3/search-tweets \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "SpaceX since:2015-06-01 until:2015-07-01 lang:en",
"order": "latest"
}'
Python with pagination
import requests
import time
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_historical(query, max_pages=10):
"""Search the full tweet archive with automatic pagination."""
all_tweets = []
next_cursor = None
for page in range(max_pages):
body = {"query": query, "order": "latest"}
if next_cursor:
body["next_cursor"] = next_cursor
resp = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
resp.raise_for_status()
data = resp.json()
tweets = data.get("tweets", [])
all_tweets.extend(tweets)
print(f"Page {page + 1}: {len(tweets)} tweets (total: {len(all_tweets)})")
next_cursor = data.get("next_cursor")
if not next_cursor:
break
time.sleep(0.1)
return all_tweets
# Pull SpaceX tweets from June 2015
tweets = search_historical('SpaceX since:2015-06-01 until:2015-07-01 lang:en')
for t in tweets[:5]:
print(f"[{t['created_at']}] @{t['user']['username']}")
print(f" {t['full_text'][:120]}...")
print(f" Likes: {t['likes_count']} | RTs: {t['retweet_count']}\n")
Each tweet object returned includes the full text (no 140-character truncation, no URL replacement), the language code, the conversation ID for thread reconstruction, all six engagement metrics (likes, retweets, replies, quotes, views, bookmarks), media entity URLs, and the complete author profile. You don't need a second call to fetch the user.
For more Python patterns, including auth, retries, and quirks of working against the API at scale, see our Twitter API in Python guide.
Code Example: High-Engagement Historical Content (JavaScript)
For content research and benchmark studies, sorting by popularity matters more than chronology. Combine order: "popular" with min_retweets: and -filter:nativeretweets to surface the original tweets that actually moved the needle in a given period.
const API_KEY = "YOUR_API_KEY";
const URL = "https://api.sorsa.io/v3/search-tweets";
async function searchHistorical(query, maxPages = 10) {
const allTweets = [];
let nextCursor = null;
for (let page = 0; page < maxPages; page++) {
const body = { query, order: "popular" };
if (nextCursor) body.next_cursor = nextCursor;
const resp = await fetch(URL, {
method: "POST",
headers: { "ApiKey": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!resp.ok) throw new Error(`API error: ${resp.status}`);
const data = await resp.json();
const tweets = data.tweets || [];
allTweets.push(...tweets);
console.log(`Page ${page + 1}: ${tweets.length} tweets (total: ${allTweets.length})`);
nextCursor = data.next_cursor;
if (!nextCursor) break;
await new Promise((r) => setTimeout(r, 100));
}
return allTweets;
}
// Find viral Tesla tweets from 2019
(async () => {
const tweets = await searchHistorical(
'Tesla since:2019-01-01 until:2019-12-31 min_retweets:1000 -filter:nativeretweets lang:en'
);
for (const t of tweets.slice(0, 5)) {
console.log(`@${t.user.username}: ${t.full_text.slice(0, 100)}...`);
console.log(` Likes: ${t.likes_count} | Views: ${t.view_count}\n`);
}
})();
The -filter:nativeretweets flag is critical here. Without it, popular searches return the same viral tweet duplicated dozens of times as retweets, burying the original content underneath. Always exclude native retweets when you want to see what people actually wrote.
Code Example: Export Historical Tweets to CSV and Pandas
A complete pipeline for production research: collect historical tweets, write them to CSV, then load directly into Pandas for analysis. This is the script I use as a baseline for most client work.
CSV export
import requests
import time
import csv
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def export_historical_to_csv(query, output_file="historical_tweets.csv", max_pages=50):
fields = [
"tweet_id", "created_at", "full_text", "lang",
"likes", "retweets", "replies", "quotes", "views",
"author_id", "username", "display_name", "followers", "verified",
]
with open(output_file, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=fields)
writer.writeheader()
next_cursor, total = None, 0
for page in range(max_pages):
body = {"query": query, "order": "latest"}
if next_cursor:
body["next_cursor"] = next_cursor
resp = requests.post(URL, headers={"ApiKey": API_KEY, "Content-Type": "application/json"}, json=body)
resp.raise_for_status()
data = resp.json()
for t in data.get("tweets", []):
u = t.get("user", {})
writer.writerow({
"tweet_id": t["id"], "created_at": t["created_at"],
"full_text": t["full_text"], "lang": t.get("lang", ""),
"likes": t.get("likes_count", 0), "retweets": t.get("retweet_count", 0),
"replies": t.get("reply_count", 0), "quotes": t.get("quote_count", 0),
"views": t.get("view_count", 0), "author_id": u.get("id", ""),
"username": u.get("username", ""), "display_name": u.get("display_name", ""),
"followers": u.get("followers_count", 0), "verified": u.get("verified", False),
})
total += 1
next_cursor = data.get("next_cursor")
print(f"Page {page + 1} done. Total: {total} tweets.")
if not next_cursor:
break
time.sleep(0.1)
print(f"\nExport complete: {total} tweets saved to {output_file}")
# Bitcoin tweets from 2020, English, 50+ likes, no retweets
export_historical_to_csv(
query='bitcoin since:2020-01-01 until:2020-12-31 lang:en min_faves:50 -filter:retweets',
output_file="bitcoin_2020.csv",
max_pages=100,
)
Load directly into Pandas
If you'd rather skip the CSV intermediate and work in-memory, the same payload structure loads cleanly into a DataFrame.
import pandas as pd
import requests
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def fetch_to_dataframe(query, max_pages=50):
rows, next_cursor = [], None
for _ in range(max_pages):
body = {"query": query, "order": "latest"}
if next_cursor:
body["next_cursor"] = next_cursor
data = requests.post(URL, headers={"ApiKey": API_KEY}, json=body).json()
for t in data.get("tweets", []):
u = t.get("user", {})
rows.append({
"created_at": pd.to_datetime(t["created_at"]),
"username": u.get("username"),
"followers": u.get("followers_count", 0),
"text": t["full_text"],
"likes": t.get("likes_count", 0),
"retweets": t.get("retweet_count", 0),
"views": t.get("view_count", 0),
"lang": t.get("lang"),
})
next_cursor = data.get("next_cursor")
if not next_cursor:
break
return pd.DataFrame(rows)
df = fetch_to_dataframe('"climate change" since:2020-01-01 until:2020-03-31 lang:en min_faves:25')
df["engagement_rate"] = (df["likes"] + df["retweets"]) / df["followers"].replace(0, 1)
print(df.groupby(df["created_at"].dt.date)["engagement_rate"].mean())
You now have a daily mean engagement rate series ready for plotting, regression, or feeding into a downstream sentiment model. For full sentiment workflows, see our companion guide on Twitter sentiment analysis.
Scraping a Full Account Timeline
If your goal is not keyword-based archive search but the complete posting history of a single account, use the /v3/user-tweets endpoint instead. It walks the timeline from newest to oldest until the cursor returns null, with no equivalent of the 3,200-tweet hard cap that constrains the official API's timeline endpoint.
import requests, time
resp = requests.post(
"https://api.sorsa.io/v3/user-tweets",
headers={"ApiKey": "YOUR_API_KEY", "Content-Type": "application/json"},
json={"link": "https://x.com/naval"},
)
For the complete walkthrough including cost estimation, the 3,200-tweet limit, and a comparison against GUI tools and scrapers, see our dedicated guide on downloading all tweets from a user. The rest of this article focuses on cross-user historical search, which is a different workflow.
Strategies for Large-Scale Historical Collection
A few patterns I rely on for any backfill above a few thousand tweets.
Chunk large date ranges into monthly windows
A single query over a year gives you no control over batch size and no clean resume point if a request fails halfway. Splitting by month lets you parallelize, retry, and audit cleanly.
def generate_monthly_chunks(year):
chunks = []
for month in range(1, 13):
since = f"{year}-{month:02d}-01"
until_month = month + 1 if month < 12 else 1
until_year = year if month < 12 else year + 1
until = f"{until_year}-{until_month:02d}-01"
chunks.append((since, until))
return chunks
for since, until in generate_monthly_chunks(2020):
query = f'"climate change" since:{since} until:{until} lang:en min_faves:10'
export_historical_to_csv(query, output_file=f"climate_{since[:7]}.csv", max_pages=50)
For volatile event windows (an election week, a product launch, a crash), break further into weekly or daily chunks.
Filter retweet noise with -filter:nativeretweets
Historical popular searches return a flood of retweets that bury original content. Always exclude native retweets when researching sentiment, opinions, or content patterns. Use -filter:retweets if you want to also exclude legacy "RT @user:" style retweets.
Combine engagement filters with date ranges
Pair since: / until: with min_faves: or min_retweets: to surface only tweets that gained traction in your window. This dramatically reduces noise and credit consumption compared to grabbing every tweet matching a keyword.
"product launch" since:2022-03-01 until:2022-03-31 min_faves:100 -filter:retweets lang:en
Use language filters for global events
For worldwide topics (FIFA World Cup, COP summit, presidential elections), running separate queries per language gives cleaner per-locale datasets than mixing everything.
"world cup" since:2022-11-20 until:2022-12-19 lang:en min_faves:50
"world cup" since:2022-11-20 until:2022-12-19 lang:es min_faves:50
"world cup" since:2022-11-20 until:2022-12-19 lang:pt min_faves:50
Paginate until the cursor is empty
The loop should terminate only when next_cursor returns null, empty, or absent. Don't stop early based on tweets-per-page counts; some pages legitimately return fewer results without indicating the end. For the full cursor pattern, see pagination in the docs.
Backfill plus real-time, not backfill or real-time
For ongoing research, the strongest pattern is to backfill once across the historical window, then attach a real-time monitor going forward. That way you have both the historical baseline and point-in-time engagement metrics for future tweets. The real-time monitoring guide covers webhook and polling patterns for the forward-looking half.
Real-World Use Cases
A few of the patterns I've seen in client work over the past two years.
Quantitative crypto sentiment backfill. In 2024, I helped a quantitative hedge fund migrate a critical data pipeline off the official X API. Their thesis: build a sentiment-momentum signal from crypto-related tweets, backtest it against five years of price action, then trade it forward. Step one was a backfill of every tweet from a curated list of 400 KOL accounts plus every English tweet matching 30 crypto keywords from 2019 to 2024. On the official X Pro tier, that backfill was projected at roughly $18,000 in API costs (the read cap was the binding constraint, not just the per-call price). We rebuilt the same pipeline against a flat-rate archive API and finished the backfill for under $300 in three days of pagination. The fund has been running the live strategy for 18 months.
Brand reputation timeline reconstruction. A PR firm needed to map mentions of a consumer brand across a three-year window after a viral controversy. Their dashboard relied on a current-month feed; rebuilding the past three years required iterating monthly date chunks across "brandname" OR "@brandname" -filter:retweets, then routing the results into their existing sentiment model. About 240,000 tweets, completed over a weekend, under $50 on a Pro plan.
Academic discourse analysis. A media studies researcher running a longitudinal study on platform discourse had built their entire methodology around the Academic Research track. When the track stopped accepting new applicants, their replacement plan ran the same queries against an archive API and re-validated results against the smaller datasets they had collected during their original access. Total cost for the rebuild: a single Starter plan month.
OSINT investigative work. A journalist tracing a public figure's pre-deletion statements on a specific topic used from:username "keyword" since:YYYY-MM-DD until:YYYY-MM-DD to surface every public post on the topic, then cross-referenced with Wayback Machine snapshots to recover deleted material. The archive API gave them the surviving tweets; Wayback filled in screenshots of what had been removed.
None of these workflows are particularly exotic. They share a pattern: define a date window, combine keywords with engagement and language filters, paginate to exhaustion, write to local storage, then analyze offline.
Frequently Asked Questions
How far back does Twitter/X archive search go?
To March 21, 2006, which is when the first tweet was posted. Both the official X API's full-archive search and Sorsa API's /search-tweets endpoint cover the complete public archive from that date forward. Tweets that have since been deleted or made private by their authors are excluded.
Can I get deleted tweets through any API?
No. Once a tweet is deleted, it is removed from X's search index entirely. No public API can retrieve it. Your only options are external archives that captured the tweet before deletion (Wayback Machine screenshots, third-party monitoring services that ingested the tweet in real time, or news outlets that quoted it). If preserving deletable content matters for your use case, ingest tweets via real-time monitoring as they post and store them on your side.
Is the Twitter Academic Research API still free?
Not for new applicants. X stopped accepting new applications to the Academic Research track in 2023. Researchers who had access before that point retain it for now, but no new academic accounts are being created. The arxiv community has documented this transition in detail. Most academic projects in 2026 either use a remaining Academic seat, work with pre-built datasets like DocNow, or migrate to a third-party archive API.
How much does it cost to search the full Twitter archive in 2026?
Three reference points for May 2026. Official X API on pay-per-use: roughly $0.005 per read, capped at 2 million reads per month, no fixed monthly minimum. A full-archive search request that returns 100 tweets typically charges per tweet plus a search operation cost. Official X API legacy Pro: $5,000/month with full-archive bundled, but closed to new signups since February 2026. Sorsa API: flat plans at $49 (10,000 requests), $199 (100,000 requests), and $899 (500,000 requests) per month, with each request returning up to 20 tweets on search endpoints. For a detailed pricing comparison, see Twitter API pricing 2026.
What's the difference between recent search and full-archive search?
Recent search returns tweets from roughly the last 7 days and is available on most API tiers. Full-archive search returns tweets from March 2006 onward and is the more expensive product on the official API. On Sorsa, both windows are covered by the same /search-tweets endpoint with no tier distinction. Older tweets are queried exactly the same way as newer ones.
Can I retrieve a tweet's engagement metrics from a specific date in the past?
No. Engagement counts (likes, retweets, replies, views, quotes, bookmarks) on any returned tweet reflect the current totals, not the totals on a specific past date. If you need point-in-time engagement, you have to ingest the tweet in real time and store the metrics on your side. The platform does not store historical snapshots of engagement.
Can I download tweets from a private (protected) account?
No. Protected accounts are excluded from public search and timeline results across every public API, including the official X API and every third-party provider. The only way to read those tweets is to be an approved follower with an authenticated session.
How do I search tweets between two specific dates?
Use the since:YYYY-MM-DD and until:YYYY-MM-DD operators in your query. since is inclusive of the start date; until is exclusive of the end date. For example, since:2020-01-01 until:2020-02-01 returns the full month of January 2020. Combine with lang:, min_faves:, and -filter:retweets for cleaner results. The full operator reference is in our Twitter search operators guide.
Getting Started
The fastest way to validate a historical query before writing code is the Sorsa API Playground, which lets you fire requests against /search-tweets and /user-tweets from the browser without authentication. The Search Builder is the same idea but with a visual operator picker, useful if you don't want to memorize syntax.
When you're ready to integrate, grab an API key from the dashboard and follow the quickstart. The Starter plan ($49/month, 10,000 requests) is enough for most one-off backfills, including event analysis, single-topic research over a year window, or a few hundred account audits. If you're migrating off the official X API and need pattern-by-pattern guidance, see the migration guide.
Questions on your specific workload: contacts@sorsa.io or the Discord. I read most of the migration questions personally.
Author: Daniel Kolbassen, data engineer with 12+ years working on Twitter/X data pipelines. Last verified: May 17, 2026.