Fetch a user's posts
Fetch a public X account's recent posts, newest first. Returns the account profile plus full-metadata posts, deduplicated across pages.
GET /v1/x/user/{handle}
Path parameter
| Parameter | Type | Description |
|---|---|---|
handle | string | Required. An X handle (e.g. nasa or @nasa) or a profile URL (e.g. https://x.com/nasa). |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
max_pages | integer | 1 | Pages to fetch (max 15). Each page ≈ 20 posts, newest first. To continue past the last page, send another request with the returned next_cursor. Billed per page. |
cursor | string | — | Resume token from a previous response's next_cursor. Continues the timeline exactly where the last request stopped. |
Example
curl -G "$LISTENX_BASE/v1/x/user/nasa" \
-H "X-API-Key: $LISTENX_KEY" \
--data-urlencode 'max_pages=2'
Response
{
"handle": "nasa",
"profile": {
"id": "11348282",
"screen_name": "NASA",
"name": "NASA",
"description": "Explore the universe …",
"verified": true,
"followers": 79000000,
"following": 180,
"tweets": 70000,
"protected": false
},
"pages_requested": 2,
"pages_fetched": 2,
"returned": 38,
"next_cursor": "DAABCgAB...",
"fetched_at": "2026-10-30T12:00:00+00:00",
"results": [
{
"id": "1234567890123456789",
"created_at": "Mon Oct 27 10:00:00 +0000 2025",
"text": "We're going back to the Moon. …",
"type": "post",
"url": "https://x.com/NASA/status/1234567890123456789",
"metrics": { "replies": 320, "retweets": 1500, "likes": 22000, "quotes": 140, "bookmarks": 980, "views": 1800000 },
"media": [],
"author": { "id": "11348282", "screen_name": "NASA", "name": "NASA" }
}
],
"billing": { "endpoint": "x.user_timeline", "units": 2, "unit_price": "0.010000", "amount": "0.020000", "balance_after": "96.97", "request_id": "…" }
}
Fields
| Field | Description |
|---|---|
handle | The resolved account handle. |
profile | The account: name, bio, follower/following/post counts, verification. |
pages_fetched | Pages actually fetched (also the billed unit count). |
returned | Number of posts in results (deduplicated across pages). |
next_cursor | Pass as cursor on a follow-up request to continue the timeline; null once exhausted. |
fetched_at | UTC timestamp when the result set was captured (metrics are a snapshot from that moment). |
results[] | Posts, newest first — same shape as the post endpoint. |
Billing
Billed per page fetched — units = pages_fetched, minimum 1. See
Billing.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_handle | No valid handle could be parsed from the input. |
404 | not_found | The account does not exist or is suspended. |
Protected (private) accounts return their profile but no posts. See Errors.