TwitterAPIs Docs
API ReferenceGrok

Grok Chat Result API | Poll an Async Grok Answer

Poll a job POST /twitter/grok/chat/submit started. While it runs you get a 202 with status pending and poll_after_seconds. When it finishes you get a 200 with exactly the body POST /twitter/grok/chat returns plus job_id and status done, and the fields projection works on it. If the chat failed you get the status and typed error grok/chat would have answered, plus job_id and status failed; 504 job_timeout and 503 job_interrupted mean the job did not finish on our side. An unknown job_id, a finished answer older than 15 minutes, or another key's job all return 404. The $0.0040 grok/chat price is charged once, on the first poll that delivers the finished answer; polling it again is free. Cost: Free per call.

GET grok/chat/result polls a job from grok/chat/submit. Pending answers 202 with poll_after_seconds. Done answers 200 with the grok/chat body plus job_id and status. The call is free, and $0.0040 is charged once, on the first poll that delivers the finished answer.

GET
/grok/chat/result

Authorization

bearerAuth
AuthorizationBearer <token>

Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.

In: header

Query Parameters

job_id*string

The job_id POST /twitter/grok/chat/submit returned, a UUID.

fields?string

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.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/grok/chat/result?job_id=5b0f6a52-3c7e-4f1a-9d2b-8e4c6a1f0b37&fields=id%2Ctext%2Ccreated_at%2Cauthor.username"
{  "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",  "job_id": "5b0f6a52-3c7e-4f1a-9d2b-8e4c6a1f0b37",  "status": "done"}
{  "job_id": "5b0f6a52-3c7e-4f1a-9d2b-8e4c6a1f0b37",  "status": "pending",  "poll_after_seconds": 3,  "created_at": "2026-11-04T18:02:11.482Z"}
{  "error": "bad_request",  "message": "`job_id` is required: the id POST /twitter/grok/chat/submit returned."}
{  "error": "unauthorized",  "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}
{  "error": "not_found",  "message": "No Grok job with this job_id for this API key. Finished results are kept for 900 seconds; submit again if it has expired."}
{  "error": "job_interrupted",  "message": "The service restarted while this Grok job was running. It was not charged. Submit it again."}
{  "error": "job_timeout",  "message": "This Grok job did not finish in time and was not charged. Submit it again."}

Pricing

UnitPrice
Per callFree

Polling is free. The $0.0040 grok/chat price is charged once, on the first poll that delivers a finished answer. Polling the same finished job again returns the same answer and charges nothing, and a pending or failed poll is never charged.

When to use

Call this after Grok Chat: Submit, waiting poll_after_seconds between polls, until you get anything other than a 202. It takes only the job_id and your API key. It sends no prompt of its own, and it cannot start a job.

Notes

  • pending answers 202 with poll_after_seconds and a Retry-After header. Poll again after that many seconds.
  • done answers 200 with the Grok Chat body plus job_id and status done. The fields projection works on it.
  • failed returns the status and typed error Grok Chat would have answered (for example 401, 403, 422, 429 or 502), plus job_id and status failed. A failed job is not charged.
  • 504 job_timeout means the job did not finish in time, and 503 job_interrupted means the service restarted while it ran. Neither is charged. Submit again.
  • 404 not_found covers an unknown job_id, a finished answer older than 15 minutes, and a job that belongs to another API key, so a job id cannot be used to probe someone else's jobs.
  • Grok Chat: Submit: Start a Grok chat in the background and get a job id to poll, for clients that time out before a long answer.
  • Grok Chat: Ask X's Grok a question and get the answer plus the pages it cited.
  • Grok Config: Check whether your account can use Grok, and which models it may pick.

FAQ

How often should I poll?

Wait the poll_after_seconds the last response gave you, which is 3 seconds. The Retry-After header on a 202 carries the same value. Stop on anything other than a 202.

Am I charged again if I poll a finished job twice?

No. Only the first poll that delivers the answer is charged $0.0040, and that charge is claimed atomically, so concurrent polls cannot charge twice. Later polls return the same answer for free until it expires.

What if I never collect the answer?

Then you are not charged. A finished answer is kept for 900 seconds, then deleted, and the charge only happens on delivery. After that, polling returns 404 and you submit again.

How do I tell a failed job from a failed poll?

Read status in the body. A failed job carries job_id and status failed beside the error. A 404 or a 401 with no job_id means the poll itself was refused, and the job's state is unchanged.

Was this page helpful?