X API curl Examples for v2: Calls and Prices (2026)
Seven X API curl examples for v2, from the bearer token to List members, each with its path and October 2026 price, plus the 401 fixes and Weir's credits.
Tarun Khatri
Published · Updated · 7 min read
X API curl examples all follow one pattern: a GET to api.x.com/2 with an Authorization: Bearer header that carries your app's token.
This cheat sheet is for developers testing the X (Twitter) API v2 from a terminal. You get each call with its path and price, the same calls on Weir, and the fixes for a 401. We run Weir, so weigh that part knowing it.
Set your token once, then look up a user:
export X_BEARER_TOKEN="paste-your-bearer-token"
curl "https://api.x.com/2/users/by/username/XDevelopers?user.fields=created_at,public_metrics" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
- Get a bearer tokenFrom the Console, or with one curl call.
- Look up a userThen read their posts by numeric id.
- Search or look up postsFields and expansions add data.
- Page with next_tokenSend it back as pagination_token.
- Try the same calls on WeirOne key, 5,000 free credits a month.
X API curl examples: paths and prices
These are the reads people test first, with X's price for each from its pricing page on 22 October 2026:
| Call | Path | X price |
|---|---|---|
| Bearer token | POST /oauth2/token |
Not on the price list |
| User by username | GET /2/users/by/username/{username} |
$0.010 per user |
| User's posts | GET /2/users/{id}/tweets |
$0.005 per post |
| Recent search | GET /2/tweets/search/recent |
$0.005 per post |
| One post | GET /2/tweets/{id} |
$0.005 per post |
| Many posts | GET /2/tweets?ids= |
$0.005 per post |
| List members | GET /2/lists/{id}/members |
$0.010 per user |
X bills each resource it returns, and a post fetched twice in one UTC day is billed once.
List members come back as user objects, and X lists user reads at $0.010 each.
What we ran, and what we didn't. We have no X key, so on 22 October 2026 we sent every call on this page to X without one. Each data call answered 401.
A made-up path got a 404, so the paths are real. A 401 doesn't check parameters, though, so those come from X's docs.
Step 1: Get an X API bearer token with curl
The quickest way is to copy the bearer token from your app in the X Developer Console.
Our guide on how to get an X API key walks through it.
You can also mint one from your API key and secret. This is the call from X's bearer token page:
curl -u "$API_KEY:$API_SECRET_KEY" \
--data 'grant_type=client_credentials' \
'https://api.x.com/oauth2/token'
X's docs say the reply carries your token as access_token.
Sent with no key, X answered 403:
{
"errors": [
{
"code": 99,
"message": "Unable to verify your credentials",
"label": "authenticity_token_error"
}
]
}
Step 2: Look up a user, then read their posts
The user lookup at the top returns the account's numeric id.
X's quickstart shows 2244994945 for @XDevelopers, and the timeline needs that id:
curl "https://api.x.com/2/users/2244994945/tweets?max_results=5&exclude=replies,retweets&tweet.fields=created_at,public_metrics" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
max_resultsruns from 5 to 100 per page on this endpoint.exclude=replies,retweetskeeps the account's own original posts.- The cost: $0.005 per post, so 5 posts are $0.025, after $0.010 for the lookup.
By default a post holds only id, text and edit_history_tweet_ids. The tweet.fields list adds the rest.
Step 3: Search recent posts with fields and expansions
Recent search covers the last 7 days.
Let curl encode the query, because spaces and colons break a raw URL:
curl -G "https://api.x.com/2/tweets/search/recent" \
-H "Authorization: Bearer $X_BEARER_TOKEN" \
--data-urlencode "query=from:XDevelopers -is:retweet" \
-d "max_results=10" \
-d "tweet.fields=created_at,public_metrics" \
-d "expansions=author_id" \
-d "user.fields=username,verified"
-Gturns each-dinto a query parameter, so the request stays a GET.expansions=author_idputs each author inincludes.users, next to the posts.- The cost: $0.005 per post, so a full page of 10 is $0.05.
X's pricing page doesn't say whether users in includes count as user reads. Check your usage in the Console after the first call.
Our Twitter search API guide covers operators and full-archive search.
Step 4: Look up posts by id and read List members
Post lookup takes one id in the path, or up to 100 in ids. List members takes a List's numeric id:
curl "https://api.x.com/2/tweets/2041557036274475228?tweet.fields=created_at,public_metrics" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
curl "https://api.x.com/2/tweets?ids=2041557036274475228,2019881223666233717" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
curl "https://api.x.com/2/lists/4143408/members?max_results=100&user.fields=public_metrics" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
List 4143408 is NASA's, the one our Twitter List API guide looks up.
Members come back up to 100 a page, at $0.010 each.
Step 5: Page through results with next_token
When more results exist, the response's meta holds a next_token. Send it back as pagination_token, and stop when it's missing:
curl "https://api.x.com/2/users/2244994945/tweets?max_results=100&pagination_token=PASTE_NEXT_TOKEN" \
-H "Authorization: Bearer $X_BEARER_TOKEN"
Recent search also takes it as next_token.
Add -i to any call to print the headers, including the x-rate-limit trio explained in our X API rate limits guide.
The same calls on Weir, with credits
Weir is a read-only API for public X data, and it takes the same Authorization: Bearer header with a Weir key. Its credits per call, from our billing code:
| Call | Weir path | Credits |
|---|---|---|
| User | GET /v1/x/users/{user} |
3 |
| User's posts | GET /v1/x/users/{user}/posts |
3 + 1 per post on page one |
| Search | POST /v1/x/search |
1 + 1 per post |
| One post | GET /v1/x/posts/{id} |
2 |
| Many posts | GET /v1/x/posts?ids= |
1 + 1 per post |
| List members | GET /v1/x/lists/{id}/members |
1 + 1 per member |
{user} takes a username or a numeric id, so there's no lookup first. Later timeline pages drop the 2-credit profile charge.
Search takes a JSON body:
curl --request POST \
--url https://api.weirapp.io/v1/x/search \
--header "Authorization: Bearer $WEIR_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"fromUsers":["XDevelopers"],"query":"-filter:nativeretweets","onlyOriginal":true,"limit":1}'
We ran this on 22 October 2026 through Weir's MCP server, which takes the same fields. It returned one post for 2 credits, trimmed here:
{
"id": "2111172163776708859",
"text": "New guide to the 𝕏 Chat API ...",
"createdAt": "2026-10-16T19:07:22.000Z",
"author": { "username": "XDevelopers", "followersCount": 697852 },
"likeCount": 120,
"viewCount": 15167
}
The reply also carried meta.nextCursor, which you send back as cursor until it's null.
Here is what 1,000 posts cost:
Weir's figure assumes search pages of about 20 posts.
Price your own job with the X API cost calculator.
Why does my X API curl call return 401?
- The header is in single quotes.
'Authorization: Bearer $X_BEARER_TOKEN'sends the variable's name as the token, so X answers 401. X's old first-request tutorial, archived in January 2025, quoted it this way. - The variable is empty. Run
echo ${#X_BEARER_TOKEN}. A 0 means the token never reached this shell. - The token was regenerated. X's quickstart lists that as a 401 cause, because the old token stops working.
curl: (3) URL rejected: a raw space in the URL. Our curl 8.9.0 refused to send it, so use-G --data-urlencode.
When not to use Weir
- You need to post, like or DM. Weir is read-only. Use X's API, or X's xurl tool, which handles OAuth for you.
- You need X's own terms or a contract with X.
- You read your own account. X's Owned Reads cost $0.001 per resource.
- Price per post is all that matters. TwitterAPI.io lists $0.15 per 1,000 tweets, and it can post.
Weir reads public data only and isn't licensed by X, so access can change. This isn't legal advice.
FAQ
How do I use a bearer token with curl for the X API?
Send it in one header: -H "Authorization: Bearer $X_BEARER_TOKEN", in double quotes so the shell fills in the variable. Copy the token from your app in the X Developer Console, or mint one with the /oauth2/token call above.
Do old Twitter API curl calls to api.twitter.com still work?
In our test without a key, api.twitter.com still answered the user lookup with a 401, the same as api.x.com, so the old host is live. New code should use api.x.com, the host in X's current docs.
Can I call the X API with curl for free?
Not really. X's pricing page lists pay-per-use credits that you buy first. It offers $20 in credits after your first saved card and first purchase. Weir gives 5,000 free credits a month with no card.
Sources
All checked on 22 October 2026, with docs.x.com read as Markdown:
- X, make your first request and fields: https://docs.x.com/make-your-first-request and https://docs.x.com/x-api/fundamentals/fields
- X, app-only bearer tokens: https://docs.x.com/fundamentals/authentication/oauth-2-0/bearer-tokens
- X API reference: https://docs.x.com/x-api/users/get-user-by-username, https://docs.x.com/x-api/users/get-posts, https://docs.x.com/x-api/posts/search-recent-posts, https://docs.x.com/x-api/posts/get-post-by-id, https://docs.x.com/x-api/posts/get-posts-by-ids and https://docs.x.com/x-api/lists/get-list-members
- X, expansions and pagination: https://docs.x.com/x-api/fundamentals/expansions and https://docs.x.com/x-api/fundamentals/pagination
- X API pricing and usage: https://docs.x.com/x-api/getting-started/pricing and https://docs.x.com/x-api/fundamentals/post-cap
- X, xurl: https://docs.x.com/tools/xurl
- X's old first-request tutorial (Internet Archive copy of 26 January 2025; the live URL now redirects): https://developer.x.com/en/docs/tutorials/step-by-step-guide-to-making-your-first-request-to-the-twitter-api-v2
- TwitterAPI.io: https://twitterapi.io/pricing and https://docs.twitterapi.io/api-reference/endpoint/create_tweet_v2
- Weir: https://docs.weirapp.io/reference/x/searchX, https://docs.weirapp.io/authentication and https://docs.weirapp.io/billing
- Our calls: X's 401s and 403 without a key, and Weir's search_x for @XDevelopers (2 credits)