# ReadX — X/Twitter JSON API > A clean, read-only JSON mirror of X/Twitter — profiles, timelines, tweets, search, lists, followers and following. No API keys and no signup: each call is paid per request straight from an agent's own wallet (default $0.01 in USDC), via [x402](https://x402.org) at `readx.sh`. ## How to use it - Every endpoint is a `GET` under `/api` at `https://readx.sh/api/…`, paid via **x402**. No payment returns HTTP `402` + a `PAYMENT-REQUIRED` header; rails are USDC on Base or Solana. - Responses are `{ "code": 0, "data": ..., "pagination": ... }` on success (`pagination` present whenever the endpoint paginates) and `{ "code": -1, "error", "error_type" }` on error. - Paginate any endpoint by passing a response's `pagination.next_cursor` back as `?cursor=` until `pagination.has_more` is false. (The conversation endpoint, `GET /api/{name}/tweets/{id}`, is the one exception — it carries its own nested `before`/`after`/`replies` cursors instead.) ## Machine-readable contracts - [OpenAPI 3.1 spec](https://readx.sh/openapi.json): the canonical description of every `/api` endpoint, schema, and price (`x-payment-info`), advertising the `x402` protocol. - [Agent skill](https://readx.sh/skill.md): a drop-in skill file. Point an x402-capable agent at it and it learns every endpoint and the payment flow. - [A2A Agent Card](https://readx.sh/.well-known/agent-card.json): an [A2A](https://a2a-protocol.org) `AgentCard` listing every skill as a callable unit. Invoke over the `HTTP+JSON` transport: `POST /api/a2a/v1/message:send` with a `DataPart` naming a skill id + input, get back a `Task` with the result (`GET /api/a2a/v1/tasks/{id}` to re-fetch one, retained 10 minutes). Priced the same as any other call. ## Quick start - Set up as a skill: `Set up ReadX at https://readx.sh/skill.md with x402` - One call over x402: `npx agentcash fetch https://readx.sh/api/jack/profile` ## Key endpoints - `GET /api/{name}/profile` — user object, photo rail, pinned tweet - `GET /api/{name}/followers` — a user's followers (~200/page; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/followers_web` — a user's followers as shown on the web (~70/page, capped at ~800; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/following` — accounts a user follows (~200/page; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/following_web` — accounts a user follows as shown on the web (~70/page, capped at ~800; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/verified_followers` — a user's verified followers (~200/page; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/mentions` — tweets that mention a user (paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/media` — a user's tweets that contain media (~20/page; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/tweets_complete` — a user's recent tweets and replies with self-threads expanded (~40/page; dedupe by tweet `id` across pages; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/{name}/affiliates` — accounts affiliated with a user (e.g. an org's members) - `GET /api/{name}/relations?name=...` — whether `{name}` follows `name` (plus block/mute/DM flags) - `GET /api/{name}/info` — profile info (id, bio, location, follower/following counts, verification) - `GET /api/{name}/status` — account status: alive, suspended, not_found, or unavailable (always 200; `id` set when alive) - `GET /api/{name}` — user timeline (first page includes `data.pinned`; also `/with_replies`, `/with_media` — `/with_media` may omit `pinned`) - `GET /api/{name}/tweets/{id}` — a tweet and its conversation (or `/api/tweets/{id}` for just the tweet) - `GET /api/{name}/tweets/{id}/history` — a tweet's edit history (latest plus prior versions) - `GET /api/tweets/{id}/replies` — replies to a tweet (paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/tweets/{id}/retweeters` — accounts that retweeted a tweet (paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/tweets/{id}/thread` — the author's full self-thread from any tweet in it, root first (one response; `complete` is false if only partially retrieved) - `GET /api/search?q=...` — tweet search (a leading `@` or `f:user` returns users) - `GET /api/search/users?q=...` — user search (paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/search/tweets?q=...` — tweet search (optional `product`; paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/lists/{id}/members` — the members of a List by id (paginate with `?cursor=` + `pagination.next_cursor`) - `GET /api/trends?country=...` — trending topics for a location (worldwide by default; or `?woeid=...`) - `GET /api/trends/locations` — every location trends are available for (worldwide, countries, cities), with its `woeid` - `GET /api/spaces/{id}` — a Space's metadata (title, host, state, listener counts, downloadable) - `GET /api/communities/{id}` — a Community's metadata (name, description, member/moderator counts, rules, topic, admin, creator) - `GET /api/articles/{id}` — an X article by wrapper tweet id (public) - `GET /api/article-entities/{article_id}?auth_token=…` — an X article by entity rest_id (owner-only) - `GET /api/tools/get_user_id?username=...` — resolve an @handle to a numeric user id - `GET /api/tools/get_user_ids?usernames=...` — resolve up to 20 @handles to user ids (map; null on per-handle failure) - `GET /api/tools/get_username?user_id=...` — resolve a numeric user id to a username - `GET /api/tools/get_usernames?user_ids=...` — resolve up to 20 user ids to @usernames (map; null on per-id failure)