API
Write
On a Postgres-backed namespace, conditions use the query filter syntax and are evaluated against each targeted row’s stored value in the write’s transaction:
-
upsert_condition: an existing row is replaced only if it passes. A new id is always inserted. A$ref_newvalue reads the row being written, where a missing attribute isnull.["id", "Eq", null]inserts without overwriting, and this condition keeps only newer versions:["version", "Lt", {"$ref_new": "version"}] -
delete_condition: a row is deleted only if it passes.$ref_newisnullfor every attribute, and a missing id is skipped. -
rows_affectedcounts only the rows whose condition passed. -
A condition on an undeclared attribute, or a
$ref_newwhose type differs from the compared attribute, is a400validation error. The whole write is rejected with no effects.
Conditional writes: approximate — upsert_condition and delete_condition, including $ref_new; patch_condition returns 422 because row and column patches are unsupported
Layer stamps every row-producing write with _hevlayer_upserted_at for supported stores. The stamp is what holds the
read watermark; the full set of reserved attributes Layer
manages on a row lives in the document model.
To branch or copy a namespace, see Branching.
Status
Layer validates the body before forwarding and can fail independently of the backing store, so the write path carries a few statuses a plain proxy wouldn’t:
- 200 OK — applied to the store and stamped.
- 422 Unprocessable Entity — Layer rejected the body before forwarding:
no recognized native write operation, a reserved
_hevlayer_*attribute name, a removed custom-write key, or a schema type the configured store cannot represent. The body is a Layer error ({ "error": "validation_error", … }or{ "error": "UnsupportedByStore", … }), not a store one. - Upstream passthrough — any non-2xx the backing store returns is relayed verbatim.
- 502 Bad Gateway — Layer could not reach the backing store
(
{ "error": "upstream_error", … }); the write did not apply.
The passthrough case includes a failed conditional write (upsert_condition,
patch_condition, delete_condition) — turbopuffer’s error body comes back
untouched.