Records
Create, read, update and delete JSON records over HTTP, with versioning, bulk writes, soft delete and history.
A record is one JSON document in a collection. Your own fields live
under data; the API adds the rest.
{
"id": "01a12621-a7f6-7241-a836-853cd6595895",
"collectionId": "41a46615-602c-461d-8155-3760b9468a38",
"data": { "title": "Ship the landing page", "done": false },
"metadata": {},
"version": 1,
"schemaVersion": 1,
"createdBy": { "type": "user", "id": "97bbba40-…" },
"updatedBy": { "type": "user", "id": "97bbba40-…" },
"createdAt": "2026-10-10T14:05:02.301Z",
"updatedAt": "2026-10-10T14:05:02.301Z",
"deletedAt": null
}data can be any JSON — an object, but also an array, a string or a number.
metadata is a small object you own, for bookkeeping like {"source":"importer"}; it is
never checked against your schema.
In the examples below, …/records means
$BAAS_URL/workspaces/$BAAS_WS/collections/todos/records.
Create
curl -s -X POST "…/records" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"data":{"title":"Buy milk","done":false}}'Returns 201 Created with the stored record. Needs records:create.
To avoid double-writes when a request is retried, send an Idempotency-Key header with a
value you make up (a UUID is ideal). The first response is remembered for 24 hours and
replayed if the same key arrives again:
curl -s -X POST "…/records" \
-H "Authorization: Bearer $BAAS_KEY" \
-H "Idempotency-Key: 8f2c41e0-7b14-4f0e-9a51-2c7b3d6e1a90" \
-H "Content-Type: application/json" \
-d '{"data":{"title":"Buy milk"}}'Read
curl -s "…/records" -H "Authorization: Bearer $BAAS_KEY" # a page of records
curl -s "…/records/RECORD_ID" -H "Authorization: Bearer $BAAS_KEY" # one recordLists come back as { "data": [...], "pagination": { "nextCursor": …, "hasMore": … } }.
See Filtering and sorting to narrow them down.
Update
Replace the whole document:
curl -s -X PUT "…/records/RECORD_ID" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"data":{"title":"Buy oat milk","done":true}}'Change a few fields and leave the rest alone:
curl -s -X PATCH "…/records/RECORD_ID" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"data":{"done":true}}'In a PATCH, null removes a field: {"data":{"due":null}} deletes due. Arrays are
replaced whole, not merged.
Both need records:update.
Not overwriting someone else's change
Every write bumps version. Send the version you based your edit on and the API refuses
to clobber a newer one:
curl -s -X PATCH "…/records/RECORD_ID" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"data":{"done":true},"expectedVersion":3}'If someone else got there first you get 409 VERSION_CONFLICT, and details.currentVersion
tells you where things stand. Fetch the record again, re-apply your change, and retry.
This is optional. Without it, the last write wins — but writes are still serialised, so two simultaneous updates can never corrupt a record.
Delete and restore
curl -s -X DELETE "…/records/RECORD_ID" -H "Authorization: Bearer $BAAS_KEY"This is a soft delete: the record moves to the trash and stops appearing in lists. Bring it back with:
curl -s -X POST "…/records/RECORD_ID/restore" -H "Authorization: Bearer $BAAS_KEY"To see the trash, add ?deleted=only (or ?deleted=include) to a list request.
Erasing a record for good is a separate action and is not available to API keys — it needs a signed-in owner or admin.
History
Every version is kept.
curl -s "…/records/RECORD_ID/history" -H "Authorization: Bearer $BAAS_KEY"You can look at one revision, or roll back to it — which creates a new version rather than rewriting the past, so the history stays honest:
curl -s -X POST "…/records/RECORD_ID/restore/2" -H "Authorization: Bearer $BAAS_KEY"Many at once
Up to 500 records per call, all-or-nothing:
# Create
curl -s -X POST "…/records/bulk" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"records":[{"data":{"title":"One"}},{"data":{"title":"Two"}}]}'
# Delete
curl -s -X POST "…/records/bulk-delete" \
-H "Authorization: Bearer $BAAS_KEY" -H "Content-Type: application/json" \
-d '{"ids":["01a12621-…","01a12622-…"]}'For more than 500, use import.
Limits
One record's data | 256 KB |
metadata | 16 KB |
| JSON nesting depth | 32 levels |
| Records per bulk call | 500 |
A key named __proto__ is rejected, which stops a known class of JavaScript attack.
Next steps
- Filtering and sorting — searching, paging and
select. - Schemas — rejecting records that are the wrong shape.
- Webhooks — getting told when records change.
View this page as Markdown — handy for copying into an editor or an AI assistant.