# Get the edit history of an X post

`GET /v1/x/posts/{id}/edits`

Returns every version of an edited post, newest first, including the current one. An empty list means the post exists and was never edited. X allows edits only in the first hour after posting. 404 when the post does not exist. Billed per version returned.

**Price:** 1 credit per call, plus 1 credit per X post returned. Failed and refused calls cost nothing.

**Rate limit:** Counts as 1 request against your per-minute rate limit.

**MCP tool:** `get_x_post_edits`, on every [MCP](/mcp) connection.

Requires an API key, sent as `Authorization: Bearer <key>`.

## Request

```bash
curl --request GET \
  --url https://api.weirapp.io/v1/x/posts/ID/edits \
  --header "Authorization: Bearer $WEIR_API_KEY"
```

### Path parameters

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `id` | string | yes | Numeric post id: the digits after `/status/` in a post's URL. · matches `^\d{1,19}$` |

## Response

Versions of the post, newest first.

### `200`

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `data` | array of object | yes |  |
| `data[].id` | string | yes | Numeric post id, as a string. It exceeds 2^53. |
| `data[].text` | string | yes | Full post text, untruncated. |
| `data[].url` | string | yes |  |
| `data[].lang` | string or null | yes | BCP-47 language tag detected by X. |
| `data[].createdAt` | string (date-time) | yes |  |
| `data[].conversationId` | string or null | yes | The thread this post belongs to. |
| `data[].inReplyToId` | string or null | yes |  |
| `data[].author` | object | yes |  |
| `data[].author.id` | string | yes |  |
| `data[].author.username` | string | yes |  |
| `data[].author.name` | string | yes |  |
| `data[].author.verified` | boolean | yes |  |
| `data[].author.followersCount` | integer | yes | min 0 |
| `data[].author.profileImageUrl` | string or null | yes |  |
| `data[].likeCount` | integer or null | yes | min 0 |
| `data[].retweetCount` | integer or null | yes | min 0 |
| `data[].replyCount` | integer or null | yes | min 0 |
| `data[].viewCount` | integer or null | yes | min 0 |
| `data[].quoteCount` | integer or null | yes | min 0 |
| `data[].bookmarkCount` | integer or null | yes | min 0 |
| `data[].media` | array of object | yes | Attached photos, videos, and GIFs, in display order. |
| `data[].media[].id` | string | yes |  |
| `data[].media[].type` | string | yes | X's own media type names. · `photo`, `video`, `animated_gif` |
| `data[].media[].url` | string or null | yes | The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream. |
| `data[].media[].previewImageUrl` | string or null | yes | Poster frame for a video. Null for photos and GIFs. |
| `data[].entities` | object | yes |  |
| `data[].entities.hashtags` | array of string | yes | Hashtags, without the `#`. |
| `data[].entities.mentions` | array of string | yes | Mentioned usernames, without the `@`. |
| `data[].entities.urls` | array of string | yes | Expanded link targets, not t.co short links. |
| `data[].quotedPost` | object or null | yes | The post this one quotes, when it is a quote post. |
| `data[].quotedPost.id` | string | yes | Numeric post id, as a string. It exceeds 2^53. |
| `data[].quotedPost.text` | string | yes | Full post text, untruncated. |
| `data[].quotedPost.url` | string | yes |  |
| `data[].quotedPost.lang` | string or null | yes | BCP-47 language tag detected by X. |
| `data[].quotedPost.createdAt` | string (date-time) | yes |  |
| `data[].quotedPost.conversationId` | string or null | yes | The thread this post belongs to. |
| `data[].quotedPost.inReplyToId` | string or null | yes |  |
| `data[].quotedPost.author` | object | yes |  |
| `data[].quotedPost.author.id` | string | yes |  |
| `data[].quotedPost.author.username` | string | yes |  |
| `data[].quotedPost.author.name` | string | yes |  |
| `data[].quotedPost.author.verified` | boolean | yes |  |
| `data[].quotedPost.author.followersCount` | integer | yes | min 0 |
| `data[].quotedPost.author.profileImageUrl` | string or null | yes |  |
| `data[].quotedPost.likeCount` | integer or null | yes | min 0 |
| `data[].quotedPost.retweetCount` | integer or null | yes | min 0 |
| `data[].quotedPost.replyCount` | integer or null | yes | min 0 |
| `data[].quotedPost.viewCount` | integer or null | yes | min 0 |
| `data[].quotedPost.quoteCount` | integer or null | yes | min 0 |
| `data[].quotedPost.bookmarkCount` | integer or null | yes | min 0 |
| `data[].quotedPost.media` | array of object | yes | Attached photos, videos, and GIFs, in display order. |
| `data[].quotedPost.media[].id` | string | yes |  |
| `data[].quotedPost.media[].type` | string | yes | X's own media type names. · `photo`, `video`, `animated_gif` |
| `data[].quotedPost.media[].url` | string or null | yes | The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream. |
| `data[].quotedPost.media[].previewImageUrl` | string or null | yes | Poster frame for a video. Null for photos and GIFs. |
| `data[].quotedPost.entities` | object | yes |  |
| `data[].quotedPost.entities.hashtags` | array of string | yes | Hashtags, without the `#`. |
| `data[].quotedPost.entities.mentions` | array of string | yes | Mentioned usernames, without the `@`. |
| `data[].quotedPost.entities.urls` | array of string | yes | Expanded link targets, not t.co short links. |
| `data[].retweetedPost` | object or null | yes | Set when this post is a repost. Read the original's text and counts here: X truncates a repost's own `text` to `RT @user: …`. |
| `data[].retweetedPost.id` | string | yes | Numeric post id, as a string. It exceeds 2^53. |
| `data[].retweetedPost.text` | string | yes | Full post text, untruncated. |
| `data[].retweetedPost.url` | string | yes |  |
| `data[].retweetedPost.lang` | string or null | yes | BCP-47 language tag detected by X. |
| `data[].retweetedPost.createdAt` | string (date-time) | yes |  |
| `data[].retweetedPost.conversationId` | string or null | yes | The thread this post belongs to. |
| `data[].retweetedPost.inReplyToId` | string or null | yes |  |
| `data[].retweetedPost.author` | object | yes |  |
| `data[].retweetedPost.author.id` | string | yes |  |
| `data[].retweetedPost.author.username` | string | yes |  |
| `data[].retweetedPost.author.name` | string | yes |  |
| `data[].retweetedPost.author.verified` | boolean | yes |  |
| `data[].retweetedPost.author.followersCount` | integer | yes | min 0 |
| `data[].retweetedPost.author.profileImageUrl` | string or null | yes |  |
| `data[].retweetedPost.likeCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.retweetCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.replyCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.viewCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.quoteCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.bookmarkCount` | integer or null | yes | min 0 |
| `data[].retweetedPost.media` | array of object | yes | Attached photos, videos, and GIFs, in display order. |
| `data[].retweetedPost.media[].id` | string | yes |  |
| `data[].retweetedPost.media[].type` | string | yes | X's own media type names. · `photo`, `video`, `animated_gif` |
| `data[].retweetedPost.media[].url` | string or null | yes | The image for a photo; the highest-bitrate MP4 for a video or GIF. Null when X offers only a stream. |
| `data[].retweetedPost.media[].previewImageUrl` | string or null | yes | Poster frame for a video. Null for photos and GIFs. |
| `data[].retweetedPost.entities` | object | yes |  |
| `data[].retweetedPost.entities.hashtags` | array of string | yes | Hashtags, without the `#`. |
| `data[].retweetedPost.entities.mentions` | array of string | yes | Mentioned usernames, without the `@`. |
| `data[].retweetedPost.entities.urls` | array of string | yes | Expanded link targets, not t.co short links. |
| `meta` | object | yes |  |
| `meta.requestId` | string | yes |  |
| `meta.nextCursor` | string or null | no |  |

## Errors

| Status | Meaning | What to do |
| --- | --- | --- |
| `400` | The request failed validation. | The request was malformed. The `details` object names the field. |
| `401` | The API key is missing, malformed, expired, or revoked. | The key is missing, malformed, revoked, or expired. |
| `402` | The account is out of credit. Not retryable: this cannot clear until the billing period resets or the plan changes. | Out of credits. **Never retry.** Only a person can clear it, by adding credits at https://weirapp.io/dashboard/billing. Retrying never will. |
| `403` | The API key does not carry the scope this route requires. | The key is valid but lacks the scope this operation needs. |
| `404` | The requested resource does not exist. | No such resource, or it is not public. |
| `429` | The per-minute rate limit is exhausted. Retryable: wait for Retry-After and try again. | Rate limited. Retryable: wait for `Retry-After`, then try again. |
| `500` | An unexpected error occurred. | Something failed on our side. Retryable with backoff. |
| `503` | The source is temporarily unavailable. The request is safe to retry. | A source was unreachable. Retryable with backoff. |
