Twitter User About Batch API | 100 Profiles a Call
Read the full About object for up to 100 accounts in one request: the same object GET /user/user_about returns, including X's "About this account" transparency panel (account country, how the account was created, and username-change history). Results come back in request order, each with its about object or an error code. Cost: $0.0008 per billed item.
User About Batch reads the About object for up to 100 accounts in one request, the same object GET /user/user_about returns for one. Pass a comma-separated list of usernames. Results come back in request order, one entry per account, each with its about object or an error code. Use it to vet a list of accounts by country (account_based_in) in a single call. $0.0008 per billed item.
Authorization
bearerAuth Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.
In: header
Query Parameters
Comma-separated handles, with or without the leading @. Send this or user_ids, never both. Between 1 and 100 distinct entries after duplicates are removed (handles compare case-insensitively). A malformed handle returns a 400 for the whole request.
Comma-separated numeric user IDs, as an alternative to usernames. Send this or usernames, never both. Same 1 to 100 limit. Each ID is resolved to its current handle, then looked up; results echo each ID as you sent it. Leading zeros are ignored for duplicates (012 and 12 are one account).
Comma-separated list of dotted field paths to keep in the response (one parameter, never repeated), applied to every object in the returned lists and to nested objects (for example fields=id,text,author.username; the list's own name may prefix a path, fields=tweets.id). A path prefix that lands on an array applies to each element (media.media_url_https). Pagination and envelope keys (next_cursor, cursor, has_more, count, partial, error, message, reason) are always kept. Unknown paths are ignored; up to 50 paths of up to 6 segments. Projection never changes status codes or billing, and applies to data reads only: account, feedback, session status, monitor (other than deliveries), webhook and stream-compat reads return their bodies unchanged.
Set to 1 (or true) to apply the built-in compact preset: ids, url, text, created_at, lang, the engagement counts, the is_retweet/is_reply/is_quote flags, conversation ids, the author's id/username/name/followers_count/verification, and the quoted or retweeted tweet's id/url/author username. The preset trims what it recognises and leaves alone what it would empty, so it never turns a body into {}. Combine with fields to add paths on top of the preset. Typically cuts a tweet page by 70 to 90 percent for LLM tool callers.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/user/user_about/batch?usernames=stripe%2Cnasa%2Copenai&user_ids=44196397%2C11348282&fields=id%2Ctext%2Ccreated_at%2Cauthor.username&compact=1"{ "requested": 3, "served": 1, "billed_items": 2, "results": [ { "username": "stripe", "about": { "id": "102812444", "username": "stripe", "name": "Stripe", "verified_type": "Business", "professional_type": "Business", "account_based_in": "United States", "created_via": "Web", "username_changes": { "count": 0, "last_changed_at": null }, "created_country_accurate": true } }, { "username": "no_such_handle", "error": "not_found" }, { "username": "nasa", "error": "rate_limited" } ]}{ "error": "bad_request", "message": "Provide `usernames` or `user_ids`, not both."}{ "error": "unauthorized", "message": "Missing or invalid x-api-key header."}{ "error": "insufficient_credits", "message": "Not enough credits for 3 items. Top up, or send a smaller batch."}{ "error": "batch_in_progress", "message": "One batch per API key at a time. Retry when the running batch returns. Not billed."}{ "error": "upstream_unavailable", "message": "No item could be fetched right now. This is temporary; retry shortly."}Pricing
| Unit | Price |
|---|---|
| Per billed item | $0.0008 |
| Per 1,000 billed items | $0.80 |
Billed per item, not per call: each account X answered for costs $0.0008, whether it was found or confirmed not_found, so a 100-item batch costs at most $0.08. Items X refused (forbidden) and items that failed on our side (rate_limited, unavailable) are free. The balance is checked for every item before any lookup starts, so a key that cannot cover the whole list gets a 402 and nothing is fetched or billed.
When to use
Use it when you need About data for many accounts at once, for example checking which of 80 shortlisted creators are based in the United States. For a single account, call User About.
Related endpoints
- User About: Fetch a profile's extended About / professional details.
- User Info by Username: Fetch a full profile by @handle.
- User Info by ID: Fetch a full profile by numeric user ID.
FAQ
How many accounts can one request read?
Up to 100. Duplicates are removed first (handles compare case-insensitively, and a leading @ is ignored), so the limit applies to distinct accounts. More than 100 distinct entries, or a malformed entry, returns a 400 before any lookup runs.
Am I billed for accounts that do not exist?
Yes. A confirmed not_found is an answer from X, so it is billed at $0.0008 like a found account. Items X refused (forbidden) and items that failed on our side (rate_limited, unavailable) are not billed. billed_items in the response tells you exactly how many items the call charged.
What happens if every lookup fails?
When nothing was answered and every failure was temporary (rate_limited or unavailable), the API returns a 503 with a Retry-After header of 5 seconds and bills nothing. Otherwise it returns 200 with an error code on each item that failed, so retry only those items.
Can I mix usernames and user IDs?
No. Send either usernames or user_ids in one request, never both. Each ID is resolved to its current handle and then looked up, and the result is keyed by the ID exactly as you sent it.
How do fields and compact work on a batch?
They apply inside each item's about object, exactly as on User About: fields=account_based_in or fields=about.account_based_in keeps that field. A path that starts with results matches nothing and returns about: {} (still billed). requested, served, billed_items and each item's username, user_id or error are never trimmed.
What do the 429 and 503 errors mean here?
A 429 with error batch_in_progress means a batch on the same API key is still running; it carries a Retry-After header of 5 seconds and is not billed. The per-key rate limit is also a 429. A 503 with error upstream_unavailable means nothing could be fetched (Retry-After 5 seconds); a 503 with error billing_unavailable means the balance check could not run. Nothing is looked up or billed on either 503.
Can I run several batches at once?
One batch per API key runs at a time. A second batch sent while the first is still running gets a 429 with error batch_in_progress and is not billed, so send the next batch when the previous one returns. Items a batch did not start (it stops early after repeated upstream failures, a long run, or a disconnect) come back as unavailable, are not billed, and are safe to retry.
User Status GET
Return the liveness state of a handle: alive, suspended, not_found, or unavailable. Every outcome is an HTTP 200 and the caller branches on the status field. This exists because a standard profile lookup collapses suspended, deleted, and never-existed into one indistinguishable 404. Cost: $0.0008 per call.
Check Follow Relationship Batch GET
Check the directional relationship between one fixed account and up to 100 others in one request: one source against up to 100 targets, or one target against up to 100 sources. Each item carries the same relationship object GET /user/check_follow_relationship returns, read from the source's side: whether the source follows the target (following) and the target follows the source (followed_by), plus block, mute, and DM-eligibility flags. Results come back in request order, each with its relationship object or an error code. Cost: $0.0008 per billed item.