Submit many searches in one request. POST /v1/search/batch accepts up to 500 items, where each item is a full search body. Items are validated independently: a validation failure on one item never blocks the others.
Batch is a convenience for submission, not a different execution model. Each accepted item behaves exactly like an async standalone POST /v1/search — it becomes a parent job that fans out into one child per surface × region, and each child is billed and completed on its own.

Request

items
object[]
required
Array of 1–500 search bodies. Each element is validated independently and supports the standard search body: query (or prompt), surfaces, regions, webhook, and a per-item idempotencyKey (see Idempotency below).

Response

Returns 200 with an items array that mirrors the request order. Each result carries the original index and is either accepted (with the created parent jobId and its child ids) or rejected (with the stable error code and message). A rejected item does not affect any other item in the batch.
Response
items
object[]
One result per submitted item, in request order.

Batch-level errors

Some conditions reject the whole batch before anything is spawned — as a standard flat error envelope, not per-item results:

Fan-out and billing

Each accepted item becomes its own parent job with one child per surface × region. Credits are charged per child on a successful capture — an empty or failed capture costs nothing. In the example above, item 0 (chatgpt + perplexity, one region) creates two children, and item 1 (google_ai_overview, one region) creates one child. Item 2 was rejected and created nothing.
Batch is always asynchronous — there is no mode=sync for batch. Prefer webhooks over polling when submitting large batches so you are notified as each child reaches a terminal state.

Idempotency

Each batch item is an independent job, so a per-item idempotencyKey behaves exactly like it does on POST /v1/search — applied to that one item. Give each item its own key (a stable id from your side, e.g. a run id) and safely retry the whole batch after an ambiguous failure:
  • Same key, same body → the item is accepted with replayed: true and its original jobId. It is not re-billed and spawns no new work — poll that jobId for the already-running (or finished) results.
  • Same key, different body → the item is rejected with IDEMPOTENCY_CONFLICT (a per-item rejection — sibling items are unaffected). Use a fresh key whenever the payload changes.
  • New key → runs normally as a fresh submission.
Response — item 0 retried (replay), item 1 fresh
Retrying a whole batch where every item carries a stable idempotencyKey is safe: already-accepted items replay (no double-charge, no duplicate jobs) and only the genuinely-new items run.

Search

The single-search endpoint and full request body.

Read a job

Poll a parent or read a child Envelope.

Webhooks

Get notified as each child completes.

Errors

Error codes returned on rejected items.