Skip to main content
When you need to submit thousands (or tens of thousands) of requests to Sail, serial requests become a major bottleneck. Sail offers two ways to handle high-volume workloads: the Batch API and the Responses API.

Batch API

The Batch API lets you submit up to 100,000 requests in a single call (max 256 MB per batch).
  1. Submit a batch — Send all your requests in one POST /batches call.
  2. Poll for status — Check GET /batches/{batch_id} until all requests are completed.
  3. Retrieve results — Fetch individual results via GET /batches/{batch_id}/{custom_id}.
To view all your previously submitted batches, use GET /batches. Attach an Idempotency-Key header on submission so a client retry after a network blip replays the original batch reservation instead of creating a duplicate. See Idempotent Requests.
Batch items default to metadata.completion_window: "standard" when the field is omitted. If you set it explicitly, it must be either "standard" or "flex" — the low-latency "asap" and "priority" tiers are rejected for batch items. For latency-sensitive workloads, use the Responses API instead. See Completion Windows for the full tier definitions and per-model availability.

Python example

First, install the requests library:

Responses API with background mode

You can also submit requests individually using the Responses API with background=True. For large-volume workloads (1,000+ requests), we recommend:
  1. Use AsyncOpenAI with DefaultAioHttpClient() — The OpenAI SDK’s built-in aiohttp client is more efficient than the default httpx backend for high-concurrency workloads.
  2. Gate concurrency with an asyncio.Semaphore — This gives you fine-grained control over how many simultaneous connections are opened (e.g. 200), preventing connection exhaustion.
  3. Submit all requests concurrently with background=True, then poll — Fire off all submissions in parallel (gated by the semaphore), collect the response IDs, and poll for completions in a separate loop.
  4. Send a per-request Idempotency-Key — So a retry after a transient failure replays the reservation instead of duplicating inference work. See Idempotent Requests.

Python example

First, install tqdm and the OpenAI SDK with the aiohttp extra:
The semaphore limit of 200 is a good starting point. Lower it if you run into connection errors or timeouts; raise it if you have headroom and want faster submission throughput.