CRUD endpoints
Every resource generates a standard set of REST endpoints. This page documents their request and response shapes. Filtering, pagination, ordering, and relation includes are covered in their own pages and apply to the list endpoint.
List — GET /
Returns a paginated list. Supports filter, select, include, orderBy, cursor, limit, totalCount.
GET /api/posts?filter=published==true&orderBy=createdAt:desc&limit=20&include=author
{
"items": [{ "id": "p1", "title": "Hello", "author": { "id": "u1", "name": "Ada" } }],
"nextCursor": "eyJ2YWx1ZXMiOnsuLi59fQ==",
"hasMore": true,
"totalCount": 137
}
totalCount is present only when ?totalCount=true.
Get one — GET /:id
GET /api/posts/p1?include=author,tags
Returns the single row, or 404 if not found or outside the read scope. With ETags enabled, the response carries an ETag header and honors If-None-Match (returns 304).
Create — POST /
POST /api/posts
Content-Type: application/json
{ "title": "Hello", "body": "..." }
- Runs
onBeforeCreate→ insert →onAfterCreate(hooks). fields.writablestrips non-writable columns before hooks run;strictInputrejects unknown fields with422.- Emits an
addedsubscription event. - Returns the created row (
201), read-masked with computed fields applied. - With
nestedWrites, embedded relation objects are created in the same transaction.
Update (partial) — PATCH /:id
Updates only the provided fields.
PATCH /api/posts/p1
Content-Type: application/json
{ "title": "Updated title" }
Runs onBeforeUpdate → update → onAfterUpdate, emits a changed event, enforces If-Match when ETags are configured (412 on mismatch), and auto-increments the version field.
Replace (full) — PUT /:id
Same as PATCH but replaces the whole row; omitted writable fields are reset to their defaults/null. Governed by the same enableUpdate capability.
Delete — DELETE /:id
DELETE /api/posts/p1
Returns 204. Runs onBeforeDelete/onAfterDelete, emits a removed event, enforces If-Match. With softDelete, the row is marked instead of removed.
Counting — GET /count
GET /api/posts/count?filter=published==true
{ "count": 137 }
Honors the read scope and filter; excludes soft-deleted rows unless ?withDeleted=true.
Projections
The select parameter narrows returned columns:
GET /api/posts?select=id,title,createdAt
GET /api/posts/p1?select=id,title
select cannot recover columns hidden by fields.readable — masking is applied after projection. Computed fields and included relations always pass through.
The typed client narrows the return type to exactly the selected fields — see Client queries.
Error format
All errors use RFC 7807 Problem Details. See Error handling.
{
"type": "https://covara.dev/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "post p1 not found"
}
Related
- Filtering · Pagination · Relations
- Fields · Optimistic locking · Batch operations
- Subscriptions — every mutation streams to subscribers