Skip to content

Effective per-field readability for composing this collection's form

GET
/collections/{id}/field-composition

The collection twin of GET /assets/{id}/field-composition. One entry per non-archived collection field definition, carrying the field’s identity and whether THIS caller may read THIS collection’s values of it, and no values at all (ADR 0099 §5).

The collection surface needs this as much as the asset surface does, and for a reason that is easy to miss: GET /collections/{id}/fields has always filtered by read_capability, but it filters by DROPPING THE ROW, so a withheld value and a value that was never set arrive as the same nothing. Those two states have opposite consequences for a condition (unevaluable shows the dependent, absent hides it), so the distinction has to come from somewhere.

collections carries no team_id column, so a team-scoped grant confers nothing here and the caller’s global holding is the whole answer. That asymmetry with assets is deliberate and pre-existing: giving collections a team is a separate decision, not something this endpoint should imply.

id
required
string format: uuid

Per-field effective readability, values excluded

Array<object>

What a composition surface needs to know about ONE field definition in order to evaluate a display_condition against a particular subject, and nothing else (#1173, #1119, ADR 0099 §5).

THERE IS NO VALUE MEMBER HERE AND THERE MUST NOT BE ONE. The non-disclosure requirement is met by the SHAPE: a caller who may not read a field receives its identity and readable: false, and there is no member into which the protected value could have been placed. Sending the value alongside a false flag, or sending it and expecting the client to drop it, are both explicitly refused designs. The typed values live on GET /assets/{id}/fields and GET /collections/{id}/fields, both of which now filter by the same effective readability this reports.

object
field_id
required
string format: uuid
field_code
required

The federation-stable code. Carried alongside the id because a display_condition term names a CODE, so a client resolving a term would otherwise need a second index to get from the term to this row.

string
readable
required

May THIS caller read THIS subject’s values of this field?

Derived on the SERVER, and it has to be: read_capability is answerable globally OR scoped to a team, and GET /auth/me/capabilities carries only the global codes, so a browser inferring this from what it holds would answer “no” for exactly the team-scoped operator the field was configured for.

true when the field carries no read_capability at all, or when the caller holds it globally, or when the caller holds it scoped to the subject’s team and the subject has one. An asset may have a team_id; a collection has no team column, so on a collection the global holding is the whole answer.

What a condition evaluator does with it: false makes the term UNEVALUABLE, which makes the whole condition unevaluable and SHOWS the dependent. That is deliberately not the same as a readable field with no value, which is a real FALSE and HIDES the dependent. Distinguishing those two is the reason this endpoint exists.

boolean

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"
}

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed