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

# Deep Search

> Full reference for the start, status, query, export, and download endpoints for deep search.

## Use case

Turn natural language into a targeted list of people or companies — without manual prospecting. These endpoints let you submit a query, track progress asynchronously, and either browse results as paginated JSON or download them as a CSV.

<Card title="API Reference" icon="code" href="/api-reference/search/start-deep-search-async">
  See the full request/response schema and parameters in the API Reference.
</Card>

## Pricing

See [Credits & Pricing Guide](/guides/credits-and-pricing) for credit costs.

## Errors

For error responses (400, 403, 404, 409, 429, etc.), see [Handling Errors](/api-reference/errors).

***

## Start deep search

Submit a natural language query to start an agentic search. Returns a `task_id` for polling.

```http theme={null}
POST https://api.sixtyfour.ai/search/start-deep-search
```

### Example request

```json theme={null}
{
  "query": "VP of Engineering at Series B SaaS startups in New York",
  "mode": "people",
  "max_results": 500
}
```

<Tip>Save the `task_id` returned in the response — you'll need it to poll for status.</Tip>

<Note>Each organization can run up to 5 concurrent deep searches. Additional requests receive a 429 response until an in-flight search completes.</Note>

***

## Get search status

Poll for progress and results of a running or completed search.

```http theme={null}
GET https://api.sixtyfour.ai/search/status/{task_id}
```

`task_id` is the value returned by Start Deep Search or Export.

### Status values

| Status    | Description                                                                                                                       |
| --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| queued    | Search is waiting to start.                                                                                                       |
| running   | Search is actively running. Use `progress_message` and `iterations` to show progress.                                             |
| completed | Search finished. `resource_handle_id` is available for `"csv"` mode. `search_id` can be used with `/search/query` in either mode. |
| failed    | Search encountered an error — check the `error` field.                                                                            |

### Polling recommendations

* Poll every 10–15 seconds for active searches
* Stop polling when `status` is `completed` or `failed`
* Use `progress_message` to show users what the agent is currently doing

<Tip>Once `status` is `completed`, use `search_id` with `/search/query` for paginated JSON, or `resource_handle_id` with `/search/download` for the CSV.</Tip>

***

## Download search results

Get a signed URL to download the result CSV for a completed search.

```http theme={null}
GET https://api.sixtyfour.ai/search/download
```

Pass `resource_handle_id` (the value returned in the completed status response) as a query parameter.

<Note>The storage backend and URL format may vary. Use the `url` field in the response directly for downloading — it is always a valid signed URL regardless of the underlying storage provider.</Note>

<Warning>Signed URLs expire after 15 minutes (900 seconds). Download the file immediately or request a new URL before it expires.</Warning>

***

## Query search results

Browse results from a completed deep search as paginated JSON.

```http theme={null}
POST https://api.sixtyfour.ai/search/query
```

This endpoint is shared with filter search. Pass `search_id` to browse a completed deep search, or use `simple_filters`/`filters`/`parsed_query` for fresh searches. For pagination semantics, request flow, and the effective result cap, see [Filter Search → Search query](/api-reference/search/filter-search#search-query).

### Example: browse deep search results

```json theme={null}
{
  "search_id": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
  "page_size": 25
}
```

### Example: next page

```json theme={null}
{
  "cursor": "eyJpZCI6I..."
}
```

<Tip>Cursor requests must send only `{"cursor": "..."}`. Do not include `search_id`, `page_size`, or other fields.</Tip>

<Note>
  `/search/query` also accepts `exclude_entity_ids` and `exclude_list_ids` on the first request to suppress known people or companies from results. A `search_id` stores the query, not exclusions — pass exclusions again when browsing its results. See [Search Exclusions](/api-reference/search/search-exclusions).
</Note>

***

## Export search results

Generate a CSV from a completed search. Runs asynchronously — poll for status, then download.

```http theme={null}
POST https://api.sixtyfour.ai/search/export
```

Provide `search_id` to export an existing search, or `parsed_query` for a direct query (advanced) — not both.

### Export flow

1. POST to `/search/export` with `search_id` — receive `task_id`.
2. Poll `GET /search/status/{task_id}` until `completed` — response includes `resource_handle_id`.
3. Download via `GET /search/download?resource_handle_id=...`.

<Note>If an export is already in progress for the given `search_id`, the API returns 409. Poll the existing `task_id` instead of starting a new export.</Note>

***

## Example usage

<CodeGroup>
  ```bash cURL theme={null}
  # 1. Start a deep search
  curl -X POST "https://api.sixtyfour.ai/search/start-deep-search" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "VP of Engineering at Series B SaaS startups in New York",
      "mode": "people",
      "max_results": 500
    }'

  # 2. Poll for status (use task_id from step 1)
  curl -X GET "https://api.sixtyfour.ai/search/status/TASK_ID" \
    -H "x-api-key: YOUR_API_KEY"

  # 3. Download results (use resource_handle_id from step 2)
  curl -X GET "https://api.sixtyfour.ai/search/download?resource_handle_id=RESOURCE_HANDLE_ID" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests
  import time

  API_KEY = "YOUR_API_KEY"
  BASE_URL = "https://api.sixtyfour.ai"
  headers = {
      "x-api-key": API_KEY,
      "Content-Type": "application/json"
  }

  start_response = requests.post(
      f"{BASE_URL}/search/start-deep-search",
      headers=headers,
      json={
          "query": "VP of Engineering at Series B SaaS startups in New York",
          "mode": "people",
          "max_results": 500
      }
  )
  start_response.raise_for_status()
  task_id = start_response.json()["task_id"]
  print(f"Search started: {task_id}")

  while True:
      status_response = requests.get(
          f"{BASE_URL}/search/status/{task_id}",
          headers=headers
      )
      status_response.raise_for_status()
      status_data = status_response.json()

      print(f"Status: {status_data['status']} — {status_data.get('progress_message', '')}")

      if status_data["status"] == "completed":
          resource_handle_id = status_data["resource_handle_id"]
          print(f"Total results: {status_data['total_results']}")
          break
      elif status_data["status"] == "failed":
          raise RuntimeError(f"Search failed: {status_data.get('error')}")

      time.sleep(10)

  download_response = requests.get(
      f"{BASE_URL}/search/download",
      headers=headers,
      params={"resource_handle_id": resource_handle_id}
  )
  download_response.raise_for_status()
  download_url = download_response.json()["url"]
  print(f"Download URL: {download_url}")

  csv_response = requests.get(download_url)
  with open("search_results.csv", "wb") as f:
      f.write(csv_response.content)
  print("Results saved to search_results.csv")
  ```

  ```javascript JavaScript theme={null}
  const API_KEY = "YOUR_API_KEY";
  const BASE_URL = "https://api.sixtyfour.ai";
  const headers = { "x-api-key": API_KEY, "Content-Type": "application/json" };

  const startResponse = await fetch(`${BASE_URL}/search/start-deep-search`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      query: "VP of Engineering at Series B SaaS startups in New York",
      mode: "people",
      max_results: 500
    })
  });
  if (!startResponse.ok) throw new Error(`Failed to start: ${await startResponse.text()}`);
  const { task_id } = await startResponse.json();
  console.log(`Search started: ${task_id}`);

  let resourceHandleId;
  while (true) {
    const statusResponse = await fetch(
      `${BASE_URL}/search/status/${task_id}`,
      { headers }
    );
    const statusData = await statusResponse.json();

    console.log(`Status: ${statusData.status} — ${statusData.progress_message ?? ""}`);

    if (statusData.status === "completed") {
      resourceHandleId = statusData.resource_handle_id;
      console.log(`Total results: ${statusData.total_results}`);
      break;
    } else if (statusData.status === "failed") {
      throw new Error(`Search failed: ${statusData.error}`);
    }

    await new Promise((r) => setTimeout(r, 10000));
  }

  const downloadResponse = await fetch(
    `${BASE_URL}/search/download?resource_handle_id=${resourceHandleId}`,
    { headers }
  );
  const { url } = await downloadResponse.json();
  console.log(`Download URL: ${url}`);

  const csvResponse = await fetch(url);
  const buffer = Buffer.from(await csvResponse.arrayBuffer());
  const fs = await import("fs");
  fs.writeFileSync("search_results.csv", buffer);
  console.log("Results saved to search_results.csv");
  ```
</CodeGroup>
