Skip to content

Search one field's controlled vocabulary

GET
/fields/{id}/values

THE contract for offering vocabulary values (ADR 0092 §1). A surface that lets someone pick a term asks this endpoint with a query and a limit; it does not fetch the field definition and filter options.values in the browser.

The distinction matters at production size. A field with two thousand terms is unremarkable in a real catalogue, and a page carrying twenty such fields would ship forty thousand values before the reader touched a control. Shipping a whole vocabulary stays legal as an OPTIMISATION for demonstrably small ones — GET /fields still returns options — but it is never the only path, and any client that filters in memory is searching a prefix of the truth the moment the vocabulary outgrows what it was given.

Matching

q is matched against a term’s slug, its label, and any operator-configured aliases, case-insensitively and whitespace-trimmed — the same three keys the WRITE path resolves against, so a term this endpoint offers is a term a value write will accept.

Ordering

Stable and rank-first: exact hits, then prefix hits, then substring hits, each group ordered by label and broken by slug. Equal inputs give equal output, so a caller may page by raising limit without the earlier rows reshuffling.

The bound is real

limit caps what comes back. matched reports how many terms the query actually admitted, so a caller can say “1 of 340” rather than pretending the capped list is the answer.

id
required
string format: uuid
q
string
<= 200 characters

The text to match. Omit or leave empty to browse the vocabulary from the top, ordered by label.

match
string
default: prefix
Allowed values: prefix substring

prefix (the default) admits terms that START with q. substring also admits terms that merely contain it — looser, useful for browsing, and still ranked so the prefix hits come first.

limit
integer
default: 50 >= 1 <= 200

Maximum terms to return. The response says how many matched.

status
string
default: active
Allowed values: active deprecated archived any

Which lifecycle states to include. Defaults to active — the set a picker may OFFER. any includes deprecated and archived terms and is what a curation surface needs, since a tombstone is only useful to someone who can see it.

The matching terms, capped at limit.

One bounded answer to a vocabulary query. matched is the honest total, so a client can say how much it is NOT showing instead of implying the capped list is the whole set.

object
values
required
Array<object>

One term of a field’s controlled vocabulary, as a picker or a curation surface needs to see it.

object
value
required

The slug asset_field_value stores. Unique across the field’s WHOLE option tree, which is what lets a stored value be one leaf slug rather than a path.

string
label
required

Display text. Equals value for a bare-slug entry.

string
path
required

Ancestor labels from the root of the vocabulary down to and including this term. One element for a flat vocabulary, N for a node N levels into a tree field.

Array<string>
status
required

active may be chosen. deprecated still resolves and displays but is not offered for new values. archived is a hard retire — or, with replaced_by set, a merge tombstone.

string
Allowed values: active deprecated archived
replaced_by

The slug that supersedes this one. Set by a merge, in which case this term is a TOMBSTONE: a later write naming it resolves to the successor instead of being refused, which is how a value arriving from a peer that predates the merge still lands somewhere real.

string
nullable
aliases

Extra match keys an operator attached to this term. An alias is a WRITE-TIME REDIRECT (ADR 0092 §4): typing one stores this term’s slug. It is non-retroactive — rows written before the alias existed are untouched — and reversible, since removing it simply stops the redirect. A real slug or label always beats an alias, so an alias can never shadow a term that exists.

Array<string>
matched
required

How many terms the query admitted, before limit was applied.

integer
returned
required

How many are in values. Never greater than limit.

integer
limit
required

The cap that was applied — the effective one, after clamping.

integer
truncated
required

True when matched exceeded limit.

boolean
vocabulary_size
required

Terms in the whole vocabulary at every depth, in every lifecycle state. Lets a client decide whether fetching the list whole is defensible for this particular field.

integer
open_vocabulary
required

The field’s open_vocabulary flag, as honoured for this field’s type.

boolean
can_extend
required

Whether THIS caller may create a term here — the field is open AND the caller holds fields.vocabulary.extend. A client renders its create affordance from this and nothing else, so the control it shows matches the answer the write path will give (ADR 0092 §2: the same control with the create arm absent, never a silent failure).

boolean

Malformed request

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Authenticated but missing required capabilities

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Unexpected server error

object
error
required

Human-readable error summary

string
Example
the request could not be completed