# How do I get replies or a full thread on X (Twitter)?

X (Twitter). Checked September 2026.

Call `GET /v1/twitter/posts/{id}/comments`. Each request returns one page of direct replies with the author, text, time, and metrics, plus a cursor for the next page. For the replies under a reply, call `GET /v1/twitter/posts/{id}/comments/{replyId}/replies`.

A self-thread, where the author replies to their own post, is the same call. Filter replies where `author.id` equals the original author to read the thread in order.

## GET /v1/twitter/posts/{id}/comments

```bash
curl "https://api.openhandle.dev/v1/twitter/posts/940100000000000001/comments" \
  -H "Authorization: Bearer $OPENHANDLE_API_KEY"
```

```ts
import { OpenHandle } from '@openhandle/sdk';

const openhandle = new OpenHandle({ apiKey: process.env.OPENHANDLE_API_KEY! });
let page = await openhandle.twitter.post('940100000000000001').comments.list();

while (page) {
    for (const reply of page.data) console.log(reply.author.handle, reply.text);
    page = await page.next();
}
```

200 OK:

```json
{
  "platform": "twitter",
  "resource": "comment",
  "capturedAt": "2026-09-18T12:22:41Z",
  "source": "live",
  "data": [
    {
      "id": "940200000000000001",
      "postId": "940100000000000001",
      "text": "Synthetic Twitter reply 1.",
      "createdAt": "2026-08-09T15:31:00Z",
      "author": { "id": "940000000020", "handle": "reply_signal_x_test" },
      "metrics": { "likes": 0, "replies": 0 }
    }
  ],
  "meta": { "cursors": { "next": "b3BhcXVlLWN1cnNvcg" } }
}
```

Trimmed to one reply. The example post is a Test fixture with three replies, so you can test paging on a free Test key.

## From a status URL

Pass the x.com status URL to `POST /v1/urls/fetch` or `openhandle.fetch(url)`. It returns the post with its `id` and `conversationId`. Then read the replies. Store the ID. URLs carry handles, and handles change.

## Thread, replies, quotes

- **Direct replies.** The comments endpoint. One level deep, newest as X orders them.
- **Nested replies.** The replies endpoint under a comment. Call it for each reply whose `metrics.replies` is above zero.
- **The author’s thread.** Direct replies where `author.id` matches the original post’s author, sorted by `createdAt`.
- **Quote posts.** A post that quotes another carries `quotedPost`. Search for the original URL to find quotes of it.

## Why the old tools half-worked

X loads replies in chunks behind cursors that expire within minutes. Scrapers that paused between pages lost the rest of the thread. Openhandle cursors are bound to the request and stay valid, so a slow pipeline still gets every page.

## When this does not work

These answers are definitive. Store them, do not retry them.

| Situation | Status | Code |
|---|---|---|
| The post is deleted or never existed | 404 | `POST_NOT_FOUND` |
| The author’s account is protected | 403 | `PROFILE_PRIVATE` |
| The cursor came from another request | 400 | `CURSOR_MISMATCH` |

```json
{
  "error": {
    "code": "POST_NOT_FOUND",
    "message": "This post was not found.",
    "requestId": "req_01j8…",
    "retryable": false
  }
}
```

A reply from a protected account does not appear. X hides it from logged-out visitors, and so do we. Replies X marks as hidden by the author are not returned either.

## Related

- [How do I search X (Twitter) posts by keyword?](https://openhandle.dev/questions/how-do-i-search-x-twitter-posts-by-keyword): Find the posts whose threads you want.
- [Pagination](https://openhandle.dev/docs/concepts/pagination): Opaque cursors, one page per request.
- [X (Twitter) API](https://openhandle.dev/apis/twitter): Every X endpoint with examples.
