§ docs — rest api
a plain REST API, no SDK required.
Every table gets REST endpoints automatically. Use any HTTP client — curl, fetch, your favourite language. Responses are JSON, errors are plain, and there’s nothing proprietary to learn.
Authentication
Pass an API token as a Bearer header. Create tokens in Studio under System → Tokens; scope them read or read_write.
# every request carries your token
curl https://api.nicebaas.com/api/synthetic-project/items/pages \
-H "Authorization: Bearer nb_live_..."List records
Returns matching non-deleted records with a stable order. Use limit from 1 to 1000 and nonnegative offset for pages. Filter only schema fields with field=value or field[operator]=value. Supported operators are eq, neq, contains, gt, gte, lt, and lte where the field type allows them. Use sort=field or sort=-field, search, and comma-separated fields to project returned data. The total is the count before pagination.
// fetch
const response = await fetch(
base + "/synthetic-project/items/pages?title[contains]=home&sort=-title&limit=1&offset=0&fields=title",
{ headers }
)
const { items, total } = await response.json()// 200 OK
{
"items": [
{
"id": "record-uuid",
"data": { "title": "Home" },
"created_at": "2026-06-18T12:00:00Z",
"updated_at": "2026-06-18T12:00:00Z"
}
],
"total": 2
}List records · Query rows.
Fetch one record · Fetch by id.
Create a record · Create row.
Update a record · Merge fields.
Delete a record · Soft-delete.
Create a record
Send a JSON body with your field values. Required fields are validated; the new record is returned with its generated id.
curl -X POST $base/items/pages \
-H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d '{ "title": "Field Notes", "status": "Draft" }'Update & delete
Partial update. Send only changed fields.
Soft-delete. Hidden from lists.
try it
playground.
// response will appear hereautomation action
Signed webhook deliveries
Create an automation in Studio by choosing a table, one record change, a public HTTPS webhook URL, and a signing secret from 16 to 1024 bytes. NiceBaaS sends a POST containing only that matching record event.
# POST JSON body
{
"id": "event-uuid",
"event": "record.created",
"table": "pages",
"record": { ... }
}Verification headers
- X-NiceBaaS-Delivery
- Stable delivery UUID. Store this to deduplicate retries.
- X-NiceBaaS-Event
- One of record.created, record.updated, or record.deleted.
- X-NiceBaaS-Timestamp
- Unix seconds used in the signature input.
- X-NiceBaaS-Signature
- v1=<hex(HMAC-SHA256(secret, timestamp + "." + raw_body))>
Delivery policy. Each request has a 5 second timeout and succeeds only on a 2xx response. Redirects are not followed. NiceBaaS tries at most three times: immediately, then after 1 minute, then after 5 minutes.
Delivery is at least once. A process failure after your endpoint receives the request can repeat the same delivery ID, so receivers must deduplicate it. Studio activity records every attempt and the final failure.
content api
Project content primitives
Lists and blocks are not generic record tables. They are first-class, ordered project resources, kept separate from /items/{table} records.
Project isolation: every path includes a project slug. A list, entry, or block from another project is not addressable through this API.
Authorization: read tokens can GET. Creating, editing, ordering, and removing require a read_write token or an authenticated project member session with a valid X-CSRF-Token request header.
Ordering: reorder requests send the complete ordered UUID list. IDs must be unique and belong to that exact list or project.
Responses: collection reads return {"lists"}, {"entries"}, or {"blocks"}. Creates return 201 with {"list"}, {"entry"}, or {"block"}; updates and deletes return 200 with the same envelope, and reorders return {"ok":true}.
Value lists
A list has a unique name and a project-local position. Its entries are ordered strings, not rows with user-defined fields.
GET /api/{project}/content/lists
POST /api/{project}/content/lists { "name": "Genres" }
PATCH /api/{project}/content/lists/{list} { "name": "Genres" }
DELETE /api/{project}/content/lists/{list}
GET /api/{project}/content/lists/{list}/entries
POST /api/{project}/content/lists/{list}/entries { "value": "Ambient" }
PATCH /api/{project}/content/lists/{list}/entries/{entry} { "value": "Ambient electronic" }
DELETE /api/{project}/content/lists/{list}/entries/{entry}
POST /api/{project}/content/lists/{list}/entries/reorder { "ids": ["11111111-1111-4111-8111-111111111111", "22222222-2222-4222-8222-222222222222"] }
Content blocks
Blocks have a name, one of six kinds, a body, and a project-local position. Supported kinds are text, richtext, media, embed, data, and layout.
GET /api/{project}/content/blocks
POST /api/{project}/content/blocks { "name": "Hero", "kind": "layout", "body": "Lead story" }
PATCH /api/{project}/content/blocks/{block} { "name": "Hero", "kind": "layout", "body": "Lead story" }
DELETE /api/{project}/content/blocks/{block}
POST /api/{project}/content/blocks/reorder { "ids": ["33333333-3333-4333-8333-333333333333", "44444444-4444-4444-8444-444444444444"] }
# list a project's blocks
curl https://api.nicebaas.com/api/my-project/content/blocks \
-H "Authorization: Bearer nb_live_..."Errors
Errors use a stable JSON shape with a machine-readable code and a short message.
{
"code": "invalid_query",
"message": "operator \"between\" is not supported"
}Deferred post-MVP
These features stay out of the MVP contract until the core records flow is stable.
storage/R2 shared bucket, per-client subdirs, and analytics.
automated import Directus transformer after pilot proof.