X
LiveSensitiveOne post
/data-api/v2/x/tweets/{id}- Scope
- scrape:live
- Freshness
- live read
- Group
- X
- Platforms
- 1 of 7
What this endpoint answers
A single post with its counters, its entities and its full author. The nested quote or retweet, when there is one, is reported by id rather than inlined - fetch it explicitly if you need it, so one call can never turn into an unbounded payload.
This is a live read: it goes to the platform at request time, returns cache_age_s = 0, and is metered against a separate live-per-minute bucket on top of your tier. It needs the scrape:live scope (Live scrape): Read from the platform itself rather than from the catalog: a profile or channel on any of the seven platforms, and on X the whole content layer - timelines, posts, replies, quotes, threads, followers, search, lists and communities.
Good to know
- views and bookmarks are null, never 0, when X withheld them.
- 404 covers deleted posts, posts from protected accounts and ids that never existed. X does not distinguish them and neither can we.
- Metered as a live call. It leaves the building and spends a slot on the same scraper pool that lets sellers verify a listing, so read GET /scrape/status and back off BEFORE you start failing rather than after.
- 503 with upstream_error or upstream_timeout is worth retrying; 404 is not. A 503 whose message names a rate-limited X endpoint means the answer is unknown, not empty - never cache it as a result.
Parameters
Every value the call accepts, with the example the spec ships so the request runs as written.
| Name | In | Required | Example | What it does |
|---|---|---|---|---|
id | path | required | 440322224407314432 | Numeric post id - the digits at the end of an x.com/.../status/... link. |
Call it
Authenticate with a bearer token or the x-api-key header. Keys are server-to-server credentials. Never embed one in front-end code - call the API from your own backend and forward the result.
curl "https://crmsolid.com/data-api/v2/x/tweets/440322224407314432" \
-H "Authorization: Bearer psk_live_..."
const res = await fetch("https://crmsolid.com/data-api/v2/x/tweets/440322224407314432", {
headers: {
Authorization: `Bearer ${process.env.CRM_SOLID_DATA_API_KEY}`,
},
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`${error.code}: ${error.message} (${error.request_id})`);
}
const { data, meta } = await res.json();
import os
import requests
res = requests.get(
"https://crmsolid.com/data-api/v2/x/tweets/440322224407314432",
headers={"Authorization": f"Bearer {os.environ['CRM_SOLID_DATA_API_KEY']}"},
timeout=30,
)
res.raise_for_status()
payload = res.json()
data, meta = payload["data"], payload["meta"]
Keys look like psk_live_... for production keys, psk_test_... for test keys and are minted in the panel.
What comes back
Success is { data, meta }. Failure is { error: { code, message, request_id } }. The body below is the spec's own example: the values in it are illustrative readings, not live numbers.
- Tweet id
- 1908244251923312641
- Url
- https://x.com/elonmusk/status/1908244251923312641
- Text
- Starship is stacked
- Created at
- 8/30/2026, 4:02:11 PM
- Lang
- en
- Source
- Twitter for iPhone
- Likes
- 184,221
- Retweets
- 21,004
- Replies
- 9,118
- Quotes
- 1,402
- Bookmarks
- 3,889
- Views
- 41,882,337
- Is reply
- no
- Is retweet
- no
- Is quote
- no
- Conversation id
- 1908244251923312641
- Media
- photo
- Author user id
- 44196397
- Author handle
- elonmusk
- Author display name
- Elon Musk
- Author followers
- 221,400,112
- Author following
- 1,104
- Author tweets
- 78,412
- Author media count
- 9,233
- Author likes given
- 148,902
- Author is verified
- no
- Author is blue verified
- yes
- Author is protected
- no
{
"data": {
"tweet_id": "1908244251923312641",
"url": "https://x.com/elonmusk/status/1908244251923312641",
"text": "Starship is stacked",
"created_at": "2026-08-30T16:02:11+00:00",
"lang": "en",
"source": "Twitter for iPhone",
"likes": 184221,
"retweets": 21004,
"replies": 9118,
"quotes": 1402,
"bookmarks": 3889,
"views": 41882337,
"is_reply": false,
"is_retweet": false,
"is_quote": false,
"conversation_id": "1908244251923312641",
"in_reply_to_tweet_id": null,
"quoted_tweet_id": null,
"retweeted_tweet_id": null,
"hashtags": [],
"mentions": [],
"links": [],
"media": [
"photo"
],
"author": {
"user_id": "44196397",
"handle": "elonmusk",
"display_name": "Elon Musk",
"bio": "",
"followers": 221400112,
"following": 1104,
"tweets": 78412,
"media_count": 9233,
"likes_given": 148902,
"is_verified": false,
"is_blue_verified": true,
"is_protected": false,
"location": null,
"avatar_url": "https://pbs.twimg.com/profile_images/1234567890/abc_400x400.jpg",
"header_url": null,
"created_at": "2009-06-02T20:12:29+00:00",
"profile_url": "https://x.com/elonmusk"
}
},
"meta": {
"request_id": "req_9f2c41a8b3d5",
"generated_at": "2026-08-23T09:14:02.317Z",
"took_ms": 42,
"cache_age_s": 0
}
}
The meta block
request_idstringrequiredUnique id for this request. Quote it in a support ticket.
generated_atstringrequiredServer time the response was produced.
took_msintegerrequiredMilliseconds spent server-side.
pagePageoptionalsourcestringoptionalWhich backend served the payload, for endpoints with more than one.
cache_age_sintegeroptionalAge of the underlying data in seconds. 0 for live reads.
When it fails
GET /x/tweets/{id} documents 8 failure statuses. Branch on error.code, which is stable and enumerated; message is prose and may change.
- 401Unauthorized
unauthorized | invalid_keyNo key was presented, or the key is unknown, revoked or expired.
- 402PaymentRequired
payment_required | subscription_inactiveThe key is valid but the plan behind it cannot serve the call: the included requests are spent and overage is switched off, capped or unfunded (payment_required), or the billing period lapsed and was not renewed (subscription_inactive). Retrying does not help; paying does. The X-Plan-* headers on this response say how far past the line you are.
Carries X-Plan, X-Plan-Limit, X-Plan-Overage, X-Plan-Period-End, X-Plan-Remaining.
- 403Forbidden
forbidden_scope | forbidden_ipThe key is valid but not allowed to make this call: it lacks the scope, or the request came from an address outside the key's allowlist.
- 404NotFound
not_foundThe addressed resource does not exist.
- 422InvalidRequest
invalid_requestA parameter is malformed, out of range or mutually exclusive with another. `details` names the offending fields.
- 429RateLimited
rate_limited | quota_exceededEither the burst ceiling for the current minute or the daily quota is spent. Distinguish with the code: rate_limited clears within the minute, quota_exceeded does not clear until 00:00 UTC.
Carries Retry-After, X-Quota-Limit, X-Quota-Remaining, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-Request-Id.
- 500InternalError
internal_errorSomething failed on our side. Internals are never leaked; quote the request id.
- 503Unavailable
upstream_timeout | upstream_error | not_configuredThe request could not be served right now. BRANCH ON error.code, not on the status: 'upstream_timeout' means a source was too slow (this is what a catalog query hitting its 15-second statement timeout returns, so it is reachable from any endpoint that reads the corpus, not only the live-scrape ones) and the same call is worth retrying with backoff - narrowing it with a smaller limit, a filtered scope or a less popular account makes it far less likely; 'upstream_error' means a source was unreachable, so back off further; 'not_configured' means the capability has no backing service in this deployment, and retrying will never help.
Every response carries X-Request-Id and meta.request_id. Quote it in support requests.
Coverage and limits
This endpoint covers X. Rate limits come from the tier on your key.
| Tier | Requests a minute | Requests a day | Live reads a minute |
|---|---|---|---|
| free | 30 | 1,000 | 5 |
| standard | 120 | 25,000 | 20 |
| pro | 600 | 250,000 | 60 |
| unlimited | 6,000 | 10,000,000 | 600 |
Live reads count against the live column as well as the ordinary one, so a burst of them runs out of the live bucket first. Every response reports where you stand in X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and the X-Plan headers.
Start calling it
A key takes a minute to mint in the panel, no card. The reference covers authentication, the envelope, scopes, rate limits and every error code in one page.
Reference path: /data-api/reference/x-tweets-get