Batch reads
Up to 100 profiles or tweets in one request.
Two endpoints take a list instead of one handle or id. They cost the same per object as the single endpoints, answer in one round trip, and never charge for an input that returned nothing.
| Endpoint | Input | Max | Credits |
|---|---|---|---|
POST /v1/users/batch | handles | 100 | 1 per profile found |
POST /v1/tweets/batch | ids | 100 | 1 per tweet found |
Both also accept GET with a comma list: /v1/users/batch?handles=x,github,vercel.
Request
curl -X POST https://api.xdataapi.io/v1/users/batch \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d '{"handles": ["x", "github", "nobody_here_12345"]}'{
"data": [
{ "id": "783214", "handle": "X", "followers": 60738793, "...": "..." },
{ "id": "13334762", "handle": "github", "followers": 2900000, "...": "..." }
],
"errors": [
{ "input": "nobody_here_12345", "code": "not_found", "message": "no user" }
],
"items": 2,
"credits_charged": 2,
"balance_remaining": 4998,
"cache": "miss",
"cache_hits": 0,
"request_id": "3d4f3d1c-..."
}Rules
dataholds the objects that were found, in input order. Every input that returned nothing is inerrorswith acode:not_found,access_denied,upstream_error, orno_credits.- Duplicates are folded.
@xandXare the same handle. - The cache is shared with the single endpoints. An object read in the last 10 minutes (profiles) or 5 minutes
(tweets) is served from cache at half price;
cache_hitssays how many, andcacheismixedwhen a batch has both. - When the balance covers only part of the list, the API fetches what it can pay for and returns the rest as
no_credits. Send those again after a top-up. - When nothing is found and every failure is transient, the answer is
503withretry-after, and nothing is charged. fresh=truebypasses the cache for the whole list, at 2x.
Batch by numeric user id is not available yet. Resolve ids through /v1/users/{id}/tweets?count=20 or ask
hello@xdataapi.io if you need it.