{"name":"Probe Uranus","version":"1.11.0","description":"Profiles, posts, and search for X. Authenticate with an API key. Plan limits are per account.","auth":{"api_key":{"header":"Authorization","format":"Bearer <api_key>","alternateHeader":"X-API-Key"},"admin":{"header":"X-Admin-Secret","description":"Required for /v1/admin/* routes"}},"links":{"openapi":"/v1/openapi.json","health":"/health","commands":"/v1/commands"},"endpoints":[{"id":"health","method":"GET","path":"/health","summary":"Health check","description":"Service liveness plus scraper session pool status (operational | degraded | down).","auth":"none"},{"id":"catalog","method":"GET","path":"/v1","summary":"List available API commands","description":"Full list of available commands.","auth":"none","notes":["Also available at GET / and GET /v1/commands","Also available for API tools at GET /v1/openapi.json"]},{"id":"openapi","method":"GET","path":"/v1/openapi.json","summary":"Schema for API tools","description":"Command list in a format API tools understand.","auth":"none"},{"id":"me","method":"GET","path":"/v1/me","summary":"Current account plan and usage","description":"Returns plan limits, remaining RPM/daily/monthly quota, and reset timestamps for the account that owns this API key.","auth":"api_key","notes":["Counts as one request against your account quota","Also mirrored on every keyed response via X-RateLimit-* and X-RateLimit-Reset* headers","Response envelope: { data, meta }"]},{"id":"user_info","method":"GET","path":"/v1/user/info","summary":"Get user profile and stats","description":"Returns profile fields, follower/following counts, statuses, media counts, etc. Lookup by handle or numeric rest id.","auth":"api_key","params":[{"name":"userName","in":"query","required":false,"type":"string","description":"X handle without @ (alias: username). Provide userName or userId.","example":"elonmusk"},{"name":"userId","in":"query","required":false,"type":"string","description":"Numeric rest id (alias: user_id). Use when you store ids instead of handles.","example":"44196397"},{"name":"fresh","in":"query","required":false,"type":"boolean","description":"Bypass cache when 1/true/yes","example":"1"},{"name":"include_space","in":"query","required":false,"type":"boolean","description":"Look up whether the account is in a live Space (default true). Set 0/false/no to skip.","example":"1"},{"name":"include_broadcast","in":"query","required":false,"type":"boolean","description":"Look up whether the account is running a live video broadcast (default true). Set 0/false/no to skip.","example":"1"}],"notes":["Response envelope: { data, meta } with meta.cached / meta.fetched_at","Cache-Control: private, max-age=60 (or CACHE_TTL_MS capped); weak ETag from user id + fetched_at; 304 on If-None-Match","userName takes precedence if both are sent","data.currentSpace is live (fleets), not from the profile cache. Pass include_space=0 to skip.","data.currentBroadcast is the live video stream they are hosting, or null. X does not expose watchers. Pass include_broadcast=0 to skip."]},{"id":"user_tweets","method":"GET","path":"/v1/user/tweets","summary":"Get latest tweets for a user","description":"User timeline with cursor pagination. Tweets include media[] (url, previewUrl, width/height, durationMs, altText, variants[] with contentType/url/bitrate).","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @","example":"elonmusk"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_tweets_and_replies","method":"GET","path":"/v1/user/tweets-and-replies","summary":"Get tweets and replies for a user","description":"Timeline including the user's replies (UserTweetsAndReplies). Cursor-paginated.","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @","example":"elonmusk"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_mentions","method":"GET","path":"/v1/user/mentions","summary":"Get tweets mentioning a user","description":"Tweets that mention an account (SearchTimeline `@handle -from:handle`). Cursor-paginated. Not the authenticated user's notification inbox.","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @ (alias: username)","example":"elonmusk"},{"name":"product","in":"query","required":false,"type":"string","description":"Latest or Top (default Latest)","example":"Latest"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way.","meta.query is the search string used; equivalent to GET /v1/search/tweets?query=@handle%20-from:handle"]},{"id":"search_tweets","method":"GET","path":"/v1/search/tweets","summary":"Search tweets","description":"Latest/Top search over X posts.","auth":"api_key","params":[{"name":"query","in":"query","required":true,"type":"string","description":"Search query (alias: q). Supports X operators.","example":"solana"},{"name":"product","in":"query","required":false,"type":"string","description":"Latest or Top (default Latest)","example":"Latest"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":5},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"search_users","method":"GET","path":"/v1/search/users","summary":"Search users","description":"People search over X accounts via SearchTimeline (product=People). Cursor-paginated.","auth":"api_key","params":[{"name":"query","in":"query","required":true,"type":"string","description":"Search query (alias: q)","example":"solana"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_media","method":"GET","path":"/v1/user/media","summary":"Get media tweets for a user","description":"Media tab timeline (photos/videos/gifs). Cursor-paginated; tweets include media[] (altText and video variants[]).","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @ (alias: username)","example":"nasa"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"list_tweets","method":"GET","path":"/v1/list/{id}/tweets","summary":"Get tweets from an X list","description":"Latest tweets from a public list by numeric list id. Cursor-paginated.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric list id","example":"1539453138322673664"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"community_tweets","method":"GET","path":"/v1/community/{id}/tweets","summary":"Get tweets from an X community","description":"Community timeline (CommunityTweetsTimeline). Cursor-paginated.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric community id","example":"1489422448332197888"},{"name":"ranking","in":"query","required":false,"type":"string","description":"Relevance (default) or Recency (alias: rankingMode)","example":"Relevance"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."},{"name":"include_replies","in":"query","required":false,"type":"boolean","description":"Include reply tweets (default false on /user/tweets, true elsewhere)","example":"0"},{"name":"include_retweets","in":"query","required":false,"type":"boolean","description":"Include retweets (default true)","example":"1"},{"name":"media_only","in":"query","required":false,"type":"boolean","description":"Only tweets that have media[] (default false)","example":"1"},{"name":"since_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly greater than this snowflake (page filter; keep paging with cursor)"},{"name":"until_id","in":"query","required":false,"type":"string","description":"Keep tweets with id strictly less than this snowflake (exclusive)"}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"community_info","method":"GET","path":"/v1/community/{id}","summary":"Get community metadata","description":"Community name, description, member count, join policy (CommunityQuery).","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric community id","example":"1489422448332197888"}],"notes":["Response envelope: { data, meta }"]},{"id":"space_info","method":"GET","path":"/v1/space/{id}","summary":"Get an X Space","description":"Title, state, start time, listener counts, host/admins/speakers, and a listener sample (AudioSpaceById).","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Space id from x.com/i/spaces/{id} (e.g. 1wxWjlvBZynJQ). Full space URLs are also accepted.","example":"1wxWjlvBZynJQ"}],"notes":["Response envelope: { data, meta }","state is running | ended | scheduled | canceled | unknown","listeners[] is a sample; compare listeners.length to listenerCount. Silent listeners are not a complete roster.","admins = hosts/co-hosts, speakers = on-stage guests"]},{"id":"space_users","method":"GET","path":"/v1/space/{id}/users","summary":"Get users in an X Space","description":"Hosts, on-stage speakers, and a listener sample for a Space. Filter with role=admins|speakers|listeners|on_stage|all.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Space id (same as /v1/space/{id})","example":"1wxWjlvBZynJQ"},{"name":"role","in":"query","required":false,"type":"string","description":"all (default), admins, speakers, listeners, or on_stage (admins+speakers)","example":"on_stage"}],"notes":["Response envelope: { data, next_cursor, cursor, meta } — snapshot, not cursor-paged","Each row: id, userName, name, profileImageUrl, isBlueVerified, role, joinedAt*","meta.listener_sample is true when listeners.length < listenerCount"]},{"id":"broadcast_info","method":"GET","path":"/v1/broadcast/{id}","summary":"Get an X broadcast (live video)","description":"Title, state, host, viewer counts, thumbnail, and start time for a live or replayable video broadcast.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Broadcast id from x.com/i/broadcasts/{id} (e.g. 1nxeLMkBVgYJX). Full broadcast URLs are also accepted.","example":"1nxeLMkBVgYJX"}],"notes":["Response envelope: { data, meta }","state is running | ended | scheduled | canceled | unknown","X does not expose a watcher roster — only watchingCount / watchedCount","host is the account running the stream"]},{"id":"trends","method":"GET","path":"/v1/trends","summary":"Trending topics by location","description":"Trending topics for a Yahoo WOEID via X trends/place. 1 = Worldwide. Tweet volumes are what X returns (often null).","auth":"api_key","params":[{"name":"woeid","in":"query","required":false,"type":"number","description":"Yahoo WOEID (alias: id). Default 1 (Worldwide). US = 23424977.","example":1}],"notes":["Response envelope: { data, next_cursor, cursor, meta } — next_cursor is always null","Each trend: name, query, url, tweetVolume","This is not a tweet-volume time series (X tweets/counts/recent). Use search for that."]},{"id":"tweet_by_id","method":"GET","path":"/v1/tweet/{id}","summary":"Get a tweet by id","description":"Returns a single post with author, media[] (including altText and video variants[]), and engagement counts (likes, replies, retweets, quotes, bookmarks, views).","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"}],"notes":["Response envelope: { data, meta }","Cache-Control: private, max-age=60 (or CACHE_TTL_MS capped); weak ETag from tweet id; 304 on If-None-Match"]},{"id":"tweet_by_url","method":"GET","path":"/v1/tweet/by-url","summary":"Get a tweet by X/Twitter URL","description":"Accepts an x.com or twitter.com status URL (or raw numeric id) and returns the same shape as tweet-by-id.","auth":"api_key","params":[{"name":"url","in":"query","required":true,"type":"string","description":"Status URL (alias: u)","example":"https://x.com/jack/status/20"}],"notes":["Response envelope: { data, meta }","Cache-Control: private, max-age=60 (or CACHE_TTL_MS capped); weak ETag from tweet id; 304 on If-None-Match"]},{"id":"tweet_replies","method":"GET","path":"/v1/tweet/{id}/replies","summary":"Get replies to a tweet","description":"Conversation replies for a post (commenters + engagement). Cursor-paginated.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way.","Parent tweet (when available) is in meta.tweet"]},{"id":"tweet_thread","method":"GET","path":"/v1/tweet/{id}/thread","summary":"Get thread context for a tweet","description":"Parent chain (ancestors, oldest first), the focal tweet, and first-page replies from TweetDetail.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id (any tweet in the thread)","example":"20"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, meta } with data.tweet, data.ancestors, data.replies","Pass meta.next_cursor as ?cursor= to page more replies","Missing parents are fetched up the inReplyTo chain (bounded)"]},{"id":"tweet_retweeters","method":"GET","path":"/v1/tweet/{id}/retweeters","summary":"List users who retweeted a tweet","description":"Retweeters for a post. Cursor-paginated.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way.","createdAt is the account join date. X does not expose when each user retweeted."]},{"id":"tweet_likes","method":"GET","path":"/v1/tweet/{id}/likes","summary":"Like count for a tweet","description":"Returns how many times a post was liked. X does not expose who liked it to these sessions. Same number as favoriteCount on GET /v1/tweet/{id}.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"}],"notes":["Response envelope: { data, meta }","data: { id, likes }"]},{"id":"tweet_quotes","method":"GET","path":"/v1/tweet/{id}/quotes","summary":"List quote tweets of a tweet","description":"Quote posts for a status via search (quoted_tweet_id). Cursor-paginated.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"tweet_quoters","method":"GET","path":"/v1/tweet/{id}/quoters","summary":"List users who quoted a tweet","description":"Unique authors of quote tweets. Cursor-paginated (same cursor as /quotes).","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way.","quotedAt / quotedAtMs / quotedAtIso is when that user posted the quote tweet."]},{"id":"tweet_engagers","method":"GET","path":"/v1/tweet/{id}/engagers","summary":"Build an engager pool / pick winners","description":"Pages retweeters, reply authors, and/or quoters into a deduped pool. Optional random winners (TwitterPicker-style). Like identities are not available; use GET /v1/tweet/{id}/likes for the count.","auth":"api_key","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Numeric tweet/status id","example":"20"},{"name":"types","in":"query","required":false,"type":"string","description":"Comma list: retweet,reply,quote (default retweet,reply,quote). like is accepted but skipped — identities are unavailable","example":"retweet,reply,quote"},{"name":"mode","in":"query","required":false,"type":"string","description":"union (any selected type) or intersect (all selected types)","example":"union"},{"name":"max_pages","in":"query","required":false,"type":"number","description":"Pages to pull per type (1-10, default 3)","example":3},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"winners","in":"query","required":false,"type":"number","description":"If set, data is a random sample of this size from the pool","example":5},{"name":"seed","in":"query","required":false,"type":"number","description":"Optional RNG seed for reproducible winner picks","example":42}],"notes":["Response envelope: { data, meta }","meta.counts has per-type and pool sizes; meta.notes explains skipped like identities","Without winners, data is the full deduped pool"]},{"id":"tweets_batch","method":"POST","path":"/v1/tweets","summary":"Batch fetch tweets by id","description":"Fetch up to 25 tweets in one request. Partial failures return in errors[].","auth":"api_key","body":{"contentType":"application/json","fields":[{"name":"ids","in":"body","required":true,"type":"string","description":"Array of tweet ids or status URLs (alias: tweetIds), max 25","example":"20"}],"example":{"ids":["20","https://x.com/jack/status/20"]}},"notes":["Response envelope: { data, meta } with meta.errors / meta.max"]},{"id":"users_batch","method":"POST","path":"/v1/users","summary":"Batch fetch user profiles","description":"Fetch up to 25 profiles in one request by handle and/or numeric rest id. Partial failures return in errors[].","auth":"api_key","body":{"contentType":"application/json","fields":[{"name":"userNames","in":"body","required":false,"type":"string","description":"Array of handles without @ (alias: usernames)","example":"jack"},{"name":"userIds","in":"body","required":false,"type":"string","description":"Array of numeric rest ids (alias: ids)","example":"44196397"}],"example":{"userNames":["jack"],"userIds":["44196397"]}},"notes":["Response envelope: { data, meta } with meta.errors / meta.max","Each user includes currentSpace and currentBroadcast (live fleets lookup) or null"]},{"id":"user_followers","method":"GET","path":"/v1/user/followers","summary":"List followers for a user","description":"Followers of an X account. Cursor-paginated.","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @ (alias: username)","example":"elonmusk"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_following","method":"GET","path":"/v1/user/following","summary":"List accounts a user follows","description":"Following list for an X account. Cursor-paginated.","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @ (alias: username)","example":"elonmusk"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_verified_followers","method":"GET","path":"/v1/user/verified-followers","summary":"List verified followers for a user","description":"Blue-verified followers only (BlueVerifiedFollowers). Cursor-paginated.","auth":"api_key","params":[{"name":"userName","in":"query","required":true,"type":"string","description":"X handle without @ (alias: username)","example":"elonmusk"},{"name":"limit","in":"query","required":false,"type":"number","description":"Page size (1-40, default 20)","example":20},{"name":"cursor","in":"query","required":false,"type":"string","description":"Opaque pagination cursor. Pass next_cursor (or cursor) from the previous response unchanged."}],"notes":["Response envelope: { data, next_cursor, cursor, meta }","meta.has_next_page mirrors next_cursor; extra context (user, filters, query) lives in meta","Pass next_cursor back as ?cursor=. Do not invent or parse cursors","Posts include createdAt (X date string), createdAtMs (unix ms), and createdAtIso (ISO-8601). On a retweet, createdAt is when it was reposted; retweetedStatus is the original post. Quotes expose quotedStatus the same way."]},{"id":"user_relationship","method":"GET","path":"/v1/user/relationship","summary":"Check follow relationship between two users","description":"Whether source follows target and vice versa, via X friendships/show. Not scoped to the cookie owner.","auth":"api_key","params":[{"name":"sourceUserName","in":"query","required":false,"type":"string","description":"Source handle (alias: source). Provide handle or sourceUserId.","example":"jack"},{"name":"targetUserName","in":"query","required":false,"type":"string","description":"Target handle (alias: target). Provide handle or targetUserId.","example":"elonmusk"},{"name":"sourceUserId","in":"query","required":false,"type":"string","description":"Source numeric rest id (alias: sourceId)","example":"12"},{"name":"targetUserId","in":"query","required":false,"type":"string","description":"Target numeric rest id (alias: targetId)","example":"44196397"}],"notes":["Response envelope: { data, meta }","data.source.following is true when source follows target","meta.source_follows_target / meta.target_follows_source mirror those flags"]},{"id":"admin_seed_plans","method":"POST","path":"/v1/admin/seed-plans","summary":"Seed plan tiers","description":"Creates starter/pro/unlimited plans if missing.","auth":"admin"},{"id":"admin_create_key","method":"POST","path":"/v1/admin/keys","summary":"Create an API key","description":"Returns the raw API key once. Store it securely.","auth":"admin","body":{"contentType":"application/json","fields":[{"name":"name","in":"body","required":false,"type":"string","description":"Key label","example":"owner"},{"name":"planName","in":"body","required":false,"type":"string","description":"starter | pro | unlimited","example":"unlimited"}],"example":{"name":"owner","planName":"unlimited"}}},{"id":"admin_list_keys","method":"GET","path":"/v1/admin/keys","summary":"List API keys","description":"Does not return raw key secrets.","auth":"admin"},{"id":"admin_add_session","method":"POST","path":"/v1/admin/sessions","summary":"Add connection","description":"Register a connection for API capacity.","auth":"admin","body":{"contentType":"application/json","fields":[{"name":"label","in":"body","required":false,"type":"string","description":"Human label"},{"name":"authToken","in":"body","required":true,"type":"string","description":"X auth_token cookie"},{"name":"ct0","in":"body","required":true,"type":"string","description":"X ct0 cookie"},{"name":"maxRpm","in":"body","required":false,"type":"number","description":"Per-connection requests per minute (default 25)"}]}},{"id":"admin_list_sessions","method":"GET","path":"/v1/admin/sessions","summary":"List connection health","description":"Status, cooldown, and usage only. No secrets.","auth":"admin"},{"id":"admin_patch_session","method":"PATCH","path":"/v1/admin/sessions/{id}","summary":"Update connection status","description":"Set healthy | cooling | dead | disabled.","auth":"admin","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Connection id"}],"body":{"contentType":"application/json","fields":[{"name":"status","in":"body","required":true,"type":"string","description":"healthy | cooling | dead | disabled"}]}},{"id":"admin_rotate_session","method":"PUT","path":"/v1/admin/sessions/{id}","summary":"Rotate connection","description":"Replace connection tokens and mark healthy.","auth":"admin","params":[{"name":"id","in":"path","required":true,"type":"string","description":"Connection id"}],"body":{"contentType":"application/json","fields":[{"name":"authToken","in":"body","required":true,"type":"string","description":"New auth_token cookie"},{"name":"ct0","in":"body","required":true,"type":"string","description":"New ct0 cookie"}]}},{"id":"admin_refresh_query_ids","method":"POST","path":"/v1/admin/query-ids/refresh","summary":"Refresh operation IDs","description":"Refresh cached operation identifiers.","auth":"admin"}]}