Twitter API v1.1 to v2 Migration: Endpoint Map (2026)
A Twitter API v1.1 to v2 migration map from X's own docs: each common endpoint's v2 path, dated deprecations, the switch to next_token, and v2 read prices.
Tarun Khatri
Published · Updated · 7 min read
Twitter API v1.1 to v2 migration means moving each /1.1/ call to its /2/ path, then fixing auth, paging and field names.
This guide is for developers whose X (Twitter) code still calls v1.1. You get X's own endpoint map, with dates, and the gaps in X's docs. We run Weir, the read-only API near the end, so weigh that section knowing it.
Here is statuses/show in v2, from X's docs:
curl "https://api.x.com/2/tweets/1228393702244134912?tweet.fields=created_at,public_metrics&expansions=author_id&user.fields=username" \
-H "Authorization: Bearer $BEARER_TOKEN"
- Map each endpointSwap the /1.1/ path for its /2/ twin.
- Move authUse keys from an app inside a Project.
- Fix paging and fieldsSend next_token back; ask for fields and expansions.
- Budget readsPrice every post and user you fetch.
Step 1: Map v1.1 vs v2 endpoints
X's endpoint map now stops after its Posts rows, so the rest comes from X's per-endpoint migration guides:
| v1.1 endpoint | X API v2 | What changes |
|---|---|---|
search/tweets |
/2/tweets/search/recent |
Still 7 days back |
statuses/show, statuses/lookup |
/2/tweets/:id, /2/tweets?ids= |
Still 100 ids per call |
statuses/user_timeline |
/2/users/:id/tweets |
100 per page, not 200 |
users/show, users/lookup |
/2/users/:id, /2/users |
Still 100 users per call |
followers/list, followers/ids |
/2/users/:id/followers |
1,000 users per page |
friends/list, friends/ids |
/2/users/:id/following |
Same as followers |
lists/show, lists/statuses |
/2/lists/:id, /2/lists/:id/tweets |
Same data, v2 format |
lists/members, lists/memberships |
/2/lists/:id/members, /2/users/:id/list_memberships |
Memberships move under users |
The biggest code change is the id. v1.1 timelines and follower lists took a screen_name, but v2 wants the numeric user id in the path.
So look each account up once with /2/users/by/username/:username, then cache the id.
Step 2: Move auth to an app inside a Project
Three auth changes, from X's migration guides:
- v2 needs a Project. X says v2 calls must use keys from a developer app "associated with a Project."
- App-only works in more places. X lists only OAuth 1.0a user context for v1.1 post lookups.
/2/tweetsalso takes an app-only bearer token. - User context is for acting as a user, or for private metrics. Public reads need only the bearer token.
Already hold OAuth 1.0a user tokens? Since 21 September 2026, X lets you swap each one for an OAuth 2.0 token at POST /2/oauth2/token. X's changelog says the user sees no new consent screen.
Step 3: Swap cursor and max_id for next_token
v1.1 had three ways to page, and v2 has one. Here are the response keys and fields most code reads:
| What you read | v1.1 | X API v2 |
|---|---|---|
| Post list | statuses |
data |
| Next search page | search_metadata.next_results |
meta.next_token |
| Next follower page | next_cursor, sent as cursor |
meta.next_token, sent as pagination_token |
| Older timeline posts | max_id |
pagination_token or until_id |
| Search by date | until, whole days |
start_time, end_time, to the second |
| Author name | user.screen_name |
username in includes.users |
| Likes | favorite_count |
public_metrics.like_count |
v2 also sends little by default. A post comes back with only id, text and edit_history_tweet_ids until you add tweet.fields and expansions.
Our tweet JSON example maps every other field. Our X API pagination guide has a tested next_token loop.
Step 4: Budget for pay-per-use reads
On v2, you pay for every resource a call returns. X's pricing page lists these rates, as of October 2026:
A v1.1 script that walked 10,000 followers now costs $100 in follower reads.
Each username-to-id lookup from Step 1 is a user read too. X bills the same post or user only once per UTC day, so caching ids pays off.
Our X API pricing guide has every rate, and the X API rate limits guide has the per-endpoint windows.
If your first v2 call fails
X's error reference explains three failures you may meet first:
- A 403 with type
client-forbiddenmeans "App not enrolled or lacks required access." Check that it sits in a Project. - A 200 with an
errorsarray is a partial success. Batch lookups return what they found, plus one error per missing id. - A 429 that won't clear may be type
usage-capped: the monthly cap, not a rate limit.
The Twitter API v1.1 to v2 migration in 2026: what still works
X's versioning page lists v1.1 as "Legacy" with "limited support, minimal updates." Its migration overview says X intends to deprecate v1.1 "eventually."
X's About page says three kinds of v1.1 endpoints are "still available":
- Some media upload endpoints. v2 has had its own media upload since 16 January 2025.
- Legacy streaming, which X marks as deprecated.
- "Some specialized endpoints," which the page doesn't name.
X's changelog dates these v1.1 changes:
- 18 June 2021:
GET help/configurationwas retired. - 23 November 2021: the retirement date X announced for the v1.1 oEmbed endpoint.
- 14 March 2023:
statuses/filterwas deprecated in favor of v2's filtered stream. - 28 September 2023:
search/tweets,users/searchandgeo/searchwere deprecated.
What X's docs don't say about v1.1
We searched docs.x.com on 22 October 2026 and couldn't find these:
- A shutdown date for any read endpoint in the Step 1 table.
- A full list of v1.1 endpoints that still answer. The About page says only "some."
- Whether v1.1 calls are billed under pay-per-use.
- The Users and Lists rows of the endpoint map, which now stops after Posts.
- Current rate limits in the migration guides. Their numbers differ from the rate limits page, so trust that page.
Read-only code? Skip v2 and use Weir
If your v1.1 code only reads public posts and profiles, a REST API can stand in for v2. Weir takes one API key in a Bearer header: no OAuth, no Project, no user tokens.
Its timeline and follower calls take a username where v2 wants a numeric id. The same calls, from Weir's API reference:
search/tweets POST /v1/x/search
statuses/show GET /v1/x/posts/{id}
statuses/lookup GET /v1/x/posts?ids={ids}
statuses/user_timeline GET /v1/x/users/{user}/posts
users/show GET /v1/x/users/{user}
users/lookup GET /v1/x/users?ids={ids}
followers/list GET /v1/x/users/{user}/followers
friends/list GET /v1/x/users/{user}/following
lists/show, statuses, members GET /v1/x/lists/{id}, /posts, /members
Every list pages the same way: send meta.nextCursor back as cursor until it is null. Each post carries its author as author.username, so there is no includes step.
Here is a v1.1 user_timeline loop that paged with max_id, rewritten for Weir:
import os, requests
API = os.environ.get("WEIR_API_URL", "https://api.weirapp.io")
HEAD = {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"}
def user_timeline(user, max_pages=5):
params = {"limit": 20}
for _ in range(max_pages):
r = requests.get(f"{API}/v1/x/users/{user}/posts", params=params, headers=HEAD, timeout=60)
r.raise_for_status() # a 402 means out of credits: stop, don't retry
page = r.json()
yield from page["data"]
if page["meta"]["nextCursor"] is None: # the only stop
return
params["cursor"] = page["meta"]["nextCursor"]
We tested it on 22 October 2026 against a local stub that serves Weir's response shape. It read two pages, saw a null cursor and stopped.
A page costs 1 credit plus 1 per post, and the first page adds 2 for the profile. So 1,000 posts cost about 1,050 credits:
When not to use Weir
- You post, like, follow or send DMs. Weir only reads, so writes need v2.
- You call
lists/membershipsorlists/ownerships. Weir has no twin for them, and its batch user lookup takes ids, not usernames. - You need a contract with X itself, or Enterprise volume above the 3 million cap.
- Price per post is all that matters. TwitterAPI.io lists $0.15 per 1,000 tweets, below Weir's packs.
Weir isn't licensed by X, so access can change.
FAQ
Is Twitter API v1.1 deprecated?
Partly. X's docs call v1.1 "Legacy," and its changelog deprecated search/tweets on 28 September 2023. X gives no shutdown date for the other read endpoints, but plans to deprecate v1.1 eventually.
How do I migrate Twitter API v1.1 to v2?
Swap each /1.1/ path for its /2/ twin, using keys from an app inside a Project. Page with next_token instead of cursor or max_id. Add tweet.fields and expansions to get more than the id and text.
What replaced statuses/user_timeline in v2?
GET /2/users/:id/tweets. It takes the numeric user id, not a screen name, and returns up to 100 posts per page. Like v1.1, it reaches back 3,200 posts, says X's migration guide.
Can I still use Twitter API v1.1 for media upload?
Partly. X's About page says some v1.1 media upload endpoints still work, with no cutoff date. v2 has had its own media upload since 16 January 2025, so new code should use it.
Sources
All checked on 22 October 2026, read as Markdown by adding .md to each URL:
- X versioning and About pages: https://docs.x.com/x-api/fundamentals/versioning and https://docs.x.com/x-api/getting-started/about-x-api
- X migration overview and endpoint map: https://docs.x.com/x-api/migrate/overview and https://docs.x.com/x-api/migrate/x-api-endpoint-map
- X migration guides: https://docs.x.com/x-api/posts/search/migrate/overview, https://docs.x.com/x-api/posts/lookup/migrate/overview, https://docs.x.com/x-api/posts/timelines/migrate/overview, https://docs.x.com/x-api/users/lookup/migrate/overview, https://docs.x.com/x-api/users/follows/migrate/overview and https://docs.x.com/x-api/lists/list-lookup/migrate/overview, with the list-tweets and list-members pages beside it
- X reference: https://docs.x.com/x-api/posts/lookup/quickstart and https://docs.x.com/x-api/users/get-user-by-username
- X changelog, 2021 to September 2026: https://docs.x.com/changelog
- X pricing, rate limits and errors: https://docs.x.com/x-api/getting-started/pricing, https://docs.x.com/x-api/fundamentals/rate-limits and https://docs.x.com/x-api/fundamentals/response-codes-and-errors
- TwitterAPI.io pricing: https://twitterapi.io/pricing
- Weir docs: https://docs.weirapp.io/authentication, https://docs.weirapp.io/pagination and https://docs.weirapp.io/billing
- Our stub test of the Weir timeline loop, 22 October 2026