Errors

Errors

The error envelope

Plane errors are JSON with a stable machine-readable code:

{ "error": "not_found", "message": "no such item" }
HTTP error Meaning
400 invalid_body Missing/malformed body (e.g. no data object, no file part)
400 invalid_document Payload fails the schema it is validated against
400 unsupported_item Operation not defined for the slot’s kind (e.g. writing or deleting through a files slot)
400 invalid_target The legacy items/{kind}/{target} target could not be decoded
401 unauthenticated No valid caller behind the token
403 partner_token_required A first-party (non-partner) token was presented
403 unknown_client The token’s client is no longer registered
403 organization_suspended Your owning organization is suspended
403 connection_inactive The connection is revoked, withdrawn, or expired
403 verb_not_granted The slot does not carry the verb this operation needs
403 delete_refused The platform protects this document from deletion
403 subject_item_readonly Delegated write or delete on a family member’s slot
403 participant_ineligible The named party may not answer this subject: wrong relation, already cast in another role, the subject’s one seat is taken, or the user no longer manages the company (409 on a delegated company write)
403 limit_reached The user’s plan allows no more family-member vaults
404 not_found Ungranted, foreign, malformed, or nonexistent — deliberately one answer
404 participant_unknown The alias names nobody the user may answer with, or a different party than the resource belongs to
409 ambiguous_item The (kind, target) pair matches several slots / records — use slot ids
409 slot_conflict A concurrent fill changed the slot’s grants — re-list and retry
409 participant_conflict A concurrent fill cast this participant or subject differently — re-list and retry
409 subject_kind_unsupported The act does not apply to this subject’s kind (company founding not enabled)
413 too_large The upload exceeds the per-file cap (32 MiB by default); nothing written
422 participant_required A subject slot was filled without saying who
422 participant_not_allowed A participant was named on a recipient slot
423 sealed The user’s vault key could not be opened right now; see sealed keys
423 org_sealed The record’s key is your organization’s to open and no member is signed in
500 server_error Transient server failure — safe to retry
Info

Read 404 as “nothing for you here”, never as “does not exist.” The same answer covers an item the user declined to share, an id from another user, and an id that was never real. Probing teaches nothing — by design.

One 403 has a different body: a security-gate refusal (the token lacks the scope the route needs) answers with the platform’s GraphQL-style envelope — {"errors":[{"message":"…","extensions":{…}}]}. Retrying does not help; the connection needs that scope.

Unavailable records

Not every refusal is a status code. When a slot is served, a record the user can no longer hand over arrives inside the 200 with status: "unavailable" and a reason, so one dark record never hides the rest of a slot:

reason Meaning What to do
participant_ineligible The user can no longer speak for the party that answered (left the company, lost the Manager role) Show it; the grant and any kept copy stand, and it serves again if standing returns
record_unreadable This server could not produce the record right now Retry later; not consent withdrawn, so keep the party

Read status before type on every record, and treat an unknown status as unavailable. See Reading & writing data.

Sealed keys

Geena opens the user’s vault key on the server whenever a call needs it, so a seal is rare. Neither 423 is consent withdrawn: keep the connection and its parties.

  • 423 sealed: the user’s vault key could not be opened right now. The entitlement is real. Retry, or ask the user to sign in to Geena.
  • 423 org_sealed: the key is your organization’s, and it warms when a member of your organization signs in (to the dashboard, or through the organization-access ceremony). No action by the user is needed; retry once a member is in.