Batch API
Run up to 100 record operations atomically in a single request.
POST /api/v1/batchContent-Type: application/json
{ "requests": [ { "method": "POST", "url": "/api/v1/posts", "body": { "title": "a" } }, { "method": "POST", "url": "/api/v1/posts", "body": { "title": "b" } }, { "method": "PATCH", "url": "/api/v1/posts/<id>", "body": { "title": "x" } }, { "method": "DELETE", "url": "/api/v1/posts/<id>" } ]}Atomicity
Section titled “Atomicity”A batch with at least one write runs in one transaction. Any operation
failing rolls back all of them, whatever the cause: a validation error, a
rule denial, a conflict, or a missing record or collection (404). Either
every operation succeeds or none do.
While a batch runs it has the database to itself: record writes from other
requests wait until it commits or rolls back (so they can never be swept into,
or rolled back with, the batch), and concurrent batches run one after
another. Hooks run for every operation, as they would for the same request
to the records API. Realtime events, webhooks and after* hooks for the batch’s writes
fire only after COMMIT; a rolled-back batch emits none.
Limits
Section titled “Limits”- 100 operations per batch. Larger batches return
422. - Records-API methods only — POST/GET/PATCH/PUT/DELETE on
/api/v1/<collection>or/api/v1/<collection>/<id>(/api/<collection>is accepted too). Any other path (admin, files, auth) or method fails the whole batch with422(Request N: …) before anything runs.
Response
Section titled “Response”{ "data": [ { "status": 201, "body": { ...created record... } }, { "status": 201, "body": { ...created record... } }, { "status": 200, "body": { ...updated record... } }, { "status": 204, "body": null } ]}When a write batch fails, nothing is committed and the response is an error for the whole batch:
{ "error": "Batch failed at request 2: ...", "code": 422, "details": { ...validation details from the failing op... }}N in Batch failed at request N is the failing operation’s position,
counting from 0. The HTTP status and code are that operation’s: 404 for a
missing record or collection, 403 for a rule denial, 422 for a validation
error, 409 for a restrict reference or a busy record, 405 for a view
collection or for creating or deleting a singleton’s record, 400 for a bad
filter, 500 otherwise.
A batch of only reads (GETs) changes nothing, so it doesn’t run in a
transaction. It answers 200 with each operation’s status in data; a
missing record is a 404 entry there, and the other reads still answer. A
rule denial or a bad filter still fails the whole read batch.
{ "data": [ { "status": 200, "body": { ...record... } }, { "status": 404, "body": { "error": "Record not found", "code": 404 } } ]}The whole batch runs under a single Bearer token. Each operation is checked
against its collection’s rules, as the same request to the records API
would be; admins bypass rules. A denied operation fails the batch with 403.
Use cases
Section titled “Use cases”- Bulk imports — see CSV import for a higher-level variant.
- Bulk deletes — the admin UI uses batch internally for the Records-page bulk-delete feature.
- Multi-write transactions — atomic create + update sequences (e.g. insert an order + update inventory in one go).