> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tako.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Agent

export const CodingAgentCTA = ({description, href}) => <p className="mt-2 text-lg prose prose-gray dark:prose-invert [&>*]:[overflow-wrap:anywhere]">
    {description} Building with a coding agent?{" "}
    <a href={href}>Give your agent the full reference →</a>
  </p>;

export const PlaygroundButton = ({href = "https://tako.com/playground", label = "Try in Playground"}) => <div className="float-right not-prose ml-4 -mt-12">
    <a href={href} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1.5 rounded-full border border-gray-200 dark:border-white/15 bg-white dark:bg-white/5 px-3 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-200 no-underline transition-colors hover:border-gray-300 hover:bg-gray-50 dark:hover:bg-white/10">
      <svg viewBox="0 0 24 24" aria-hidden="true" className="h-3.5 w-3.5 fill-current">
        <path d="M8 5v14l11-7z" />
      </svg>
      {label}
    </a>
  </div>;

<CodingAgentCTA description="A data-retrieval agent that runs multi-step research and returns schema-defined structured data outputs and visualization cards." href="/documentation/integrating-tako/agent/for-coding-agent" />

## Capabilities

The **Search Agent** is a data-retrieval agent that returns **schema-defined structured data outputs and visualization cards**. Hand it a question that needs real retrieval work — resolving a cohort, ranking or filtering a set, multi-hop aggregation — and it researches Tako's curated knowledge graph and the live web, then returns exactly the shape you asked for.

<CardGroup cols={1}>
  <Card title="Structured data out" icon="table">
    Define an `output_schema` (JSON Schema) and the agent fills it: synthesized scalar fields plus **dataset slots** (`x-tako-dataset`) populated with the exact retrieved rows. Get machine-usable JSON, not prose you have to parse.
  </Card>

  <Card title="Visualization cards" icon="chart-column">
    Every run may also build Tako `cards` — interactive knowledge cards with their sources and methodology — ready to embed alongside the data. On by default; suppress with `cards: false`.
  </Card>

  <Card title="Grounded and citable" icon="circle-check">
    The agent draws on Tako's curated, structured data and the live web. The written `answer` carries `[n]` markers that join a top-level `citations` registry covering both, so every claim is attributable.
  </Card>

  <Card title="Asynchronous and long-running" icon="clock">
    Dispatch a run, then poll or stream it to completion (a run can take minutes) — real multi-step work in the background instead of racing a single call.
  </Card>
</CardGroup>

For a specific, known value, time series, or direct comparison, use one-shot [Search](/documentation/integrating-tako/search/overview) instead — it returns in one fast call. For a written, synthesized answer rather than structured data, use the [Answer Agent](/documentation/integrating-tako/agent/answer).

## Example

<PlaygroundButton href="https://tako.com/console/playground/agent/search" />

Dispatch a run, then poll `GET /v1/agent/search/runs/{run_id}` until `status` is `completed` or `failed`:

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    # 1. Dispatch — returns 202 with a SearchAgentRun: {"run_id": "...", "status": "queued"}.
    curl -X POST https://tako.com/api/v1/agent/search/runs \
      -H "X-API-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "query": "Largest US semiconductor companies by 2024 revenue and YoY growth"
      }'

    # 2. Poll with the run_id until status is "completed" or "failed".
    curl https://tako.com/api/v1/agent/search/runs/RUN_ID \
      -H "X-API-Key: YOUR_API_KEY"
    ```
  </Tab>

  <Tab title="Python">
    ```bash theme={null}
    pip install tako-sdk
    ```

    ```python theme={null}
    import os
    import time

    from tako import Configuration
    from tako.lib import Tako
    from tako.models.search_agent_run_request import SearchAgentRunRequest

    config = Configuration()
    config.api_key["apiKey"] = os.environ["TAKO_API_KEY"]
    client = Tako(config)

    run = client.agent.search.run(
        SearchAgentRunRequest(query="Largest US semiconductor companies by 2024 revenue and YoY growth")
    )

    # Runs can take minutes — poll on a short interval until terminal.
    while run.status not in ("completed", "failed"):
        time.sleep(3)
        run = client.agent.search.get(run.run_id)

    if run.status == "completed":
        print(run.result.answer)
        for card in run.result.cards or []:
            print(card.title, card.webpage_url)
    ```
  </Tab>
</Tabs>

<Accordion title="Example API Response">
  <p>
    A completed run. `result.answer` is markdown with `[n]` citation markers; `result.citations` is the registry those markers join; `result.cards[0]` is the lead card.
  </p>

  ```json theme={null}
  {
    "run_id": "run_8sKd2m1f0aQ",
    "object": "agent.run",
    "thread_id": "1f0e9c34-2b7a-4f0a-9c2e-7b1a2c3d4e5f",
    "status": "completed",
    "created_at": "2026-06-22T18:04:11+00:00",
    "completed_at": "2026-06-22T18:06:48+00:00",
    "result": {
      "answer": "Nvidia led the largest US semiconductor companies with about $60.9B in FY2024 revenue (+126% YoY), ahead of Broadcom and AMD [1][2].",
      "cards": [
        {
          "card_id": "mA-C6b48zxyU3G33JJdO",
          "title": "US Semiconductor Revenue, FY2024",
          "webpage_url": "https://tako.com/card/mA-C6b48zxyU3G33JJdO/",
          "image_url": "https://tako.com/api/v1/image/mA-C6b48zxyU3G33JJdO/",
          "embed_url": "https://tako.com/embed/mA-C6b48zxyU3G33JJdO/",
          "source_indexes": ["data"]
        }
      ],
      "citations": [
        {
          "index": 1,
          "title": "US Semiconductor Revenue, FY2024",
          "source_name": "Company Filings (10-K)",
          "source_index": "data"
        }
      ],
      "structured_output": null,
      "request_id": "f20f965b-6bbd-40df-b50b-a8861f34df24"
    },
    "error": null
  }
  ```
</Accordion>

## Structured outputs

Pass an `output_schema` (a JSON Schema) to get machine-usable JSON back in `result.structured_output`. Two kinds of field:

* **Synthesized fields** — ordinary schema properties the agent writes (a headline, a count, a boolean).
* **Dataset slots** — a property marked `"x-tako-dataset": true`, filled with the **exact retrieved rows** as a `TakoDataset`. A slot node carries only `x-tako-dataset`, an optional `description`, and an optional `columns` hint — no `type`.

```json theme={null}
{
  "type": "object",
  "properties": {
    "summary": { "type": "string", "description": "One-sentence summary of the finding." },
    "companies": {
      "x-tako-dataset": true,
      "description": "The companies with their revenue and growth, as a table.",
      "columns": ["company", "revenue_usd", "yoy_growth_pct"]
    }
  },
  "required": ["summary"]
}
```

The supported subset is `object` / `array` / `string` / `number` / `integer` / `boolean`, plus `enum`, `required`, and `description`. Caps: 16 KB, depth 5, 64 properties, 4 dataset slots. A schema outside these bounds returns `400 output_schema_invalid`.

The SDK ships two helpers for consuming the result — `derive_response_schema()` (the schema `structured_output` actually validates against, with each slot as `TakoDataset | null`) and `TakoDatasetView` (a records / DataFrame view over a filled slot):

```python theme={null}
import jsonschema
from tako.lib import Tako, TakoDatasetView, derive_response_schema
from tako.models.search_agent_run_request import SearchAgentRunRequest

schema = {
    "type": "object",
    "properties": {
        "summary": {"type": "string"},
        "companies": {"x-tako-dataset": True, "columns": ["company", "revenue_usd", "yoy_growth_pct"]},
    },
    "required": ["summary"],
}

run = client.agent.search.run(
    SearchAgentRunRequest(query="Largest US semiconductor companies by 2024 revenue", output_schema=schema)
)
run = client.agent.search.get(run.run_id)  # poll to a terminal status

if run.result and run.result.structured_output:
    jsonschema.validate(run.result.structured_output, derive_response_schema(schema))
    view = TakoDatasetView(run.result.structured_output["companies"])
    print(view.records)          # list[dict], one per row
    print(view.to_dataframe())   # typed pandas DataFrame (needs tako-sdk[pandas])
```

<Note>
  When the request carries an `output_schema`, the result adds `structured_output_status` (`complete` / `partial` / `failed`) and, for `partial` runs, `unfilled_fields` — the dot-separated paths of dataset slots the agent honestly couldn't fill. `structured_output_citations` maps field paths back to the same `[n]` citation index space as the answer.
</Note>

## Choosing sources

`source_indexes` controls where the agent researches. It defaults to `["data", "web"]` — both — so pass it only to **restrict**:

* `["data", "web"]` (default) — Tako's curated knowledge graph **and** the live web.
* `["data"]` — the curated knowledge graph only.
* `["web"]` — the live web only.

The legacy value `"tako"` is accepted as a synonym for `"data"`.

## Continue a thread

Each run belongs to a thread. Pass a prior run's `thread_id` to ask a follow-up in the same conversation:

```python theme={null}
follow_up = client.agent.search.run(
    SearchAgentRunRequest(query="Now break the leader's revenue down by segment", thread_id=run.thread_id)
)
```

Omit `thread_id` to start a fresh thread. A thread is pinned to one agent product and one set of `source_indexes`.

## Stream live progress

To show progress while the agent works, stream the run over Server-Sent Events instead of polling — send `Accept: text/event-stream` on dispatch. `client.agent.search.stream()` yields `SearchAgentStreamEnvelope` events; the terminal `agent_result` event carries the same `SearchAgentResult` you'd get from polling. See the [coding-agent reference](/documentation/integrating-tako/agent/for-coding-agent#stream-live-progress-sse) for the full event taxonomy and resume semantics.

<Check>
  Stream for live progress in interactive UIs; poll for simple server-to-server flows. Both return the same `SearchAgentResult` when the run completes.
</Check>
