Skip to main content
Batch search runs one query asynchronously and delivers the entire result set as a single file. Where Company Search returns one cursor page per call, a batch job walks every page for you.
POST https://api.crustdata.com/batch/company/search
For fresher results retrieved from the web in real time, see Batch Company Live Search.
  • One query, whole result set. You submit a single query; the job paginates server-side until max_results is reached or the matches run out.
  • max_results is the only volume control. It clamps to 10,000 and defaults to that cap when omitted. Values above the cap are silently clamped; zero or negative values return 400. The non-batch paging knobs — limit, page, preview — are silently ignored.
  • Flat records. Each line in the results file has exactly the non-batch search record shape. No envelope.
  • Exact field projection. When you pass fields, each record contains exactly those fields — nothing more. Omit fields to get every field your account can read.

POST /batch/company/search takes the same filter fields and operators as Company Search, with one extra rule: the top level of filters must be an {op, conditions} group — a bare {field, type, value} condition is rejected with 400. Groups nest inside conditions for complex queries. This finds companies with more than 1,000 employees:
curl --request POST \
  --url https://api.crustdata.com/batch/company/search \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'x-api-version: 2025-11-01' \
  --data '{
    "filters": {
      "op": "and",
      "conditions": [
        {"field": "headcount.total", "type": ">", "value": 1000}
      ]
    },
    "max_results": 2,
    "fields": ["basic_info.name", "basic_info.primary_domain", "headcount.total"]
  }'
Search jobs always report identifier_count: 1 — the one query. When the job completes, the downloaded file contains flat records with exactly the requested fields:
The results file (all records)
{"basic_info": {"name": "Aarti Industries Ltd.", "primary_domain": "aarti-industries.com"}, "headcount": {"total": 4923}}
{"basic_info": {"name": "Aditya Birla Capital", "primary_domain": "adityabirlacapital.com"}, "headcount": {"total": 31747}}

Two warnings before you submit large jobs

Unknown filter field names are not rejected at submit time the way non-batch search rejects them — a typo in field simply produces a job that completes with 0 results. Double-check field names against the search reference first.
Do not pass a non-empty sorts array — the job will complete with 0 results. Sort the downloaded file instead, for example jq -s 'sort_by(.headcount.total) | reverse | .[]' results.jsonl.


Errors

400 — no filters
{
    "error": {
        "type": "invalid_request",
        "message": "`filters` must be provided for search",
        "metadata": []
    }
}
400 — invalid max_results
{
    "error": {
        "type": "invalid_request",
        "message": "`max_results` must be a positive integer",
        "metadata": []
    }
}

What to do next