Relatives & subjects

Relatives & subjects

A manifest can ask about people beyond the account holder: each child you cover, your co-driver. Those asks are subjects — declared once in the manifest with a relation (child, partner, …) — and every slot that carries a subject id in /status asks about that role rather than about the user.

The user answers a subject with their family-member vaults: vaults they own and hold data in on a relative’s behalf. Your app never sees those vaults' ids — every person is addressed by a pairwise alias, minted per connection, meaningless to any other organization.

Three rules shape everything on this page:

  • Relation-scoped. A subject declared child can only ever be answered by family members the user holds as children. The relation comes from the manifest, never from your app.
  • One person, one role. Within a connection, a family member answering one subject is excluded from answering a different one.
  • Labels are the user’s. The person’s display name is typed by the user, appears in exactly one response (person candidates), and is never accepted from or served back to any other partner surface.

Discover the cast

GET /status lists the manifest’s subjects and marks their slots:

{
  "subjects": [
    { "id": "1a7e…", "relation": "child", "label": "Each child you cover", "repeat": true }
  ],
  "items": [
    { "slotId": "9e01…", "label": "Child's name", "subject": "1a7e…",
      "kind": "schema", "target": "PersonFullName", "verbs": ["fill", "keep"],
      "status": "pending" }
  ]
}

repeat: true means 0..N people — the user chooses how many by binding family members. Slot status aggregates across the bound people; drive per-person state from the fill surface below.

List who could answer

GET /partner/v1/requests/{requestId}/subjects/{subjectId}/candidates

The person half of the fill surface: the user’s family members whose relation matches, minus anyone already answering a different subject of this connection. Requires fill on at least one of the subject’s slots; receipted (listed, coalesced) like every enumeration.

{
  "subjectId": "1a7e…",
  "relation": "child",
  "label": "Each child you cover",
  "persons": [
    { "alias": "c0ffee12-…", "label": "Alma", "bound": true },
    { "alias": "beef4477-…", "label": "Sixten", "bound": false }
  ]
}

bound: true marks people already answering this subject — render them as covered. The label is the user’s own name for the person; treat it as display-only.

Add a family member (“add a child”)

POST /partner/v1/requests/{requestId}/subjects/{subjectId}/persons
Content-Type: application/json

{ "label": "Alma" }

Mints a family-member vault owned by the user — the relation comes from the subject’s declaration, the label from what the user typed in your UI (ask for it explicitly: “their name — stays in your Geena”). The response is a person ready to answer slots:

{ "alias": "c0ffee12-…", "label": "Alma" }

No receipt row is written for the creation itself — the vault is the user’s own state; its later grants are the receipts. The call is not idempotent: disable the button while one is in flight.

Fill a subject’s slots

Every fill route takes the person:

GET  …/slots/{slotId}/candidates?person=c0ffee12-…
POST …/slots/{slotId}/attach          { "resourceId": "…", "person": "c0ffee12-…" }
POST …/slots/{slotId}                 { "person": "c0ffee12-…", "name": "…", "data": { … } }

Candidates then list the family member’s vault (their documents, with current data where decryptable), attach grants their existing item, create mints a fresh document in their vault and grants it in the same act. On a subject slot the person field is required; on a recipient slot it is refused.

Served records for subject slots carry the person back to you — a subject block with the alias — so a slot answered by two children yields two records you can tell apart. See Reading & writing data.

Warning

No delegated writes on subject slots. PUT and DELETE refuse: a family member’s data is corrected first-party in Geena, never on a partner’s behalf. The fill-surface create (with person=) is the one partner-side write into a family vault — always a new document, granted in the same act.