practice

Bulk and Batch API Design

Endpoints that accept many items in one call, and the partial-failure semantics that make them either useful or dangerous.

apiperformanceintegration

Per-item APIs are clean and become untenable at integration scale: loading a million records through an endpoint that accepts one at a time is a million round trips, and the per-request overhead dominates completely.

The design question that decides everything is partial failure. If 900 of 1,000 items succeed, what does the response say and what state is the system in?

Three defensible answers, and the mistake is not choosing one explicitly. All-or-nothing transactional semantics are simplest to reason about and constrain batch size to what fits in a transaction. Best-effort with a per-item result array — each item reporting success or a specific error — is the most practical for large batches and requires the client to handle a mixed outcome properly, which many do not. Asynchronous job submission returning a job identifier, with status polling and a downloadable result, is the right shape for genuinely large volumes.

The details that make it usable: a documented maximum batch size, per-item identifiers echoed in the response so results can be matched to inputs, idempotency at both the batch and item level, and progress reporting for long-running jobs.

The failure to avoid: a bulk endpoint that returns 200 with failures buried in the body and no per-item detail. Clients then cannot tell what happened, and the usual consequence is a retry of the whole batch, duplicating the 900 that succeeded.