Documentation Index
Fetch the complete documentation index at: https://docs.sorsa.io/llms.txt
Use this file to discover all available pages before exploring further.
Moving from the official Twitter/X API to Sorsa API? This guide covers everything you need to know - from authentication and endpoint mapping to response format changes and code examples.
Why Migrate?
The official Twitter/X API (v2) comes with complex OAuth flows, strict rate limits tied to expensive access tiers, and frequent policy changes. Sorsa API provides a simpler alternative:
- Simple API key auth instead of OAuth 1.0a/2.0 flows
- Flat, predictable pricing based on request count
- Richer default responses - no need to specify
expansions or tweet.fields
- Extra features not available in the official API (Sorsa Score, follower category stats, community tools, verification checks)
Quick Comparison
| Feature | Twitter/X API v2 | Sorsa API v3 |
|---|
| Base URL | https://api.x.com/2 | https://api.sorsa.io/v3 |
| Auth | OAuth 1.0a / OAuth 2.0 Bearer | API key via ApiKey header |
| Rate limits | Per-endpoint, per-15-min window | Request-based quota |
| Response format | Nested data + includes + meta | Flat objects, direct fields |
| Field selection | Requires tweet.fields, user.fields, expansions | All fields returned by default |
| Pagination | pagination_token in query params | next_cursor in request body or query |
| Pricing tiers | Free / Basic / Pro / Enterprise | Pay-per-request packages |
Step 1: Authentication
Twitter requires OAuth 2.0 Bearer tokens or OAuth 1.0a for user-context requests. Typical setup:
# OAuth 2.0 App-Only
curl -X GET "https://api.x.com/2/users/by/username/elonmusk" \
-H "Authorization: Bearer AAAA...your_bearer_token"
For user-context endpoints you need a full OAuth 1.0a dance with consumer keys, access tokens, and signature generation.
After (Sorsa API)
A single API key in the ApiKey header. That’s it.
curl -X GET "https://api.sorsa.io/v3/info?username=elonmusk" \
-H "ApiKey: your_api_key"
No token refresh, no OAuth flows, no signature computation.
Get your API key: Log in at api.sorsa.io/overview/keys to create and manage keys.
Step 2: Endpoint Mapping
Users
| Action | Twitter/X API v2 | Sorsa API v3 |
|---|
| Get user profile | 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=... |
| Get followers | GET /2/users/:id/followers | GET /followers?user_id=:id |
| Get following | GET /2/users/:id/following | GET /follows?user_id=:id |
| Account metadata | Not available | GET /about?username=:username |
| Action | Twitter/X API v2 | Sorsa API v3 |
|---|
| Get tweet by ID | GET /2/tweets/:id | POST /tweet-info { "tweet_link": ":id" } |
| Get multiple tweets | GET /2/tweets?ids=... | POST /tweet-info-bulk { "tweet_links": [...] } |
| User timeline | GET /2/users/:id/tweets | POST /user-tweets { "user_id": ":id" } |
| Quote tweets | GET /2/tweets/:id/quote_tweets | POST /quotes { "tweet_link": "..." } |
| Retweeters | GET /2/tweets/:id/retweeted_by | POST /retweets { "tweet_link": "..." } |
| Replies/comments | Not a dedicated endpoint (use search) | POST /comments { "tweet_link": "..." } |
| Article (long-form) | Not available | POST /article { "tweet_link": "..." } |
Search
| Action | Twitter/X API v2 | Sorsa API v3 |
|---|
| Search tweets | GET /2/tweets/search/recent?query=... | POST /search-tweets { "query": "..." } |
| Search users | Not available in v2 Basic | POST /search-users { "query": "..." } |
| Search mentions | Use query=@username in search | POST /mentions { "query": "username" } |
Lists
| Action | Twitter/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 |
ID Conversion (Sorsa-only utilities)
| Action | Sorsa API v3 |
|---|
| Username to ID | GET /username-to-id/:handle |
| ID to username | GET /id-to-username/:id |
| Profile link to ID | GET /link-to-id?link=... |
| Check API quota | GET /key-usage-info |
Verification (Sorsa-only)
These endpoints have no equivalent in the Twitter/X API - you would need to fetch full lists and check manually.
| Action | Sorsa API v3 |
|---|
| Check if user follows account | POST /check-follow |
| Check if user commented on tweet | GET /check-comment |
| Check if user quoted/retweeted | POST /check-quoted |
| Check if user retweeted | POST /check-retweet |
| Check community membership | POST /check-community-member |
Sorsa Score & Analytics (Sorsa-only)
| Action | Sorsa API v3 |
|---|
| Account influence score | GET /score?username=... |
| Score changes (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 (last 7 days) | GET /new-followers-7d?username=... |
| New following (last 7 days) | GET /new-following-7d?username=... |
This is the biggest change you will need to handle in your code. Twitter/X API v2 splits data across data, includes, and meta objects. Sorsa returns everything in a flat structure.
User Profile
Twitter/X API v2:
{
"data": {
"id": "44196397",
"name": "Elon Musk",
"username": "elonmusk",
"public_metrics": {
"followers_count": 100000000,
"following_count": 500,
"tweet_count": 30000,
"listed_count": 12000
},
"verified": false,
"profile_image_url": "https://pbs.twimg.com/..."
}
}
Sorsa API:
{
"id": "44196397",
"display_name": "Elon Musk",
"username": "elonmusk",
"description": "...",
"location": "...",
"followers_count": 100000000,
"followings_count": 500,
"tweets_count": 30000,
"favourites_count": 50000,
"media_count": 1200,
"verified": false,
"protected": false,
"can_dm": true,
"profile_image_url": "https://pbs.twimg.com/...",
"profile_background_image_url": "...",
"bio_urls": ["https://example.com"],
"pinned_tweet_ids": ["17823..."],
"possibly_sensitive": false,
"created_at": "2009-06-02T00:00:00Z"
}
Key differences:
name becomes display_name
- No nested
public_metrics object - counts are top-level fields
following_count becomes followings_count
tweet_count becomes tweets_count
- Additional fields:
can_dm, favourites_count, media_count, bio_urls, pinned_tweet_ids
Twitter/X API v2 (with expansions):
{
"data": {
"id": "1234567890",
"text": "Hello world",
"created_at": "2024-01-15T12:00:00.000Z",
"public_metrics": {
"retweet_count": 100,
"reply_count": 50,
"like_count": 500,
"quote_count": 25,
"bookmark_count": 10,
"impression_count": 50000
},
"author_id": "44196397",
"conversation_id": "1234567890",
"in_reply_to_user_id": "...",
"lang": "en"
},
"includes": {
"users": [
{ "id": "44196397", "name": "Elon Musk", "username": "elonmusk" }
]
}
}
Sorsa API:
{
"id": "1234567890",
"full_text": "Hello world",
"created_at": "2024-01-15T12:00:00.000Z",
"likes_count": 500,
"retweet_count": 100,
"reply_count": 50,
"quote_count": 25,
"bookmark_count": 10,
"view_count": 50000,
"lang": "en",
"is_reply": false,
"is_quote_status": false,
"is_replies_limited": false,
"conversation_id_str": "1234567890",
"in_reply_to_tweet_id": null,
"in_reply_to_username": null,
"user": {
"id": "44196397",
"display_name": "Elon Musk",
"username": "elonmusk",
"followers_count": 100000000
},
"entities": [],
"quoted_status": null,
"retweeted_status": null
}
Key differences:
text becomes full_text
- No nested
public_metrics - counts are top-level
like_count becomes likes_count
impression_count becomes view_count
- Author data is embedded in
user (no separate includes block)
- Quoted and retweeted tweets are nested directly in
quoted_status / retweeted_status
- Boolean flags:
is_reply, is_quote_status, is_replies_limited
in_reply_to_username instead of in_reply_to_user_id
GET /2/users/44196397/followers?max_results=100&pagination_token=abc123
Token is in the meta object of the response:
{
"data": [...],
"meta": {
"next_token": "abc123",
"result_count": 100
}
}
After (Sorsa API)
For GET endpoints, pass cursor as a query parameter:
GET /followers?username=elonmusk&cursor=abc123
For POST endpoints, include next_cursor in the request body:
{
"query": "from:elonmusk",
"next_cursor": "abc123"
}
The cursor is returned at the top level of the response:
{
"tweets": [...],
"next_cursor": "xyz789"
}
When next_cursor is empty or absent, you have reached the last page.
Step 5: Code Migration Examples
Python - Get User Profile
Before:
import requests
BEARER_TOKEN = "AAAA...your_bearer_token"
url = "https://api.x.com/2/users/by/username/elonmusk"
params = {
"user.fields": "description,public_metrics,profile_image_url,verified,created_at"
}
headers = {"Authorization": f"Bearer {BEARER_TOKEN}"}
response = requests.get(url, headers=headers, params=params)
data = response.json()
user = data["data"]
followers = user["public_metrics"]["followers_count"]
name = user["name"]
After:
import requests
API_KEY = "your_api_key"
url = "https://api.sorsa.io/v3/info"
params = {"username": "elonmusk"}
headers = {"ApiKey": API_KEY}
response = requests.get(url, headers=headers, params=params)
user = response.json()
followers = user["followers_count"]
name = user["display_name"]
Before:
url = "https://api.x.com/2/tweets/search/recent"
params = {
"query": "from:elonmusk since:2024-01-01",
"tweet.fields": "created_at,public_metrics,lang",
"expansions": "author_id",
"user.fields": "username,name",
"max_results": 10
}
headers = {"Authorization": f"Bearer {BEARER_TOKEN}"}
response = requests.get(url, headers=headers, params=params)
data = response.json()
tweets = data["data"]
users = {u["id"]: u for u in data.get("includes", {}).get("users", [])}
next_token = data.get("meta", {}).get("next_token")
After:
url = "https://api.sorsa.io/v3/search-tweets"
payload = {
"query": "from:elonmusk since:2024-01-01"
}
headers = {"ApiKey": API_KEY}
response = requests.post(url, headers=headers, json=payload)
data = response.json()
tweets = data["tweets"] # each tweet already includes user data
next_cursor = data.get("next_cursor")
Before:
const tweetId = "1234567890";
const response = await fetch(
`https://api.x.com/2/tweets/${tweetId}?tweet.fields=public_metrics,created_at&expansions=author_id&user.fields=username,name`,
{ headers: { Authorization: `Bearer ${BEARER_TOKEN}` } }
);
const { data, includes } = await response.json();
const likes = data.public_metrics.like_count;
const author = includes.users[0].name;
After:
const response = await fetch("https://api.sorsa.io/v3/tweet-info", {
method: "POST",
headers: {
"ApiKey": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
tweet_link: "https://x.com/elonmusk/status/1234567890",
}),
});
const tweet = await response.json();
const likes = tweet.likes_count;
const author = tweet.user.display_name;
JavaScript - Paginate Through Followers
Before:
let paginationToken = null;
let allFollowers = [];
do {
const params = new URLSearchParams({ max_results: "100" });
if (paginationToken) params.set("pagination_token", paginationToken);
const res = await fetch(
`https://api.x.com/2/users/44196397/followers?${params}`,
{ headers: { Authorization: `Bearer ${BEARER_TOKEN}` } }
);
const json = await res.json();
allFollowers.push(...(json.data || []));
paginationToken = json.meta?.next_token || null;
} while (paginationToken);
After:
let cursor = null;
let allFollowers = [];
do {
const params = new URLSearchParams({ user_id: "44196397" });
if (cursor) params.set("cursor", cursor);
const res = await fetch(
`https://api.sorsa.io/v3/followers?${params}`,
{ headers: { ApiKey: API_KEY } }
);
const json = await res.json();
allFollowers.push(...(json.users || []));
cursor = json.next_cursor || null;
} while (cursor);
Step 6: Field Name Mapping Reference
Use this table to update your data models and parsers.
User Fields
| Twitter/X API v2 | Sorsa API | Notes |
|---|
id | id | Same |
username | username | Same |
name | display_name | Renamed |
description | description | Same |
location | location | 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 |
| - | favourites_count | Sorsa-only |
| - | media_count | Sorsa-only |
verified | verified | Same |
protected | protected | Same |
profile_image_url | profile_image_url | Same |
| - | profile_background_image_url | Sorsa-only |
| - | can_dm | Sorsa-only |
| - | bio_urls | Sorsa-only |
| - | pinned_tweet_ids | Sorsa-only |
| - | possibly_sensitive | Sorsa-only |
created_at | created_at | Same |
| Twitter/X API v2 | Sorsa API | Notes |
|---|
id | id | Same |
text | full_text | Renamed |
created_at | created_at | Same |
public_metrics.like_count | likes_count | Flattened + renamed |
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 |
lang | lang | Same |
conversation_id | conversation_id_str | Renamed |
in_reply_to_user_id | in_reply_to_username | Returns handle instead of ID |
| - | in_reply_to_tweet_id | Sorsa-only |
| - | is_reply | Sorsa-only boolean flag |
| - | is_quote_status | Sorsa-only boolean flag |
| - | is_replies_limited | Sorsa-only boolean flag |
author_id (+ includes.users) | user (embedded object) | Full user object inline |
Referenced tweets via includes | quoted_status, retweeted_status | Nested directly |
entities (urls, mentions, etc.) | entities (type, link, preview) | Different structure |
Step 7: HTTP Method Changes
Some endpoints that are GET in the Twitter/X API are POST in Sorsa. Update your HTTP clients accordingly.
| Endpoint | Twitter/X API | Sorsa API |
|---|
| Get tweet | GET | POST |
| Search tweets | GET | POST |
| User timeline | GET | POST |
| Quote tweets | GET | POST |
| Retweeters | GET | POST |
GET endpoints in Sorsa use query parameters. POST endpoints use JSON request body.
Step 8: Search Query Syntax
Sorsa supports the same Advanced Search syntax as Twitter/X. Your existing search queries will work as-is.
| Operator | Example | Works in Sorsa? |
|---|
from: | from:elonmusk | Yes |
to: | to:elonmusk | Yes |
since: / until: | since:2024-01-01 until:2024-02-01 | Yes |
| Hashtags | #bitcoin | Yes |
| Exact phrase | "hello world" | Yes |
| OR | bitcoin OR ethereum | Yes |
| Exclude | -retweets | Yes |
For the full list of supported operators, see Search Operators.
The Mentions endpoint (POST /mentions) also supports additional filters not available in the official API: min_likes, min_replies, min_retweets, and date range via since_date / until_date.
Step 9: Error Handling
Both APIs return JSON error messages, but the format is different.
Twitter/X API v2:
{
"errors": [
{
"message": "Not Found",
"type": "https://api.x.com/2/problems/resource-not-found",
"title": "Not Found Error",
"detail": "Could not find tweet with id: [123].",
"status": 404
}
]
}
Sorsa API:
{
"message": "Error description"
}
Sorsa uses a simpler format. Error codes are the same across all endpoints: 400 (bad request), 403 (forbidden / invalid API key), 404 (not found), 500 (server error).
Migration Checklist
- [ ] Replace OAuth Bearer / OAuth 1.0a with
ApiKey header
- [ ] Update base URL from
https://api.x.com/2 to https://api.sorsa.io/v3
- [ ] Change endpoint paths (see mapping tables above)
- [ ] Switch GET to POST where required (tweets, search, communities)
- [ ] Remove
tweet.fields, user.fields, and expansions params (Sorsa returns all fields)
- [ ] Update response parsing: remove
data / includes / meta unwrapping
- [ ] Rename fields in your data models (
name to display_name, text to full_text, etc.)
- [ ] Flatten metric access (remove
public_metrics nesting)
- [ ] Update pagination: replace
pagination_token / next_token with cursor / next_cursor
- [ ] Update error handling for the simplified error format
- [ ] Test with the API Playground before deploying
- [ ] Monitor your quota with
GET /key-usage-info
Features Only Available in Sorsa
These have no equivalent in the official Twitter/X API:
| Feature | Endpoint | Description |
|---|
| Sorsa Score | GET /score | Influence score based on who follows the account |
| Score Trends | GET /score-changes | Weekly and monthly score deltas |
| Follower Categories | GET /followers-stats | Breakdown by influencers, projects, VCs |
| Top Followers | GET /top-followers | Top 20 followers ranked by influence |
| New Followers (7d) | GET /new-followers-7d | Recent follower gains |
| Verification Checks | POST /check-follow, etc. | Instant follow/comment/retweet verification |
| Community Tools | POST /community-tweets, etc. | Community feeds, members, search |
| Verified Followers | GET /verified-followers | Filter for verified followers only |
| Account About | GET /about | Country, username change history |
| Article Data | POST /article | Full text of long-form X articles |
Resources