The read-resolution envelope
The response shape every record read returns, and how each field is labelled by how it resolved for the caller.
Every route that reads a record — GET a record, a
create or patch write-back — returns the same shape: the
read-resolution envelope. Each field is wrapped in a small object saying how its
value resolved for this caller, from that caller's grants. This page is the shape the
Records and Search pages point at.
The record
{
"id": "018f4e2a-7c1b-7a3e-b9d4-2f6c8a1e5b70",
"external_ref": "policy-4471",
"schema_version": 4,
"parent_record_id": "018f4e2a-6b0d-7c22-a1f4-9e7b3c5d2a10",
"fields": {
"holder_name": { "resolution": "revealed", "value": "Ada Lovelace" },
"policy_number": { "resolution": "tokenised", "token": "tok_AOWVT36VNVCIESCL" },
"card_number": { "resolution": "masked", "value": "••••••••••••0042" },
"sa_id_number": { "resolution": "tokenised", "token": "tok_9Xa1...", "detail": "the server holds no key for this field" }
}
}idis the record's identifier;external_refis the tenant's own reference;schema_versionis the version the record was written under;parent_record_idis its parent's identifier, ornull.fieldsmaps each field name to its envelope.- When the read was requested with
?include=children, the record also carries achildrenarray, each entry a record in the same envelope shape.
The per-field envelope
A field's envelope carries a resolution label and, depending on it, a value or a
token:
resolution | Carries | Means |
|---|---|---|
revealed | value — the cleartext | You hold a grant to read the value; it is returned in the clear. |
masked | value — a partially-masked string | A partial rendering (for example the last four characters); the rest is masked. |
tokenised | token — a tok_… string | The value is replaced by its stable token. |
A masked value renders its masked positions as the bullet character •.
The detail label on a degraded token
A client_encrypted field carries no server-side key, so a read_plaintext or
read_masked grant on it cannot produce the value or a mask — it degrades to the
token, and the envelope carries a detail saying why, so the downgrade is never
silent:
"the server holds no key for this field"— for aread_plaintextgrant;"no mask can be rendered without a key"— for aread_maskedgrant.
The resolution is tokenised in both cases. When a read_token grant produced the
token outright, nothing degraded and detail is absent.
Absent fields
A field you have no grant to see at all is absent: its key does not appear in
fields. It is not present with a null value. Treat a missing key as ungranted,
never as an empty value.
A record none of whose fields you may read is not returned at all — the read comes
back as not_found, the same as a record that does not exist — so a record's
existence never leaks to a credential that may read nothing of it.