# Twitter/X (/docs/twitter) X (Twitter) profiles, tweets, communities, video transcripts, AI search, and a one-call profile composite X (formerly Twitter) profiles and their tweets, individual tweets in full, community pages and their posts, video transcripts, an AI-answered search over the network, and a composite that returns a profile with computed analytics in one call. X remains the primary platform for real-time public conversation and news, and it is also the platform with the tightest read limits, most of the design decisions below follow from that. Base URL: `/v1/twitter/...` ## How do I get started with Twitter/X data? ### 1. Fetch a profile ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/twitter/profile?handle=elonmusk" \ -H "x-api-key: YOUR_API_KEY" ``` ### 2. Fetch their content ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/twitter/user/tweets?handle=elonmusk" \ -H "x-api-key: YOUR_API_KEY" ``` ### 3. Read computed fields When an endpoint supports a computed field and the required source inputs are present, the unified response includes that optional field. Depending on the endpoint, optional fields can include `engagement_rate`, `language`, `content_category`, and `estimated_reach`. See [Computed fields](/docs/computed-fields.md) for formulas, clamping rules, and null semantics. Where an endpoint supports them, list rows also carry judged labels (`computed.labels`, `computed.relevance`) by default at no extra credits; see [Labels](/docs/labels.md). ## What you can get **Accounts.** `GET /v1/twitter/profile` (1cr) takes a `handle` and returns follower, following and tweet counts, bio, avatar, banner (`author.ext.cover_url`), the website from the bio resolved past its t.co shortener (`author.ext.bio_link`), verification, privacy flag, join date and location. `GET /v1/twitter/user/tweets` (1cr a page) returns the account's Posts tab in descending order, retweets and self-threads included, with the pinned tweet flagged and the author's follower, following and tweet counts on every row (`post.ext.author_followers` and siblings), so you do not need a second profile call per tweet. `GET /v1/twitter/user/media` (1cr a page) narrows that to the tweets carrying a photo or video. **The follow graph.** `GET /v1/twitter/user/followers` and `GET /v1/twitter/user/following` (1cr a page, around 70 accounts a page) return the accounts on each side of a handle's graph, with counts, bio, avatar and join date per row. Verification is not on this surface and comes back null; fetch `profile` for an account you need it on. **One tweet.** `GET /v1/twitter/tweet` (1cr) takes the tweet `url` and returns the full record: text, likes, retweets, replies, bookmarks, views, media, author and timestamp, plus `post.ext.quote_count` and the author's follower, following and tweet counts on `post.ext`. The handle in the URL is not checked, because X serves a status by its numeric id, so the author you get back is the one X reports and can differ from the handle you sent. `GET /v1/twitter/tweet/replies` (1cr a page) returns the replies to it, each with the commenter's counts, language, views, bookmarks and quote count on `comment.ext`, and `GET /v1/twitter/tweet/retweeters` (1cr a page) the accounts that retweeted it. **Search.** `GET /v1/twitter/search/tweets` (1cr a page) searches X by keyword or phrase. X's own search operators inside `query` narrow the search itself, so `since:2026-08-01`, `until:2026-09-01`, `from:handle`, `min_faves:20`, `filter:images` and `filter:videos` all work there. The `since` and `until` parameters filter the rows that come back, and `since` ends a newest-first walk at that date. `sort=top` ranks by engagement rather than relevance, so quote a multi-word phrase when you need precision. Tweet and reply rows carry `post.ext.author_location`, the free text the author wrote in their profile's location field, as written. It is not a country code, and it is absent when the author left it blank; [discover](/docs/prism/discover.md) reads a country from it, so `country=` there filters X rows. `GET /v1/twitter/search/users` (1cr a page) searches accounts by name, handle, or keyword and returns bio, follower, following and tweet counts, location, verification, join date and avatar per row. Matching has no spelling correction, so a misspelled handle surfaces lookalikes; verify the returned handle. Page size is set by the source, typically around 20 accounts. **Video speech.** `GET /v1/twitter/tweet/transcript` (10cr) returns the spoken words from a video attached to a tweet, auto-generated captions included, for videos up to 10 minutes (600 seconds). `tweet` returns the media attachment; this returns what is said in it. A longer video returns 400 with `error.details.reason: video_too_long`, and a video with no speech returns 404 `no_captions`, both at no charge. See [error reasons](/docs/errors.md). **Communities.** `GET /v1/twitter/community` (1cr) takes a community `url` and returns the group itself: name, description, member count, creation date, and the rules under `author.ext.rules`. `GET /v1/twitter/community/tweets` (1cr) returns what has been posted inside it, a fixed window of around 16 to 20 recent posts. Both take the community URL, and neither paginates. **AI search.** `GET /v1/twitter/ai-search` (5cr) takes a plain-English `query` and returns a written answer, the X posts cited as sources, and how many searches the model ran to get there. Narrow it with `from_handles`, `exclude_handles`, `from_date`, and `to_date`. Read a thin answer as thin retrieval rather than an empty corpus: the model runs a handful of internal searches and answers from what they return, and `search/tweets` over the same window routinely finds more. **The composite.** `GET /v1/twitter/profile/full` (5cr) fans out to the profile and recent-posts endpoints in parallel and returns the unified author, the post list, and computed metrics. Two average engagement rates (`avg_engagement_rate` over view counts, `avg_engagement_rate_by_followers` over the follower count, which covers posts with no view count), posting cadence with the window it was measured over, the top post, and the format mix. `posts` sets how many recent tweets to average over (1-100, default 25), and `include=computed` drops the raw `posts[]` to save payload. ```bash title="cURL" curl "https://www.socialcrawl.dev/v1/twitter/profile/full?handle=elonmusk&posts=50" \ -H "x-api-key: YOUR_API_KEY" ``` ## Reading further back than one page `user/tweets`, `user/media`, `search/tweets`, `search/users`, `tweet/replies`, `tweet/retweeters`, `user/followers` and `user/following` are all cursor-paged. Send `pagination.next_cursor` back as `cursor` and repeat until `pagination.has_more` is false. Each page costs 1 credit, and page size is set by the source: roughly 20 tweets on the timeline and search lanes, roughly 20 accounts on `search/users`, roughly 70 accounts on the graph lanes. When the main source cannot fetch a page of `user/tweets` or a `latest` keyword search, a second source answers it and the walk carries on from the last post you received, so nothing repeats and the price stays 1 credit a page. Two cases end sooner on the second source: a `sort=top` search answered there is one page with no cursor, and so is the first page of `tweet/replies`, which then holds up to 40 direct replies. `profile/full` deepens the same way, with its own name: pass a prior response's `posts_cursor` back as `cursor`. On X the posts leg is one page of about 20 tweets; `posts` slices that page (so `posts=100` still returns about 20) and does not walk further pages. Averages in `computed` are over whatever came back. One lane genuinely does not page, and says so rather than minting a cursor that goes nowhere: `community/tweets` (the source returns one fixed window). Sending `cursor` to it is a 400 before it costs a credit. The profile leg is the only critical leg on `profile/full`. If the tweets cannot be fetched you still get a `200` with the profile and null post-dependent metrics rather than an error, and every leg's outcome is reported in `legs[]`. Check `legs[]` before you treat a null cadence as a quiet account. ## Labels These lists label their rows by default, at no extra credit. On `/v1/twitter/tweet/replies`, each comment carries `sentiment`, `question`, `purchase_intent` and `complaint` on `computed.labels`. On `/v1/twitter/user/tweets` and `/v1/twitter/search/tweets`, each row carries `sponsored`, `intent` and `niche`. `/v1/twitter/search/tweets` also scores each row's relevance to your `query` on `computed.relevance`, without dropping or reordering anything; add `relevance=filter` to drop the rows that are about something else, still free. Send `judgments=off` for the page without them. See [Labels](/docs/labels.md) for the field shapes, rows still `pending`, and the labels you can add with `label=`. ## Endpoints ## What should I know about Twitter/X data? - All endpoints use `GET` method with query parameters - Authentication via `x-api-key` header - Responses follow the unified SocialCrawl schema - `profile`, `profile/full`, `user/tweets`, `user/media`, `user/followers` and `user/following` take a `handle` (no `@`); `tweet`, `tweet/replies`, `tweet/retweeters`, `tweet/transcript`, `community` and `community/tweets` take a `url`; `search/tweets`, `search/users` and `ai-search` take a `query` - Long-form posts return their complete body on every lane, not the 280-character clamp, and t.co links inside the text are resolved to their destinations - A tweet carrying more than one photo lists every URL in `post.ext.all_media_urls`; `post.content.media_urls` holds the first - `trim=true` is accepted on `user/tweets` and `tweet` for backwards compatibility and is ignored. It only ever shrank the raw upstream payload, which the unified response never exposed - `author.likes_count` is always null on X: the platform publishes no total-likes-received figure, and the "Likes" tab count is a different number ## Official Twitter/X Resources - [X API Documentation](https://developer.x.com/en/docs): Official X developer platform - [X API Access Levels](https://developer.x.com/en/docs/twitter-api/getting-started/about-twitter-api): API tiers and access