Poll & Results
GET /v1/ask/:id polls a natural-language ask: processing, completed with a cited markdown answer, structured citations, verification verdict, and usage, or error.
GET /v1/ask/:id polls an ask started with [POST /v1/ask](post-ask). Poll roughly every 2 seconds: turns settle in 10 to 60 seconds, so a 2-second interval finds the answer promptly without wasted requests. Polling is metered under the general read namespace, not the ask namespace, so a polling loop never consumes your daily ask budget. The endpoint is tenant-isolated: an ask_id created by another workspace returns 404, exactly as if it never existed.
The response is one of three shapes, discriminated by status. While the turn runs you get the minimal processing body: ask_id, status, and poll_url. When the turn settles successfully, status is completed and the body carries the full result: the answer, the structured citations, the verification verdict, and usage. When the turn fails, status is error with a stable error code and a human-readable message.
Endpoint
/v1/ask/:idPath parameters
Polling loop (bash)
The completed payload
Response fields (completed)
Response (completed)
{
"ask_id": "7c2f0a4e-9d31-4b8a-b3e6-2f1c5d9a8e07",
"status": "completed",
"poll_url": "/v1/ask/7c2f0a4e-9d31-4b8a-b3e6-2f1c5d9a8e07",
"answer": "The Acme master services agreement has a total contract value of [EUR 96,000](https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?cite=contract_value) over a [24-month term](https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?cite=contract_term).",
"citations": [
{
"quote": "EUR 96,000",
"document_id": "1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"kind": "field",
"reference": "contract_value",
"app_url": "https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?cite=contract_value"
},
{
"quote": "24-month term",
"document_id": "1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"kind": "field",
"reference": "contract_term",
"app_url": "https://app.talonic.com/documents/1b6f2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d?cite=contract_term"
}
],
"verification": {
"verdict": "supported",
"checks_total": 3,
"checks_unsupported": 0
},
"usage": {
"tokens": 18432,
"credits_charged": 100
}
}The answer field is ready to render as-is in any markdown surface: chat UIs, Slack, a support console. Because the inline citation links and the structured citations array describe the same evidence, you can also strip the links and render your own citation affordances from the array; the two are guaranteed to agree since the array is parsed from the answer itself.
A typed client
TypeScript polling helper
Error turns and error responses
A turn that fails internally settles to an error turn, delivered with HTTP 200 and status: "error" in the body, because the poll itself succeeded. The body carries error: "ask_failed" and a message. The right handling is to submit the question again as a fresh ask: turns are independent, and the failed turn does not poison anything. Distinguish this from HTTP-level errors on the poll request itself, which mean the request never reached a turn.
Response (error turn)
{
"ask_id": "7c2f0a4e-9d31-4b8a-b3e6-2f1c5d9a8e07",
"status": "error",
"poll_url": "/v1/ask/7c2f0a4e-9d31-4b8a-b3e6-2f1c5d9a8e07",
"error": "ask_failed",
"message": "The agent turn failed. Ask again; the question was not charged twice."
}HTTP error responses