Grok API for X | Ask Grok and Get Cited Sources
Send a prompt to X's in-app Grok as the account behind your session and get back one complete JSON document: the answer text, the web pages Grok cited while writing it, and the searches it ran to find them. Grok reads X in real time, so it answers about posts and accounts a general-purpose model has never seen. Send a bare post URL as the message and you get a structured summary of that post instead, including what Grok reads out of its attached images. Billed at $0.0040 per answer. Cost: $0.0040 per call.
POST grok/chat sends a prompt to X's own Grok as the account behind your session and returns one buffered JSON reply: the answer text, citations as an array of url, domain, title and snippet, the tool calls Grok ran, and the model that actually answered. It is stateless, so prior turns travel in messages[]. $0.0040 per answer.
Authorization
bearerAuth Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/grok/chat" \ -H "Content-Type: application/json" \ -d '{}'{ "ok": true, "conversation_id": "2088999211077345534", "response_id": "2089001859230978049", "user_response_id": "2089001859230978048", "answer": "Reaction on X is running positive on the on-device model work and negative on the pricing. The liveblog thread and several developer accounts flag the new background-execution API as the change most people expect to ship against first.", "citations": [ { "url": "https://x.com/verge/status/2089000000000000001", "domain": "x.com", "title": "The Verge on X", "snippet": "Everything announced in the keynote, in order." }, { "url": "https://www.theverge.com/wwdc-keynote-liveblog", "domain": "theverge.com", "title": "WWDC keynote liveblog", "snippet": "Live updates as the keynote runs." }, { "url": "https://news.ycombinator.com/item?id=41234567", "domain": "news.ycombinator.com", "title": null, "snippet": "Developer discussion of the background-execution API." } ], "citation_count": 3, "tool_calls": [ { "id": "5f2b8c1a-9d34-4c77-b0e2-6a1f7c3d8e90", "tool": "web_search", "args": { "query": "WWDC keynote reaction developers", "num_results": "15" } } ], "requested_model": "grok-4-auto", "model": "grok-4", "mode": "auto"}{ "error": "bad_request", "message": "Missing or malformed parameter. Fix the request before retrying."}{ "error": "unauthorized", "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}{ "error": "insufficient_credits", "message": "Your balance is exhausted. Top up your credits to continue."}{ "error": "forbidden", "message": "The acting account is not authorized for this write action, or has no logged-in session."}{ "error": "not_found", "message": "The resource does not exist, for example a deleted tweet or a private account."}{ "error": "rate_limited", "message": "Too many requests. Back off and retry with exponential backoff."}{ "error": "server_error", "message": "Something failed on our side. Retry with backoff; if it persists, contact support."}Pricing
| Unit | Price |
|---|---|
| Per call | $0.0040 |
| Per 1,000 calls | $4.00 |
One $0.0040 call per answer, however much Grok read to write it: a reply citing thirty pages across three searches costs the same as one citing none. A call we cannot read an answer out of returns 422 and is not billed.
When to use
Reach for this when the question needs what X knows right now: what an account has been posting, how a launch is landing, or which pages get cited when someone asks an answer engine about your category. Pass a post URL instead of a question to summarise that single post. Call Grok Config first to confirm the account can use Grok at all. If you want structured post data with no model in the middle, use Advanced Tweet Search instead.
Notes
- [VERIFY] Request and response shapes come from two live operator captures of X's own Grok client (2026-08-16), request side and streamed response side. The route had not been exercised end-to-end through a customer key when these docs were written. Three things resolve on the first live call and are instrumented to be captured rather than swallowed: whether GrokHome needs a features param, whether omitting response_id on a replayed turn is accepted, and any messageTag the stream assembler has not been shown.
- PRICING IS PROVISIONAL. Neither grok slug is enumerated in billing/src/config/endpoint-costs.json, so computeCost() falls back to the standard read rate of $0.0040 for what is an LLM inference call. A dedicated tier decision is open on the backend side; this page must be updated in the same pass as that change.
- Needs a session for the account you are asking as: either register one once (POST /customer/session), or pass per-call inline credentials as x-auth-token and x-ct0 request headers, which let a single API key act as many accounts. Returns 409 session_required if neither is supplied, 401 session_dead when the session has expired.
- The upstream stream is newline-delimited JSON on grok.x.com, not GraphQL and not SSE. We consume the whole stream server-side and hand back one document, so there is no partial or incremental read path on this endpoint today.
- We never fabricate a response_id for a replayed turn. If you supply a prior turn without one, the key is omitted rather than filled with a synthesized id.
Related endpoints
- Grok Config: Check whether your account can use Grok, and which models it may pick.
- Advanced Tweet Search: Search tweets with Twitter's full query-operator syntax, paginated with cursors.
- Register Session: Register your auth_token and ct0 cookies once so every write and private read acts as your account, or pass them per call as x-auth-token / x-ct0 headers.
FAQ
Is the response streamed?
No. It is buffered. X streams the answer to its own client as newline-delimited JSON, and we consume that stream server-side and return one complete JSON document. That is a deliberate choice rather than a gap: it matches every other endpoint here and keeps billing and caching simple. If you need token-by-token output, say so and we will look at adding it behind an Accept header.
Do you store my prompts or Grok's answers?
No. The endpoint is stateless. There is no conversation table, no retention policy, and no prompt or answer text in our database. Our usage log records the endpoint name, the status code and a result count, exactly as it does for every other call. To continue a conversation you pass conversation_id and the prior turns back yourself in messages[], which is why that parameter exists.
Why does model come back different from what I asked for?
Because auto resolves on X's side. Ask for grok-4-auto and X commonly answers with grok-4. requested_model is what we asked for and model is what actually produced the text, so read model when you care.
Some citations have no title. Is that a bug?
No. X omits title on some cited pages and sends only url and snippet. We pass through what arrived rather than dropping the entry or inventing a title, so treat title as optional and key on url.
Why did I get more citations than the answer seems to reference?
One answer can run several searches. A single reply in the reference capture made three web_search calls returning 15, 10 and 5 results. Every one of them counts as a source Grok read, so all are returned, merged in arrival order and de-duplicated by url. Read tool_calls to see which query produced them.
What is a 422 on this endpoint?
It means X answered but we could not read an answer out of the stream, for example a refusal or an upstream shape change. You are not billed for it and the raw upstream body is recorded on our side so the cause gets fixed. It exists so a broken call never reaches you as a successful, empty answer.
Can I just send a post URL?
Yes, that is a first-class use. Put the status URL in message with no other text and Grok returns a structured summary of that post, including detail read out of images attached to it.
Overview
Grok: Ask X's own in-app Grok a question and get the answer back with the pages it cited. Grok reads X in real time, so it answers about posts and accounts a general model has never seen. Runs as your account, returns one buffered JSON document rather than a stream, and stores nothing: you pass prior turns back yourself.
Grok Config GET
Read the Grok settings for the account behind your session: whether X has enabled Grok for it, the reasons if not, and the model options it is allowed to choose between. Grok eligibility belongs to the X account rather than to us, so this runs as your session and not off our pool. Call it once before your first chat request. Billed at $0.0008 per call. Cost: $0.0008 per call.