Batch Operations
Batch endpoints write many records in a single request, so you can import, synchronize, or modify bulk data efficiently — and atomically. Each batch runs in a single transaction: if any record fails validation, the whole batch rolls back and no rows are written. Pass returnRecords: true to receive the affected records in the response (otherwise only a summary is returned).
| Method & Path | Operation | Max per batch |
|---|---|---|
POST /api/tables/:tableId/records/batch |
Create | 1000 |
PATCH /api/tables/:tableId/records/batch |
Update | 100 |
DELETE /api/tables/:tableId/records/batch |
Soft delete | 100 |
POST /api/tables/:tableId/records/batch/restore |
Restore | 100 |
POST /api/tables/:tableId/records/upsert |
Upsert | 100 |
All batch bodies require the canonical envelope form ({ "fields": { ... } }) — the flat-body shorthand accepted by single-record create is not available in batch requests. Every batch must contain at least one record.
Batch create
Send a records array, each item an envelope. Up to 1000 records per call.
POST /api/tables/contacts/records/batch
{
"records": [
{ "fields": { "email": "alice@example.com", "name": "Alice" } },
{ "fields": { "email": "bob@example.com", "name": "Bob" } }
],
"returnRecords": true
}
| Status | Meaning |
|---|---|
201 Created |
All records created |
400 Bad Request |
Empty array, over the 1000 limit, or any record fails validation (whole batch rolls back) |
401 Unauthorized |
No active session |
404 Not Found |
Table not found or not visible |
Batch update
Each item names the record id (string or number) plus the fields to patch. Up to 100 records per call.
PATCH /api/tables/contacts/records/batch
{
"records": [
{ "id": "1", "fields": { "status": "active" } },
{ "id": 2, "fields": { "status": "archived" } }
],
"returnRecords": true
}
Updates are partial per record — only the named fields are written. If any id is missing or any value is invalid, the transaction rolls back.
Batch delete
Send an ids array. Soft delete by default; set permanent: true to hard-delete already soft-deleted records (admin-only, enforced in the application layer). Up to 100 IDs per call.
DELETE /api/tables/contacts/records/batch
{
"ids": ["1", "2", 3],
"permanent": false
}
permanent can also be a query string. Route variants that keep the legacy contract accept ?permanent=true. The JSON-body form is preferred. Permanent batch delete is irreversible and requires the permanentDelete permission — see Soft Delete & Restore.
Batch restore
Recover many soft-deleted records at once. Records that are not currently deleted are skipped; a missing id rolls the whole batch back.
POST /api/tables/contacts/records/batch/restore
{
"ids": ["1", "2", "3"]
}
The restore clears each record's deletedAt/deletedBy and is logged to the record's change history.
Batch upsert
Create-or-update many records matched on one or more unique fields, in a single transaction. Name the merge key(s) with fieldsToMergeOn (alias: matchFields). Up to 100 records per call.
POST /api/tables/contacts/records/upsert
{
"records": [
{ "fields": { "email": "alice@example.com", "name": "Alice" } },
{ "fields": { "email": "carol@example.com", "name": "Carol" } }
],
"fieldsToMergeOn": ["email"],
"returnRecords": true
}
Each record is matched on the merge fields: an existing match is patched, otherwise a new row is created. Batch upsert is the canonical path for idempotent synchronization from an external source of truth.
Limits & semantics summary
| Property | Behavior |
|---|---|
| Atomicity | Each batch is a single transaction — all-or-nothing |
returnRecords |
false by default; true returns the affected records |
| Minimum size | At least one record/ID required (400 otherwise) |
| Authorship | createdBy/updatedBy/deletedBy stamped per record, same as single writes |
| Permissions | RBAC and field-level permissions enforced per record |
Related pages
- CRUD & Upsert — single-record operations and the upsert contract
- Soft Delete & Restore — permanent delete and restore
- Record History & Comments — batch operations are logged
- Records Overview — envelope and authorship rules