Endpoint, authentication, response format, and pagination mapping for moving from the official Twitter/X API v2 to Sorsa API v3
This page is a reference for moving an existing integration from the official Twitter/X API v2 to Sorsa API v3. It covers authentication, endpoint mapping, response format changes, pagination, HTTP method differences, search query syntax, error handling, and code examples incurl, Python, and JavaScript.
Sorsa API is read-only. If your integration also writes to X (posts tweets, sends DMs, likes, follows), keep the official API key for the write path and migrate only the read path.
Note: For a narrative migration walkthrough with cost comparisons and step-by-step examples, see Migrating from the Twitter/X API: Complete Developer Guide on the blog.
Overview of changes
| Concern | Official X API v2 | Sorsa API v3 |
|---|---|---|
| Base URL | https://api.x.com/2 | https://api.sorsa.io/v3 |
| Authentication | OAuth 2.0 Bearer / OAuth 1.0a | API key in ApiKey header |
| Field selection | tweet.fields, user.fields, expansions | All fields returned by default |
| Response envelope | data + includes + meta | Flat object, embedded relations |
| Pagination | pagination_token / meta.next_token | next_cursor (top-level) |
| Rate limits | Per-endpoint, per-15-min windows | Universal 20 req/s |
| Error shape | errors[] with type, title, detail | { "message": "..." } |
Authentication
The official API uses OAuth 2.0 Bearer tokens for app-only requests, and OAuth 1.0a User Context for user-scoped requests.ApiKey header. Generate keys in the dashboard.
Endpoint mapping
Users
| Action | Official X API v2 | Sorsa API v3 |
|---|---|---|
| Get user by username | GET /2/users/by/username/:username | GET /info?username=:username |
| Get user by ID | GET /2/users/:id | GET /info?user_id=:id |
| Get multiple users | GET /2/users?ids=... | GET /info-batch?user_ids=...&user_ids=... |
| Get followers | GET /2/users/:id/followers | GET /followers?user_id=:id |
| Get following | GET /2/users/:id/following | GET /follows?user_id=:id |
| Verified followers | Not available | GET /verified-followers?user_id=:id |
| Account “About” metadata | Not available | GET /about?username=:username |
GET /info-batchaccepts up to 100 usernames or IDs per request. Repeat the query parameter:?usernames=a&usernames=b.GET /followersandGET /followsreturn up to 200 fully-hydrated profiles per page, including bio, follower counts, and verification status.
Tweets
| Action | Official X API v2 | Sorsa API v3 |
|---|---|---|
| Get a single tweet | GET /2/tweets/:id | POST /tweet-info body: { "tweet_link": ":id" } |
| Get multiple tweets | GET /2/tweets?ids=... | POST /tweet-info-bulk body: { "tweet_links": [...] } |
| User timeline | GET /2/users/:id/tweets | POST /user-tweets body: { "user_id": ":id" } |
| Quote tweets | GET /2/tweets/:id/quote_tweets | POST /quotes body: { "tweet_link": ":id" } |
| Retweeters | GET /2/tweets/:id/retweeted_by | POST /retweeters body: { "tweet_link": ":id" } |
| Replies (comments) | Not a dedicated endpoint | POST /comments body: { "tweet_link": ":id" } |
| Long-form X Article | Not available | POST /article body: { "tweet_link": ":id" } |
tweet_linkaccepts either a full tweet URL (https://x.com/user/status/123) or just the numeric ID ("123").POST /tweet-info-bulkreturns up to 100 tweets per request. Use it instead of loopingPOST /tweet-infoto reduce request count by up to 100x.POST /user-tweetshas no 3,200-tweet ceiling. Paginate untilnext_cursoris absent to retrieve the full timeline back to the account’s first tweet. See Historical data.
Search
| Action | Official X API v2 | Sorsa API v3 |
|---|---|---|
| Search recent tweets | GET /2/tweets/search/recent?query=... | POST /search-tweets body: { "query": "..." } |
| Search full archive | GET /2/tweets/search/all?query=... | POST /search-tweets (historical included) |
| Search mentions | GET .../search/recent?query=@user | POST /mentions body: { "query": "user" } |
| Search users | Not available in v2 | POST /search-users body: { "query": "..." } |
- Sorsa supports the same Twitter Advanced Search operators on
/search-tweets. Query strings transfer unchanged. See Search operators. POST /mentionsadds filters not available on the official API:min_likes,min_replies,min_retweets,since_date,until_date.
Lists
| Action | Official X API v2 | Sorsa API v3 |
|---|---|---|
| List members | GET /2/lists/:id/members | GET /list-members?list_id=:id |
| List followers | GET /2/lists/:id/followers | GET /list-followers?list_link=:id |
| List tweets | GET /2/lists/:id/tweets | GET /list-tweets?list_id=:id |
Communities
The official X API does not expose Community endpoints. Sorsa-only.| Action | Sorsa API v3 |
|---|---|
| Community members | POST /community-members body: { "community_link": ":id" } |
| Community feed | POST /community-tweets body: { "community_id": ":id", "order": "popular" } |
| Search within a community | POST /community-search-tweets body: { "community_link": ":id", "query": "..." } |
Verification
These check membership-style questions in a single call. The official API has no equivalent; replicating them requires fetching full lists and scanning client-side.| Question | Sorsa API v3 |
|---|---|
| Does user A follow user B? | POST /check-follow |
| Did user X comment on tweet Y? | GET /check-comment?tweet_link=...&username=... |
| Did user X quote or retweet tweet Y? | POST /check-quoted |
| Did user X retweet tweet Y? | POST /check-retweet |
| Is user X in community Y? | POST /check-community-member |
Analytics (Sorsa-only)
| Action | Sorsa API v3 |
|---|---|
| Influence score | GET /score?username=... |
| Score deltas (7d, 30d) | GET /score-changes?username=... |
| Follower breakdown by category | GET /followers-stats?username=... |
| Top 20 followers by score | GET /top-followers?username=... |
| Top 20 following by score | GET /top-following?username=... |
| New followers (7 days) | GET /new-followers-7d?username=... |
| New following (7 days) | GET /new-following-7d?username=... |
Utility
| Action | Sorsa API v3 |
|---|---|
| Username to numeric ID | GET /username-to-id/:handle |
| Numeric ID to username | GET /id-to-username/:id |
| Profile URL to numeric ID | GET /link-to-id?link=... |
| API key usage stats | GET /key-usage-info |
Response format changes
The largest single change in the migration. Official v2 responses are wrapped indata, includes, and meta. Sorsa returns flat objects with author data embedded directly in each tweet.
User profile
Official X API v2 (with field selection):Tweet
Official X API v2 (withexpansions=author_id):
Field mapping
User fields
| Official X API v2 | Sorsa API v3 | Notes |
|---|---|---|
id | id | Same |
username | username | Same |
name | display_name | Renamed |
description | description | Same |
location | location | Same |
verified | verified | Same |
protected | protected | Same |
profile_image_url | profile_image_url | Same |
created_at | created_at | Same |
public_metrics.followers_count | followers_count | Flattened |
public_metrics.following_count | followings_count | Flattened, renamed |
public_metrics.tweet_count | tweets_count | Flattened, renamed |
public_metrics.listed_count | Not available | |
| Not available | favourites_count | Sorsa-only |
| Not available | media_count | Sorsa-only |
| Not available | can_dm | Sorsa-only |
| Not available | bio_urls | Sorsa-only |
| Not available | pinned_tweet_ids | Sorsa-only |
| Not available | profile_background_image_url | Sorsa-only |
| Not available | possibly_sensitive | Sorsa-only |
Tweet fields
| Official X API v2 | Sorsa API v3 | Notes |
|---|---|---|
id | id | Same |
text | full_text | Renamed |
created_at | created_at | Same |
lang | lang | Same |
conversation_id | conversation_id_str | Renamed |
in_reply_to_user_id | in_reply_to_username | Returns handle instead of numeric ID |
public_metrics.like_count | likes_count | Flattened, renamed (note plural) |
public_metrics.retweet_count | retweet_count | Flattened |
public_metrics.reply_count | reply_count | Flattened |
public_metrics.quote_count | quote_count | Flattened |
public_metrics.bookmark_count | bookmark_count | Flattened |
public_metrics.impression_count | view_count | Flattened, renamed |
author_id + includes.users[] | user (full object inline) | Embedded |
Referenced tweets via includes | quoted_status, retweeted_status | Inline objects |
| Not available | is_reply, is_quote_status, is_replies_limited | Sorsa-only booleans |
| Not available | in_reply_to_tweet_id | Sorsa-only |
entities (urls, mentions, hashtags, media) | entities array of { type, link, preview } | Different shape |
Pagination
The official API usespagination_token in query parameters and returns meta.next_token. Sorsa uses a single field, next_cursor, in both directions.
For GET endpoints, pass next_cursor as a query parameter:
next_cursor in the JSON body:
next_cursor at the top level:
next_cursor is missing or null, there are no more pages. See Pagination for details.
HTTP method differences
Some endpoints that areGET on the official API are POST on Sorsa.
| Action | Official API | Sorsa API |
|---|---|---|
| Get a tweet | GET | POST |
| Search tweets | GET | POST |
| User timeline | GET | POST |
| Quote tweets | GET | POST |
| Retweeters | GET | POST |
| Replies (comments) | (no direct equivalent) | POST |
| User profile | GET | GET |
| Followers / following | GET | GET |
| Lists | GET | GET |
POST. Endpoints that take a user identifier or a list ID are GET.
Code migration examples
Get a user profile
Before (Official API):Search tweets
Before:Paginate through all followers
Before:Search query syntax
Sorsa supports the same Advanced Search operators as the official API. Existing query strings transfer unchanged.| Operator | Example |
|---|---|
from: | from:elonmusk |
to: | to:elonmusk |
since: / until: | since:2024-01-01 until:2024-02-01 |
| Hashtag | #bitcoin |
| Exact phrase | "hello world" |
OR | bitcoin OR ethereum |
| Exclusion | -is:retweet |
| Combined | from:elonmusk #bitcoin -is:retweet |
/mentions endpoint additionally supports server-side filters: min_likes, min_replies, min_retweets, since_date, until_date. See Track mentions.
Error handling
The official API returns errors as a structurederrors array:
400, 401, 403, 404, 429, 500. See Error codes.
Rate limit handling: on 429, wait one second and retry. The universal limit is 20 req/s across all endpoints. There are no per-endpoint windows to track. See Rate limits.
A retry wrapper that handles both APIs:
Migration checklist
- Replace
Authorization: Bearer ...withApiKey: .... - Remove OAuth 1.0a signature logic (consumer keys, access tokens, signature generation).
- Update base URL from
https://api.x.com/2tohttps://api.sorsa.io/v3. - Map every endpoint path using the tables above.
- Switch GET to POST for tweet, search, comment, quote, retweeter endpoints.
- Remove
tweet.fields,user.fields,media.fields, andexpansionsparameters. - Update response parsers: remove
data/includes/metaunwrapping. - Rename fields (
name→display_name,text→full_text, etc.). - Flatten metric access (drop the
public_metricswrapper). - Replace
pagination_token/next_tokenwithnext_cursor. - Update error handling for the simplified
{ "message": "..." }format. - Adjust rate-limit logic: 20 req/s universal, no per-endpoint windows.
- Test critical endpoints in the API Playground.
- Monitor quota via
GET /key-usage-info. - Retain the official API key for write operations (posting, DMs) if needed.
Features without an official API equivalent
| Feature | Endpoint |
|---|---|
| Tweet timeline without 3,200-tweet cap | POST /user-tweets |
| Single-call follow check | POST /check-follow |
| Single-call retweet check | POST /check-retweet |
| Single-call comment check | GET /check-comment |
| Single-call quote/retweet check | POST /check-quoted |
| Community membership check | POST /check-community-member |
| Community members and feed | POST /community-members, POST /community-tweets |
| In-community search | POST /community-search-tweets |
| Long-form X Article content | POST /article |
| Verified-only follower filter | GET /verified-followers |
| Account country and username change history | GET /about |
| Influence score | GET /score, GET /score-changes |
| Top followers and following by influence | GET /top-followers, GET /top-following |
| Categorized follower breakdown | GET /followers-stats |