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

# Bulk Search Guide

> Run the same search shape across many terms and download the results

## Overview

Bulk search is for batched investigations where one search shape needs to run
against many terms. Instead of sending hundreds of separate search requests, you
create one job with a shared `query_config` and a list of `terms`.

Use bulk search when:

* you have many domains, emails, usernames, or identifiers to check
* each term should reuse the same service, fields, filters, and output format
* you want an asynchronous job with status polling and a downloadable result

For one-off searches, use the normal breach, stealer, or victims search guides.

## How It Works

1. create one job with the shared search shape and all target terms
2. poll the job until it finishes
3. download the generated output file
4. list recent jobs when you need history or recovery after a client restart

Bulk search responses are job snapshots. Create responses use the standard
`success/data` envelope; list and status responses are raw JSON snapshots.

## Query Config

`query_config` is the reusable part of the search. It can contain the same flat
filters and structured `filter` grammar used by normal V2 search.

```json theme={null}
{
  "service": "breach",
  "format": "jsonl",
  "terms": ["example.com", "example.org"],
  "query_config": {
    "filter": {
      "field": "email_domain",
      "operator": "eq",
      "value": "example.com"
    },
    "date_field": "indexed_at",
    "from": "2026-03-01T00:00:00Z",
    "to": "2026-03-31T23:59:59Z"
  },
  "limit": 1000,
  "fields": ["email", "username", "password", "dbname"]
}
```

Supported `service` values are `stealer`, `docs`, `victims`, and `breach`.
Supported `format` values are `csv`, `json`, `jsonl`, `txt`, and `html`.

## Polling

Bulk jobs may include `next_poll_after_ms`. Prefer that value when present, and
fall back to a conservative interval when it is missing.

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

headers = {"x-api-key": "YOUR_API_KEY"}
job_id = "5a947390178c534af14dd075"

while True:
    snapshot = requests.get(
        f"https://oathnet.org/api/service/v2/bulk-search/{job_id}",
        headers=headers,
    ).json()

    if snapshot["status"] in {"completed", "failed", "cancelled"}:
        break

    time.sleep(snapshot.get("next_poll_after_ms", 2000) / 1000)
```

## Downloads

The download endpoint returns a file or text stream, not JSON. Save the response
body directly.

```bash theme={null}
curl -X GET "https://oathnet.org/api/service/v2/bulk-search/5a947390178c534af14dd075/download" \
  -H "x-api-key: YOUR_API_KEY" \
  -o bulk-search.jsonl
```

## Exact Request Details

Use the OpenAPI reference for the complete schema, enum list, response fields,
and playground requests for each bulk-search endpoint.
