Skip to main content

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

GET/v1/ask/:id

Path parameters

id*uuidThe ask_id returned by POST /v1/ask.

Polling loop (bash)

The completed payload

Response fields (completed)

ask_iduuidThe ask id.
statusstringprocessing, completed, or error.
poll_urlstringRelative URL of this endpoint, echoed for convenience.
answerstringThe answer as markdown. Citations appear inline as markdown links whose targets deep-link into the Talonic app with the source span highlighted.
citationsarrayThe same citations in structured form: quote, document_id, kind, reference, app_url. See Citations & Verification.
verificationobject | nullPost-answer verification verdict: verdict (supported / issues / unverifiable), checks_total, checks_unsupported, and an optional correction. null when the turn produced no verdict.
usage.tokensinteger | nullTotal LLM tokens the turn consumed, for transparency. Not billed per token.
usage.credits_chargedintegerThe flat charge for this ask: 100 credits.

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

400validation_errorThe id is not a UUID.
401unauthorizedMissing or invalid API key.
404not_foundNo ask with this id exists in your workspace. Cross-tenant ids also read as 404.
There is no result expiry race to worry about: keep the ask_id and fetch the completed payload whenever convenient. The poll is a plain read, so it is safe to poll from multiple consumers.