X / Twitter API

X / Twitter User tweets API

Paginated timeline of a user’s tweets with text, media and engagement counts. Paginate with the cursor field.

POST/v1/run/twitter.user_tweets
Uptime
100.00%
30d · 22,227 calls
Requests
22,227
30d · weekly, last 12 wks
Response
1.4s
median · 30d

Try it

Make your first request

requireFieldsarray
Optional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `isPinned` or `nextCursor`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a post that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted.
Open in
Get a free key
Sample response
Free runs return only the first 3 results. Fund a key to get the full response.
{
  "found": true,
  "data": {
    "handle": "nasa",
    "cursor": "DAABCgABF__cursor",
    "hasMore": true,
    "tweets": [
      {
        "id": "1800000000000000000",
        "url": "https://x.com/NASA/status/1800000000000000000",
        "text": "Liftoff! 🚀",
        "likes": 142000,
        "retweets": 21400,
        "replies": 3900,
        "createdAt": "2024-06-09T13:45:00Z"
      }
    ]
  }
}
Response interface
interface TwitterUserTweetsResponse {
  data: {
    nextCursor?: string | null;
    tweets: {
      authorHandle?: string;
      authorId?: string;
      authorImage?: string;
      authorName?: string;
      bookmarks: number;
      conversationId?: string;
      createdUtc: number;
      id: string;
      isPinned: boolean | null;
      isReply?: boolean;
      lang?: string;
      likes: number;
      media?: {
        height?: number;
        type: string;
        url: string;
        videoUrl?: string;
        width?: number;
      }[];
      quotes?: number;
      replies: number;
      retweets: number;
      source?: string;
      text: string;
      url: string;
      views: number;
    }[];
  } | null;
  found: boolean;
  reason?: "not_found";
}

Full parameter and response reference - every field, type, and example for this endpoint.

Reference

Request, response, and price

Last verified 2026-09-20 · uptime and latency measured over 30d
POST /v1/run/twitter.user_tweets
curl -X POST https://api.getanyapi.com/v1/run/twitter.user_tweets \
  -H "Authorization: Bearer $ANYAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"handle":"nasa","cursor":"0"}'
FieldTypeExample value
Request body
handlestring"nasa"Twitter/X handle without the leading @.
cursorstring"0"Opaque pagination cursor from a previous response's nextCursor. Omit for the first page.
limitintegerMaximum number of authored tweets and replies to return in THIS page (1-100). Sources return fewer - most cap at 20 - so read `nextCursor` and pass it back as `cursor` to walk further rather than asking for one large page.
requireFieldsarrayOptional; omit it and routing is unchanged, with the cheapest source serving. Name the output fields this request must be able to return, for example `isPinned` or `nextCursor`, and it is served only by a source that returns every one of them. Fields you do not name are still returned whenever the serving source has them. This can raise your price: when the cheapest source cannot return a named field, a dearer source serves, and you are quoted and charged its price. A named field can still be absent on a post that genuinely lacks it. Naming a combination that no single source returns together is refused as invalid input, with no charge. On a paginated walk it applies to the first page only; later pages stay with the source that page chose, at the price it was quoted.
requireSinglePagebooleanRequire a lane that can return the requested limit in one response.
Response
foundbooleantrue
dataobject
data.handlestring"nasa"
data.cursorstring"DAABCgABF__cursor"
data.hasMorebooleantrue
data.tweetsarray
data.tweets[].idstring"1800000000000000000"
data.tweets[].urlstring"https://x.com/NASA/status/1800000000000000000"
data.tweets[].textstring"Liftoff! 🚀"
data.tweets[].likescan requirenumber142000
data.tweets[].retweetscan requirenumber21400
data.tweets[].repliescan requirenumber3900
data.tweets[].createdAtstring"2024-06-09T13:45:00Z"
Price
Price per requestUSD$0.0005
Price /1k reqUSD$0.50

FAQ

About the X / Twitter User tweets API

The AnyAPI X / Twitter User tweets API returns X / Twitter user tweets data as normalized JSON from one POST call to /v1/run/twitter.user_tweets. Paginated timeline of a user’s tweets with text, media and engagement counts. Paginate with the cursor field. AnyAPI routes each request across 3 sources and falls back automatically when one fails. It costs from $0.50 per 1,000 requests, in US dollars with no subscription and no monthly minimum. Over the last 30 days, 100.0% of X / Twitter user tweets calls through AnyAPI succeeded, with a median response time of 1.4 seconds across 22,227 measured calls.

It costs from $0.50 per 1,000 requests, in US dollars with no subscription and no monthly minimum. You fund one USD wallet, each call draws it down, and a failed request costs $0.

Paginated timeline of a user’s tweets with text, media and engagement counts. Paginate with the cursor field. The response is normalized JSON with the same envelope every AnyAPI endpoint returns, so parsing a second endpoint is a change of URL and nothing else.

Over the last 30 days, 100.0% of X / Twitter user tweets calls through AnyAPI succeeded, with a median response time of 1.4 seconds across 22,227 measured calls. These are AnyAPI's own measurements of traffic through the gateway, recomputed continuously, not a published service-level target.