The two agents
Both agents share one lifecycle — dispatch a run, then poll or stream to a terminal status — and one request shape. They differ only in what the result carries.
Reach for an agent when a question needs figuring out rather than retrieving a known value — resolving a cohort (“which companies match…”), ranking or filtering a set by criteria, or multi-hop aggregation. For a specific, known value, time series, or direct comparison, use one-shot Search or Answer instead — one fast, synchronous call.
A run is asynchronous and long-running (it can take minutes): you dispatch a run, then poll it — or stream it — until it reaches a terminal status.
- Base URL:
https://tako.com/api/ - Auth: send your API key in the
X-API-Keyrequest header (not a bearer token). Create a key in the Tako console. - Dispatch:
POST /v1/agent/{retrieval,answer}/runs→202with a run object (status: "queued"). - Poll:
GET /v1/agent/{retrieval,answer}/runs/{run_id}untilstatusiscompletedorfailed. - List:
GET /v1/agent/{retrieval,answer}/runsreturns the caller’s runs, newest first.
Install
Dispatch and poll
Dispatch returns immediately with arun_id; poll until the run is terminal. The example uses the Retrieval Agent — the Answer Agent is identical with client.agent.answer.* and the /v1/agent/answer/runs path.
Stream live progress (SSE)
To show progress while an agent works, stream the run over Server-Sent Events instead of polling. SendAccept: text/event-stream on dispatch (or on the poll endpoint to resume). client.agent.retrieval.stream() / client.agent.answer.stream() yield per-product envelope events (RetrievalAgentStreamEnvelope / AnswerAgentStreamEnvelope); the terminal agent_result event carries the same result you’d get from polling.
Stream event kinds
block.kind is one of thirteen public kinds. Fields marked (opt) may be absent.
The stream terminates at
stream_done. The structured result arrives in the terminal agent_result event, whose data is the per-product result — the same result you’d get from polling.
seq is a monotonic resume cursor, but values are not contiguous — the public stream omits internal events, so gaps are expected. If a stream drops, reconnect and pass the last seq you saw as starting_after (or the Last-Event-ID header) when reading GET /v1/agent/{retrieval,answer}/runs/{run_id} with Accept: text/event-stream.Request parameters
Both dispatch bodies share these parameters. Onlyquery is required.
The Retrieval Agent accepts two additional parameters:
The Answer Agent takes no
cards or output_schema — its contract is frozen to answer + cards + citations + metadata.
Structured output (Retrieval Agent)
Pass anoutput_schema (JSON Schema) to shape the response into machine-usable JSON in result.structured_output. Two kinds of field:
- Synthesized fields — ordinary schema properties the agent writes.
- Dataset slots — a property marked
"x-tako-dataset": true, filled with the exact retrieved rows as aTakoDataset. A slot node carries onlyx-tako-dataset, an optionaldescription, and an optionalcolumnshint — notype.
object / array / string / number / integer / boolean, plus enum, required, description. Caps: 16 KB, depth 5, 64 properties, 4 dataset slots. A schema outside these bounds returns 400 output_schema_invalid.
output_schema is supplied, the result adds:
Run lifecycle and result shape
Dispatch and poll both return the run object (RetrievalAgentRun or AnswerAgentRun):
The
result shape depends on the agent:
RetrievalAgentResult—answer(markdown with[n]markers),cards[],citations[],metadata,request_id, plus thestructured_output*fields above whenoutput_schemawas supplied.AnswerAgentResult—answer,cards[],citations[],metadata,request_id. Nostructured_output, no inline data, noweb_results— ever. Prose-only (emptycards) is legitimate.
citations is a single top-level registry the answer’s [n] markers join. Each entry has index and title; the agents populate source_index (data | web), and the Retrieval Agent additionally fills excerpt / publish_date for web sources.
There is no
web_results field. Web and Tako sources alike land in the unified top-level citations registry.List past runs
GET /v1/agent/{retrieval,answer}/runs returns the caller’s runs for that agent, newest first, as a list envelope: { "object": "list", "data": [ … ], "has_more": bool, "next_cursor": string | null }. Each item is a trimmed run summary (run_id, status, created_at, completed_at, thread_id, usage) — fetch full detail via the poll endpoint. Paginate with cursor (the prior response’s next_cursor) and limit (default 20, max 100).
When to use which
- Retrieval Agent — when you want machine-usable structured data out. Define an
output_schema; get synthesized fields plus dataset slots of exact rows, alongside cards. Ideal for feeding a database, table, or downstream code. - Answer Agent — when you want a written, citation-backed answer synthesized from everything the agent found, with the cards that support it. Ideal for a chat reply or a briefing.
- Neither — for a specific, known value, time series, or direct comparison, don’t dispatch a run. One-shot Answer (prose) or Search (raw cards) returns it in one fast, synchronous call.
Common mistakes
Errors
Failures return anErrorObject body: { "code": "...", "message": "..." }.