Custodian
ReferenceHTTP API

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" }
  }
}
  • id is the record's identifier; external_ref is the tenant's own reference; schema_version is the version the record was written under; parent_record_id is its parent's identifier, or null.
  • fields maps each field name to its envelope.
  • When the read was requested with ?include=children, the record also carries a children array, 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:

resolutionCarriesMeans
revealedvalue — the cleartextYou hold a grant to read the value; it is returned in the clear.
maskedvalue — a partially-masked stringA partial rendering (for example the last four characters); the rest is masked.
tokenisedtoken — a tok_… stringThe 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 a read_plaintext grant;
  • "no mask can be rendered without a key" — for a read_masked grant.

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.

On this page