Get up to 100 public X posts by id

GET /v1/x/posts

Looks up many posts in one request, for hydrating ids you already hold (from a webhook, a dataset, or another response). Posts come back in the order requested. An id that cannot be returned is listed in meta.notFound instead of failing the request, and is not billed. Billed per post returned.

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

Rate limit: Counts as 2 requests against your per-minute rate limit.

MCP tool: get_x_posts, on every MCP connection.

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

Request

curl --request GET \
  --url https://api.weirapp.io/v1/x/posts?ids=IDS \
  --header "Authorization: Bearer $WEIR_API_KEY"

Query parameters

Field Type Required Notes
ids string yes Comma-separated numeric post ids, 1 to 100, no spaces. Duplicates are ignored. · matches ^\d{1,19}(,\d{1,19}){0,99}$

Response

The posts found, in request order.

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.notFound array of string yes Requested ids that came back empty: deleted, suspended, protected, withheld, or never existed. They cost nothing.

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.

View this page as Markdown