# X (Twitter)

Canonical: https://monsterapi.co/docs/twitter

The X API returns public account, post, conversation, community, list, trend and audio space information.
The public API includes 18 endpoints. Nine other endpoints are unavailable; see [Unavailable endpoints](#unavailable-endpoints).

The paths below follow `https://api.monsterapi.co/twitter/api`.

<span id="shape-of-an-answer" />
<span id="empty-values" />

## Response fields

Most responses contain `data` with X’s field names and named fields for the main information, such as `user`, `tweet` or `posts`.
Each endpoint below lists its response fields. Responses with named fields alone omit `data`; `/oembed` returns `data` alone.

The `other` list carries additional public account, post, community and timeline information under X’s field names.
Existing entries without a public post come first, followed by additional object details.
Those details include supplied account metadata and attachment variants and can repeat named field values.

Named fields preserve returned empty strings, lists and objects: `""`, `[]` and `{}`.
A missing value, explicit `null` or incompatible value gives `null`.
An object whose named fields are all `null` is itself `null`; an empty value keeps the object present.
Numeric fields require numbers: an empty string gives `null`, not zero.
Identifiers are strings; keep every digit unchanged.

## Account profiles

`GET /user/{name}` returns `{data, user}` with identity, biography, images, verification and counts.
`name` is required: 1 to 15 ASCII letters, digits or underscores, without `@`.

Use `user.id` from this response as `rest_id` in the [account post endpoints](#account-posts).
The identifier stays the same when the account changes its handle; `user.screen_name` is the current handle.

## Account posts

These endpoints overlap in post information and differ in response fields and pagination.

<div className="w-full max-w-full overflow-x-auto" role="region" aria-label="X account post endpoints" tabIndex={0}>

| Method and path                               | Returned information                                                             | Response fields                            | Continuation               |
| --------------------------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------ | -------------------------- |
| `GET /user/id/{rest_id}/tweets`               | Posts and reposts, newest first                                                  | `data`, `posts`, optional `next_cursor`    | `cursor`, optional `limit` |
| `GET /user/id/{rest_id}/highlights`           | Posts selected for the account’s highlights                                      | `data`, `posts`, optional `next_cursor`    | `cursor`, optional `limit` |
| `GET /user/{name}/timeline/render`            | Account profile and original post preview, with a pinned post first when present | `user`, `posts`, `other`                   | None                       |
| `GET /user/id/{rest_id}/timeline/syndication` | Account identity and post preview                                                | `user_id`, `screen_name`, `posts`, `other` | None                       |

</div>

`rest_id` is required: take `user.id` from [`GET /user/{name}`](#account-profiles).
Use decimal digits from `1` to `9223372036854775807`, without a leading zero.
The handle in `GET /user/{name}/timeline/render` uses the format described under [Account profiles](#account-profiles).

Post previews have no cursor. Their `other` field contains additional entries and object details.
Text on `GET /user/id/{rest_id}/timeline/syndication` may be shortened near 280 characters.
Paginated posts include `pinned`, `bookmark_count`, `view_count`, `edit_tweet_ids` and author professional information where supplied.
See [Pagination](#pagination) for continuation rules.

An empty profile and post preview returns `404` `not_found`.
An empty account post preview by numeric identifier returns `500` `upstream_shape`; it does not establish an empty account or missing posts.
Use `GET /user/id/{rest_id}/tweets` for a paginated list.

<span id="a-post-and-its-conversation" />

## Posts and conversations

| Method and path               | Returned information                                                    | Response fields                                 |
| ----------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------- |
| `GET /tweet/{id}`             | Post details with full text, author, attachments, references and counts | `data`, `tweet`                                 |
| `GET /tweet/{id}/syndication` | Post summary with text, author, attachments and available counts        | `data`, `tweet`                                 |
| `GET /tweet/{id}/render`      | Post, preceding conversation posts and reply sample                     | `tweet`, `parents`, `comments_preview`, `other` |

`id` is required: use the numeric identifier in the post’s X status URL, or `posts[].id` from [`GET /user/id/{rest_id}/tweets`](#account-posts).
Use decimal digits from `1` to `9223372036854775807`, without a leading zero.
None of these endpoints has a pagination cursor.

`GET /tweet/{id}` and `GET /tweet/{id}/render` include the full long text where supplied.
Post fields include reply identifiers, edit versions, sensitive-attachment flags, links, mentions, hashtags, cashtags, cards and quoted posts.
Author fields include `protected`, `followers_count`, `friends_count`, `statuses_count` and `about`.

`GET /tweet/{id}/syndication` can shorten long text near 280 characters.
Its `tweet.comments` is the conversation count; on `tweet.quoted`, `comments` is the reply count.
`shares` is supplied only for a quoted post.
Use `GET /tweet/{id}` for the requested post’s share count and full text.

In `GET /tweet/{id}/render`, `parents` preserves conversation order, with the direct parent last.
`comments_preview` is a reply sample without continuation; `other` includes additional entries and object details.
A missing or deleted post returns `404` `not_found`; a post unavailable publicly returns `403` `private`.

To follow a reply, use `tweet.in_reply_to_id` from [`GET /tweet/{id}`](#posts-and-conversations) as `id` in another `GET /tweet/{id}` request.
`tweet.in_reply_to_screen_name` identifies the account addressed by the reply.

## Embeddable content

`GET /oembed?url=…` returns `{data}` with oEmbed fields such as `html`, `author_name`, `author_url` and `url`.
Post responses include author metadata; profile and list responses contain embeddable timelines.

`url` is required. Use HTTPS on `x.com` or `twitter.com`, including their `www.` and `mobile.` hosts, and encode the whole query value.
Accepted paths are `/{handle}/status/{id}`, `/{handle}`, `/i/lists/{id}` and `/{handle}/lists/{slug}`.
Post handles and identifiers use the formats under [Posts and conversations](#posts-and-conversations) and [Account profiles](#account-profiles).
Numeric list identifiers follow the same range as post identifiers: decimal digits from `1` to `9223372036854775807`, without a leading zero.

<span id="community-metadata" />

## Communities

| Method and path              | Returned information                                | Response fields                         | Continuation               |
| ---------------------------- | --------------------------------------------------- | --------------------------------------- | -------------------------- |
| `GET /community/{id}/render` | Metadata, rules, creator, banners and member sample | `community`, `other`                    | None                       |
| `GET /community/{id}/tweets` | Community posts                                     | `data`, `posts`, optional `next_cursor` | `cursor`, optional `limit` |
| `GET /community/{id}/media`  | Community media posts                               | `data`, `posts`, optional `next_cursor` | `cursor`, optional `limit` |

`id` is required: use the numeric identifier in `https://x.com/i/communities/{id}`.
Use decimal digits from `1` to `9223372036854775807`, without a leading zero.
The post endpoints also accept `community.id` from [`GET /community/{id}/render`](#communities).

Metadata includes `id`, `name`, `description`, `created_time`, `created_at`, `member_count`, `join_policy`, `is_nsfw` and `topic.name`.
`creator` identifies the creator; `rules` contains each rule’s `id`, `name` and `description`.
`members_preview` is a sample, not a complete member list, and has no continuation.
`custom_banner` and `default_banner` each include `type`, `url`, `width` and `height`, with dimensions in pixels.

`GET /community/{id}/render` returns `404` `not_found` for an absent community and `500` `upstream_shape` for unreadable metadata.
Unreadable metadata does not prove absence. Information unavailable without sign-in returns `501` `requires_auth`.

<span id="a-list" />

## Lists

`GET /list/{id}/timeline/syndication` returns `{list, posts, other}` with list details and a post preview, newest first.
`id` is required: use the numeric identifier in `https://x.com/i/lists/{id}`.
Use decimal digits from `1` to `9223372036854775807`, without a leading zero.

`list` includes `id`, `name`, `member_count` and `owner`.
`posts` has the same fields as the preview in [`GET /user/id/{rest_id}/timeline/syndication`](#account-posts), including potentially shortened text.
`other` contains additional entries and public object details. There is no cursor.

A missing list or a list with no available posts returns `404` `not_found`.
For `503` `rate_limited`, wait the number of seconds in `Retry-After`, or 60 seconds when no interval is supplied.

<span id="posts-for-a-topic" />

## Trends and topics

| Method and path              | Returned information                                   | Response fields                         |
| ---------------------------- | ------------------------------------------------------ | --------------------------------------- |
| `GET /trends/locations`      | Places with reported trends                            | `data`, `places`                        |
| `GET /trends?woeid=…`        | Trending topics for a place, including promoted topics | `data`, `trends`, `place`, `as_of`      |
| `GET /trends/timeline?tag=…` | Popular posts for a topic                              | `data`, `posts`, optional `next_cursor` |

`woeid` is optional: take `places[].woeid` from [GET /trends/locations](#trends-and-topics).
Use decimal digits from `1` to `4294967295`, without a leading zero.
The default is `1`, for worldwide trends. `places[].url` retains the published geographic address.

`tag` is required: 1 to 256 printable Unicode characters, with at least one non-space character.
Controls, invisible formatting characters and line or paragraph separators return `400` `bad_request` before X is asked.
Encode the query value, for example `tag=%23bitcoin` or `tag=New%20York`.
`GET /trends/timeline` has no `limit` parameter or search modes and does not provide a topic’s complete history.

Continue only when top-level `next_cursor` is present; follow [Pagination](#pagination).
An empty topic preview without continuation returns `500` `upstream_shape` and does not establish that the topic is absent.
This endpoint does not guarantee `404` for an absent topic.

## Live video

`GET /live` returns `{data, posts, next_cursor?}` with live broadcasts and video posts.
It accepts optional `cursor` and `limit`; see [Pagination](#pagination).
Later pages can contain recent videos already present on an earlier page.

## Audio spaces

`GET /space/{id}` returns `{data, space}` with a space’s title, state, times, host and participants.
`id` is required: 13 ASCII letters or digits from `https://x.com/i/spaces/{id}`.

`space` includes recording availability, live listener count, replay count, `host`, `admins`, `speakers` and `listeners` where supplied.
Participant records contain account `id`, `name`, `screen_name`, `avatar` and `is_verified`.
There is no pagination cursor.

<span id="derived-values" />
<span id="post-and-account-fields" />
<span id="professional-accounts" />

## Post and account values

- `created_at`, `started_at` and `ended_at` are ISO 8601 UTC times. Corresponding `created_time`, `started_time` and `ended_time` values use Unix milliseconds.
- `created_text`, where present, keeps the original date wording, such as `Tue Sep 29 03:16:33 +0000 2026`. `created_time` can be `null` while `created_at` is present.
- Video `duration_ms` and `duration_seconds` express the same duration. `variants` lists available files with content type, URL and bitrate where supplied; bitrate uses bits per second.
- `view_count` is numeric. Related values in `data` can be decimal strings.
- `edit_tweet_ids` lists post versions oldest first. `hashtags` omits `#`; `symbols` omits `$`.
- `company` contains a business affiliation name; other affiliation kinds give `null`.
- Paginated post authors can include `favourites_count`, `media_count`, `pinned_tweet_ids` and `professional`. `listed_count` is `null` when no count is supplied.

Professional information appears on `posts[].author` in [`GET /user/id/{rest_id}/tweets`](#account-posts), and on `space.host` in [`GET /space/{id}`](#audio-spaces), where supplied.
`professional.id` identifies the professional profile and can differ from the account ID.
`professional.type` retains values such as `Business` or `Creator`; each category contains `id` and `name` in X’s order.
An empty category list stays `[]`; unavailable category information gives `categories: null`, and unavailable professional information gives `professional: null`.
The `user` in [`GET /user/{name}`](#account-profiles) does not include this block.

<span id="pages" />

## Pagination

For each endpoint below, send the top-level response field `next_cursor` unchanged as query parameter `cursor` to the same method and path.
Keep the object identifier or topic tag unchanged. Omit `cursor` for the first request and stop when `next_cursor` is absent.
Use each cursor only for the endpoint that returned it.

| Method and path                                       | Cursor relation                                                 | Other page input           |
| ----------------------------------------------------- | --------------------------------------------------------------- | -------------------------- |
| [`GET /user/id/{rest_id}/tweets`](#account-posts)     | `next_cursor` → `cursor` in `GET /user/id/{rest_id}/tweets`     | Optional `limit`           |
| [`GET /user/id/{rest_id}/highlights`](#account-posts) | `next_cursor` → `cursor` in `GET /user/id/{rest_id}/highlights` | Optional `limit`           |
| [`GET /community/{id}/tweets`](#communities)          | `next_cursor` → `cursor` in `GET /community/{id}/tweets`        | Optional `limit`           |
| [`GET /community/{id}/media`](#communities)           | `next_cursor` → `cursor` in `GET /community/{id}/media`         | Optional `limit`           |
| [GET /live](#live-video)                              | `next_cursor` → `cursor` in `GET /live`                         | Optional `limit`           |
| [GET /trends/timeline](#trends-and-topics)            | `next_cursor` → `cursor` in `GET /trends/timeline`              | Required `tag`; no `limit` |

`cursor` accepts up to 8,192 characters: base64 or base64url decoding to at least five bytes, or two signed 64-bit decimal numbers separated by `|`.
Encode it as a query value; accepted base64 padding is zero to two `=` characters.
An unsupported cursor or one that cannot continue the list returns `400` `bad_request`.

`limit`, where available, is optional: 1 to 100, default 40. A response can contain more or fewer posts than requested.
An empty final paginated list returns `404` `not_found`; an empty list with `next_cursor` remains `200`.
The topic preview uses the `500` rule described under [Trends and topics](#trends-and-topics).

`pinned` is `true` for a pinned list entry and `false` for other entries and nested posts; a response can contain no pinned entry.
Pinned posts can repeat on later pages. Keep each once by `posts[].id` when combining responses.

<span id="endpoints-a-guest-cant-use" />

## Unavailable endpoints

These nine endpoints are excluded from the public API catalog. Their public paths return `404` without a charge; see [Pricing](https://monsterapi.co/docs/pricing).
They do not offer a usable public continuation path.

| Method and path                    | Information               | Public alternative                                                                                    |
| ---------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------- |
| `GET /tweet/{id}/thread`           | Paginated conversation    | [`GET /tweet/{id}/render`](#posts-and-conversations) provides a reply sample without continuation     |
| `GET /list/{id}/tweets`            | Paginated list posts      | [`GET /list/{id}/timeline/syndication`](#lists) provides a post preview without continuation          |
| `GET /list/{id}/members`           | List members              | No complete member list; [`GET /list/{id}/timeline/syndication`](#lists) includes `list.member_count` |
| `GET /user/id/{rest_id}/media`     | Account media posts       | Filter `posts[].media` in [`GET /user/id/{rest_id}/tweets`](#account-posts)                           |
| `GET /user/id/{rest_id}/followers` | Account followers         | No follower list; [`GET /user/{name}`](#account-profiles) includes `user.followers_count`             |
| `GET /user/id/{rest_id}/following` | Accounts followed         | No followed-account list; [`GET /user/{name}`](#account-profiles) includes `user.friends_count`       |
| `GET /user/id/{rest_id}/replies`   | Account posts and replies | None                                                                                                  |
| `GET /user/id/{rest_id}/likes`     | Account liked posts       | None                                                                                                  |
| `GET /search`                      | Search results            | None                                                                                                  |

<span id="refusals-and-retries" />

## Errors and retries

- `503` `rate_limited`: retry after the number of seconds in `Retry-After`, usually 60.
- `503` `upstream_error`: the request could not be completed. Retry after `Retry-After`, which is five seconds for this code.
- `503` `upstream_stale`: the request is temporarily unavailable. Retry the request; this code has no `Retry-After`.
- `500` `upstream_shape`: the requested information could not be read. This does not establish that the resource is absent.
- `501` `requires_auth`: the requested information is unavailable without sign-in.

A `5xx` response is not billed. See [Errors](https://monsterapi.co/docs/errors) for the error body and other codes.

## Public examples

Use the [API reference](https://monsterapi.co/docs/api) for ready-made public inputs and response examples.
Read [Examples](https://monsterapi.co/docs/examples) for provenance, preparation costs, task recipes, and pagination stop rules.
