Skip to content

Essence Authentication Service API ​

All OpenAPI documents

Version v1.0 · OpenAPI 3.0.1 · 323 operations · Download the JSON document

API for user authentication, registration, and session management. ## Features - User registration with email/password - Multi-factor authentication (TOTP, SMS, Email) - Device fingerprinting and trust management - JWT tokens with RS256 signing - Refresh token rotation - Federated identity (UAE PASS, Azure AD, Okta, etc.) ## Security - Zero-knowledge architecture (client-side password hashing) - Account lockout policy (5 attempts = 30min) - Token blacklisting for revocation - Constant-time password verification (SEC-005) - Adopted Essence platform foundation (Phase 1 WS-B)

Generated from the Auth service's code at build time (api-specs/generated/Auth/Essence.Identity.Auth.Api.json) and drift-checked in CI. It describes what the code registers, which is not the same as what any one deployment has routed.

AccessRecertificationTermination

POST/api/v1/access-recertification/terminations

Terminates a named staff principal's sessions and issued credentials under the authority of a recertification campaign.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Executed. A principal who was already signed out yields `sessionsRevoked: 0` — that is a successful termination of nothing, not a failure, and it is still recorded as evidence. — TerminatePrincipalAccessResult
400The request is not accountable (missing actor, campaign, reason or scope target). — ProblemDetails
401Unauthorized — ProblemDetails
403The caller does not hold the access-recertification-operator role. — ProblemDetails
409The subject is unknown or is not a staff principal; nothing was terminated. — TerminatePrincipalAccessResult

AccountAction

GET/api/v1/account/action-notice

Returns the honest account-action notice for the signed-in / affected account. When a `case` reference is supplied it scopes the lookup to that decision. Returns 204 when there is no action on the account.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
casequerystringno—

Request body

No request body.

Responses

200The current notice. — AccountActionNoticeDto
204No action is in force on the account.
GET/api/v1/account/action-notice/by-token

Returns the account-action notice for the holder of a single-purpose notice token, WITHOUT a session. A suspended account cannot hold a session, so the person the notice is about would otherwise be the one person unable to read it — including the appeal route it describes. The token is minted only when that person successfully proves their password at sign-in, is 256 bits of CSPRNG output, is stored only as a hash, expires in 30 minutes, and is accepted by this endpoint alone. It is deliberately not a bearer token: it can authenticate nothing else. The appeal case reference is NOT usable for this purpose — it carries ~32 bits behind a guessable date prefix and does not exist until an appeal has already been opened.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenquerystringno—

Request body

No request body.

Responses

200The notice for the token holder. — AccountActionNoticeDto
404Unknown, expired or already-replaced token. — ProblemDetails
POST/api/v1/account/actions

Applies a graduated administrative action to an end-user account (the EPIC 48 moderation decision). Admin-only. Emits the shared account-action event.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The action was applied. — ApplyAccountActionResult
400Invalid action token or missing required fields. — ProblemDetails
404The target user does not exist. — ProblemDetails
POST/api/v1/account/appeals

Submits an appeal against an account action on behalf of the affected user. Returns a returnable case reference + the response-SLA window.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The appeal was opened. — AppealCaseDto
400The action is not appealable or an appeal already exists. — ProblemDetails
404No such action for this account. — ProblemDetails
GET/api/v1/account/appeals/by-token

Re-reads the appeal opened against the token's action, WITHOUT a session, so a suspended holder can return and track it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenquerystringno—

Request body

No request body.

Responses

200The appeal case. — AppealCaseDto
404Unknown/expired token, or no appeal has been opened yet. — ProblemDetails
POST/api/v1/account/appeals/by-token

Submits an appeal using the single-purpose notice token, WITHOUT a session — the only route available to a suspended holder. The notice this token was minted for tells its holder they may appeal. The session-based `POST appeals` above resolves the appellant from JWT claims, so until this existed the right to appeal was announced to exactly the people who could not exercise it. The appealed decision is resolved FROM the token — it is not accepted in the body — so the token can only ever open an appeal against its own action.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The appeal was opened (or already existed). — AppealCaseDto
400The action is not appealable. — ProblemDetails
404Unknown, expired or already-replaced token. — ProblemDetails
GET/api/v1/account/appeals/{caseRef}

Re-fetches an appeal's status by case reference.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
caseRefpathstringyes—

Request body

No request body.

Responses

200The appeal case. — AppealCaseDto
404No such appeal for this account. — ProblemDetails

AccountClosureCancel

POST/api/v1/auth/account/closure/cancel

Cancel the closure the link was minted for, and reopen the account.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The link was live: the closure is cancelled and the account is open. — AccountClosureCancelResponse
410The link cannot be used — the same answer whatever the reason. — ProblemDetails

AccountClosureDecisions

POST/api/v1/auth/account-closure-decisions/fraud

Decide a fraud closure (T7). Closes nothing until a different principal approves it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Decided; awaiting a different approver. — AccountClosureDecisionResult
403The caller may not decide a fraud closure. — ProblemDetails
409The account is not open, or already has an open fraud closure. — ProblemDetails
GET/api/v1/auth/account-closure-decisions/{id}

Read one closure decision.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/auth/account-closure-decisions/{id}/approve

Approve a decided fraud closure or a verified death — by a different principal. Closes the account.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/auth/account-closure-decisions/{id}/reject

Stop an open closure. Nothing is closed.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/auth/account-closure-decisions/{id}/verify-death

Verify a reported death (T8, the Support lead). A different principal must approve it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

AccountFactorHolds

GET/api/v1/auth/account-factor-holds/current

The hold in force on the caller's text-message factor, if any.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200A hold is in force: the event it names, when it ends and how it can end. — AccountFactorHoldView
204Nothing is held.
POST/api/v1/auth/account-factor-holds/{holdId}/confirm

Ends the hold: the caller confirms the number change was theirs.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
holdIdpathstring (uuid)yes—

Request body

No request body.

Responses

200Released; text-message codes work again. — AccountFactorHoldView
403This session cannot end the hold: sign in with a passkey, or use a device trusted before it. — ProblemDetails
404No such hold is in force on this account. — ProblemDetails

AccountMerge

POST/api/v1/account/merge/sessions

Start a merge session naming the account to retire into the caller's own.

<b>The surviving account is taken from the validated token, never the body.</b> A self-service merge always folds another account into the caller's own, so accepting a client-supplied survivor would be an account-takeover primitive (name a victim as the retiring account, yourself as the survivor). Any `survivingAccountId` in the body is ignored; the domain re-asserts the same invariant so this cannot be bypassed.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
503Service Unavailable
POST/api/v1/account/merge/sessions/{id}/commit

Commit the merge (retire + fold). Requires the session to be proven AND a fresh survivor step-up (WCAG 2.2 SC 3.3.4 error-prevention gate, debt-2026-07-03-226). Rejects the destructive confirm with 403 when the step-up is absent or invalid.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
503Service Unavailable
POST/api/v1/account/merge/sessions/{id}/prove

Bind proof-of-control for one account of the session. Submit once per account; the session becomes `Proven` once both are bound.

The body carries the account being proven PLUS a second-factor proof enrolled on THAT account. The caller's own authenticated session is not evidence about the retiring account — which is, by construction, not the account they are signed in as — so the factor is verified against `accountId`, never against the caller.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/account/merge/sessions/{id}/status

Read the merge session's per-stage progress so the UI can render honest, discrete "visibly working" stages (rekey → move_records → unify_identity → repoint_consents) instead of an indeterminate busy state (debt-2026-07-03-226). Only the session initiator may read it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/account/merge/sessions/{id}/undo

Reverse a committed merge within the grace window.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/account/merge/{id}/policy

Resolve the organisation governance policy that governs THIS merge — the member-facing read behind the step-6 confirm gate (journey `account-merge-consolidate-duplicate-identities`, debt-2026-07-09-253). Returns the governing mode (`allow` | `require-approval` | `block`) and, when an organisation governs it, that organisation's display name.

The same resolver backs the server-side commit gate, so what the member is shown and what the server enforces cannot diverge. An ungoverned (personal) merge — the common case — resolves to `allow` with no organisation. Only the session initiator may read it: a merge session id would otherwise be an IDOR handle onto another member's organisation membership. Zero-knowledge: a mode and an organisation display name only — never org data.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/account/merge/{id}/request-approval

Enqueue this merge for its surviving member's organisation to approve before it can commit (EPIC 7 governance seam, debt-2026-07-09-284). Flags the merge require-approval and feeds the org-console approval queue via an outbox integration event. Only the session initiator may request approval.

Calling this is <b>not</b> what makes the org gate apply. The commit gate resolves the governing organisation's policy directly, so a client that never calls this endpoint still cannot commit a merge a `require-approval` organisation governs. This endpoint is how the member puts their merge INTO that org's queue.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/account/merge/{id}/reverse

Reverse a committed merge within the grace window, returning the full reversal receipt (journey Step-7 "Undo merge", debt-2026-07-07-104). Exposed at the absolute route the delivered client calls — `POST /api/v1/account/merge/{id}/reverse`. Restores both accounts, instructs downstream consumers (via the reversal outbox event) to revert re-pointed grants and retract org notices, and reports the counts of each. Only the session initiator may reverse it; valid only while `ReversibleUntil` is open (else 409).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/account/merge/{id}/reversibility

Resolve the reversal posture that applies to THIS merge — `self-service`, `assisted-only` or `none`, with the window length in whole days (journey `account-merge-consolidate-duplicate-identities`, gap G-reversibility, debt-2026-08-10-003).

<b>Answerable before the destructive confirm.</b> That is the point of it: the confirm gate used to promise an unconditional 30-day self-service undo and the receipt then walked it back to "(assisted recovery)" — after the member could no longer decline. Both surfaces now render one posture resolved here. The posture is derived from what the reversal path actually enforces (the same resolved org policy `POST {id}/reverse` applies), so it can neither over-claim nor — as the client's unavailable-read fallback had to — under-claim. Only the session initiator may read it. Zero-knowledge: a posture and a window length.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/account/merge/{id}/withdraw-approval

Retract a queued org-approval request on the member's own initiative, before the organisation has decided it (gap <b>G-withdraw</b>, `uxf-2026-08-12-017`). Moves the merge's approval state to `Withdrawn` and drops the org-console queue's held decision via an outbox integration event. Only the session initiator may withdraw.

This is the server half of the member's "submit-then-override" guard. The client releases the override <b>only</b> when this call succeeds: the behaviour it replaces cleared a device-local record and unlocked the override on a no-op, leaving the organisation holding a decision about a merge that had already run. <b>409</b> is returned when there is nothing to retract — the merge already committed or was undone, no request was ever made, or the organisation has already decided it. Withdrawing an already-withdrawn request returns <b>200</b>, so a retried call reads as the success it is.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

AdminSetupPosture

POST/api/v1/admin/setup-posture/backfill

Announces one keyset page of accounts' setup posture. Call repeatedly, passing the returned `nextAfterId`, until `complete` is true.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails

AdminUserRoles

POST/api/v1/admin/users/{idOrEmail}/roles

Grants request.Role to the user identified by idOrEmail.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idOrEmailpathstringyesA user id (GUID) or email address.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
DELETE/api/v1/admin/users/{idOrEmail}/roles/{role}

Revokes role from the user identified by idOrEmail.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idOrEmailpathstringyesA user id (GUID) or email address.
rolepathstringyesRole name to revoke.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails

AdminUsersDirectory

GET/api/v1/admin/users

Paginated directory search over email and name.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
queryquerystringno—
pagequeryinteger (int32)no—
pageSizequeryinteger (int32)no—

Request body

No request body.

Responses

GET/api/v1/admin/users/{userId}

One user's identity and setup summary.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails

AdulthoodHandover

GET/api/v1/identity/adulthood-handover/claim-context

Read the claim-context ("what you keep / what changes"). Seam: `getClaimContext`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
guardianshipIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
GET/api/v1/identity/adulthood-handover/handover-confirmation

Read the verified-majority handover confirmation: the live who-has-access set + the revocation date. Seam: `getHandoverConfirmation`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/adulthood-handover/key-claim/rekey-token

Mint the <b>one-shot</b>, 5-minute `purpose=majority-transition-rekey` token the now-adult presents to EPIC 1's `POST /api/v1/keys/wrapped-umk/majority-transition-rekey` to re-wrap their vault UMK under their own KEK (decision D-439, FR-30.011 / CC-070).

<b>Authorisation.</b> Requires an authenticated caller (class-level `[Authorize]`; no policy name, so nothing can 500 on an unregistered policy). The subject is taken from the caller's OWN claims via `GetUserIdFromClaims()` — there is deliberately no `{childId}`-style route or body parameter, so a guardian holding a perfectly valid session cannot request a key-custody token for the young adult: they would only ever mint one bound to their own (non-existent) majority claim and get a 404. <b>Status codes.</b> 404 when the caller has no majority claim (identical to the absent-record 404 elsewhere on this controller, so claim existence cannot be probed); <b>403</b> when the claim exists but is not yet `Verified` — the authority does not exist yet, which is a permission answer rather than the state-conflict 409 used for mis-sequenced challenge operations; 409 when a token was already issued (one shot). <b>Zero-knowledge.</b> The token authorises a re-wrap performed on the device. It carries only opaque identifiers; no key material passes through this endpoint.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/adulthood-handover/key-claim/resend

Resend the one-time code (rotates the code, no expiry). Seam: `resendKeyClaimCode`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/adulthood-handover/key-claim/start

Start the key-claim ceremony: issue a one-time-code identity-verification challenge (AAL2, no expiry). Seam: `startKeyClaim` (aka `verify/start`).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
POST/api/v1/identity/adulthood-handover/key-claim/verify

Verify the submitted one-time code and, on success, re-wrap the vault UMK to the now-adult and record the minor→adult identity change + revocation proof. Seam: `verifyKeyClaim` (aka `verify/submit`). Returns `200` with `verified=false` on a code mismatch (with remaining attempts), so the client can prompt a retry.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

AdviceAgencies

GET/api/v1/advice-agencies

The advice-agency register.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
includeWithdrawnquerybooleannoInclude agencies whose recognition has been withdrawn.

Request body

No request body.

Responses

200The register. — AdviceAgencyRow[]
403The caller is not a platform administrator. — ProblemDetails
POST/api/v1/advice-agencies

Recognises an organisation as an advice agency.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The agency's register row. — AdviceAgencyRow
400The request failed validation. — ProblemDetails
403The caller is not a platform administrator. — ProblemDetails
409The organisation is already on the register. — ProblemDetails
PUT/api/v1/advice-agencies/{organizationId}/adviser-capabilities

Replaces an agency's adviser permission ceiling — the set defined once at agency level rather than re-chosen by each client.

The set is a <b>ceiling, never a grant</b>. A relying service intersects it with what the client's own delegation conveyed, so widening it here can never authorise something a client did not consent to; narrowing it takes effect for every live case of the agency at once.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The agency's updated register row. — AdviceAgencyRow
400The capability set is empty or malformed. — ProblemDetails
403The caller is not a platform administrator. — ProblemDetails
404The organisation is not on the register. — ProblemDetails
409The agency's recognition is suspended or withdrawn. — ProblemDetails
POST/api/v1/advice-agencies/{organizationId}/standing

Suspends, restores or withdraws an agency's recognition.

A withdrawal de-authorises every adviser of the agency at once — authorisation is read as a conjunction, so no adviser row is rewritten — and reconciles their role claims, which are cached projections a still-valid token would otherwise carry past the withdrawal.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The agency's updated register row. — AdviceAgencyRow
400Unknown action, or a reason is missing where one is required. — ProblemDetails
403The caller is not a platform administrator. — ProblemDetails
404The organisation is not on the register. — ProblemDetails
409The transition is unavailable from the current standing. — ProblemDetails

AdviceAgencyAdvisers

GET/api/v1/advice-agency/advisers

The calling agency's own adviser register.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
includeInactivequerybooleannoInclude revoked registrations (the audit view).

Request body

No request body.

Responses

200The register plus its header counts and the agency permission set. — ProfessionalAdviserRegisterResult
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
POST/api/v1/advice-agency/advisers

Registers an individual onto the calling agency's adviser register, unverified.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The adviser's register row. — ProfessionalAdviserRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
404No account exists for the supplied adviser user id. — ProblemDetails
409The agency's recognition is suspended or withdrawn. — ProblemDetails
PUT/api/v1/advice-agency/advisers/{adviserUserId}/accreditation

Records or updates an adviser's own professional accreditation with their regulator.

Separate from identity verification: one establishes who they are, the other what they are accredited to do, and an agency commonly learns them at different moments. A creditor asked to accept a moratorium instruction is entitled to know which individual accreditation stands behind it, which the agency's own firm permission does not answer.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
adviserUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The adviser's updated register row. — ProfessionalAdviserRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
404No such adviser is on this agency's register. — ProblemDetails
409The registration has been revoked, or recognition is not in good standing. — ProblemDetails
POST/api/v1/advice-agency/advisers/{adviserUserId}/standing

Stands an adviser down, reinstates them, or revokes their registration.

A revocation is accepted even while the agency's own recognition is suspended: being unable to strike off a compromised adviser because your recognition lapsed would trap an agency at exactly the moment it most needs to act. It also ends every live case that adviser held <i>with this agency</i>, leaving those clients visibly unassigned rather than nominally advised by somebody who has left. A stand-down deliberately does <b>not</b> touch the caseload. A client whose adviser is on leave needs a named successor, so the handover stays an act a supervisor performs.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
adviserUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The adviser's updated register row. — ProfessionalAdviserRow
400Unknown action, or a reason is missing where one is required. — ProblemDetails
403No organisation claim, or the organisation is not on the register. — ProblemDetails
404No such adviser is on this agency's register. — ProblemDetails
409The transition is unavailable from the current standing. — ProblemDetails
POST/api/v1/advice-agency/advisers/{adviserUserId}/verification

Records that the adviser's identity has been verified, issuing the `professional-adviser` claim and making them assignable to a client case.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
adviserUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The adviser's updated register row. — ProfessionalAdviserRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
404No such adviser is on this agency's register. — ProblemDetails
409The registration has been revoked, or recognition is not in good standing. — ProblemDetails
GET/api/v1/advice-agency/caseload

The calling agency's caseload.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
clientUserIdquerystring (uuid)noOptional filter to one client — the "which of this agency's advisers held this case" read a regulator asks for. Combine with includeClosed for the full history.
includeClosedquerybooleannoInclude closed and handed-over assignments.

Request body

No request body.

Responses

200The caseload. — AdviserCaseloadResult
403No organisation claim, or the organisation is not on the register. — ProblemDetails
POST/api/v1/advice-agency/caseload

Puts a named adviser on a client's case.

Refused when the agency already has a live assignment for this client: opening a second one would leave two advisers each believing they hold the case. Hand it over instead, so the change of hands is recorded.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The new assignment. — AdviserCaseAssignmentRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
409The adviser is not currently authorised, or the client already has a live assignment. — ProblemDetails
POST/api/v1/advice-agency/caseload/{clientUserId}/end

Closes a client's case with no successor.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
clientUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The closed assignment. — AdviserCaseAssignmentRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not on the register. — ProblemDetails
404This agency holds no live assignment for the client. — ProblemDetails
POST/api/v1/advice-agency/caseload/{clientUserId}/reassign

Hands a client's case from its current adviser to another adviser of the same agency — the caseload reassignment the journey needs when an adviser goes on leave or leaves.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
clientUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The successor's assignment. — AdviserCaseAssignmentRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised agency. — ProblemDetails
404This agency holds no live assignment for the client. — ProblemDetails
409The successor is not currently an authorised adviser of this agency. — ProblemDetails

Assist

POST/api/v1/identity/assist/actions

Record a delegate-attributed assist action against an active session. The helper is always the authenticated caller (audit attribution). Returns `409` when the session has no active grant or is held by a different helper.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/assist/consent

Record a live account owner's consent to be assisted at first-run. The granter (oversight attribution) defaults to the authenticated caller — the consenting owner. Idempotent: the same owner re-consenting for the same helper on a live session returns `200` with the existing grant id; a session id that carries any other grant returns `409 assist-session-taken`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/identity/assist/non-custody-attestation/{sessionId}

Read the verifiable non-custody attestation for an assist session — the oversight-status read that proves the helper never accessed the owner's key or recovery material. Degrades honestly (`nonCustodyAttested=false`) if any breach was ever recorded.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
sessionIdpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
GET/api/v1/identity/assist/sessions/{sessionId}/actions

List the delegate-attributed action records for an assist session (the oversight-status action feed).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
sessionIdpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/assist/{grantId}/revoke

Revoke a consent-to-assist grant (clean teardown — "assistance ended").

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
grantIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

AssistedRecovery

POST/api/v1/auth/assisted-recovery/requests

Raise a delegated assisted-recovery request. Always returns `202 Accepted` with an opaque request reference for a well-formed request — a deliberate enumeration-safety property (the caller cannot distinguish a real managed identity from an unknown/unmanaged one). A malformed body returns `400` via the platform ProblemDetails handler (API-003) — including a `reason` the endpoint does not recognise, which is refused rather than rewritten (#8916). Omitting `reason` altogether is still accepted and defaults to `locked`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
GET/api/v1/auth/assisted-recovery/requests/{requestRef}

Read the current state of a delegated assisted-recovery case — journey step 1b, the logged-out, re-enterable status surface. Returns metadata only.

`[AllowAnonymous]` (SEC-002, explicit and inherited from the class): the subject is locked out and holds no token, so the opaque request reference is the only credential available to them. Rate-limited under the platform default policy (`essence-default`) — annotated explicitly rather than relied on implicitly, because this endpoint's risk profile is materially different from the raise endpoint's. <b>Zero-knowledge.</b> The response carries the reference, the case status, the subject's own stated reason, a machine rejection-reason slug, and two timestamps. It carries no email, no organisation identity, no helpdesk approver identity, no proofing evidence and no key material. <b>Security trade-off — stated, not hidden.</b> The raise endpoint returns a uniform `202` with an opaque reference whether or not the work email resolves to a real managed identity. This endpoint makes those two cases distinguishable <em>to the holder of a reference</em>: a reference minted for a real managed identity resolves, while a synthetic one returns `404`. That is an account-existence / org-membership oracle for anyone who can submit an email and then poll the reference they were handed back. It was accepted rather than eliminated because the alternative — refusing the subject any view of their own case — is the gap this endpoint exists to close, and because the positive case is <b>loud</b>: minting a resolvable reference also creates a visible entry in that organisation's helpdesk queue, so the probe is not silent. The residual exposure is further bounded by per-IP rate limiting and by the reference being an unguessable 128-bit value (a reference cannot be <em>enumerated</em>, only replayed after being issued). A stricter, distributed, per-reference limiter for this endpoint is a real improvement that is NOT in place: the service currently registers only the platform default policy.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
requestRefpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/auth/assisted-recovery/requests/{requestRef}/complete

Complete a delegated assisted recovery — journey step 4. The subject redeems the CC-061 authorise-only recovery token their helpdesk's authorisation minted and sets a new, client-derived credential.

`[AllowAnonymous]` (SEC-002, explicit): the subject is by definition unable to authenticate — that is the situation being recovered from. The endpoint is not unauthenticated in effect: possession of the single-use recovery token bound to an <em>authorised</em> case IS the credential, and both conditions are checked server-side before anything is mutated. <b>A helpdesk agent cannot complete a recovery here.</b> No role, claim, or org membership grants access to this endpoint — there is nothing to grant, because it is anonymous. What it requires is the token minted by the escrow grant and bound to the case, which is not something authorising confers on the authoriser. <b>Zero-knowledge.</b> `newPasswordHash` is the client-derived verifier, the same contract as `POST /auth/change-password`. No plaintext credential and no key material is ever transmitted; the subject re-wraps their own keys on-device. <b>Out-of-band delivery of the token to the subject is NOT implemented in this service.</b> The escrow grant returns the token reference to the authorising admin; getting it to the locked-out subject is a Notifications-owned seam. This endpoint validates whatever token the subject presents — it does not, and must not, mint or resend one.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
requestRefpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails

Auth

POST/api/v1/auth/account/deactivate

Closes the authenticated user's account at their own request (holder-account lifecycle procedure §3 T5). Requires a fresh GPG 44 medium step-up (DVS-7.2b).

The closure schedules the crypto-shred of the account's wrapped keys, recovery shares and ciphertext for the end of the 14-day grace window (DVS-7.2), so a bearer token alone is not enough: a fresh (≤ 5 minutes) `act=account-deactivation` elevation on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IAccountClosureStepUpGate), proved with a passkey, an authenticator-app or text-message code, or the password for an account with none of those; never an emailed or backup code. The closure alert's email carries a single-use link that cancels it until Essence.Identity.Auth.Application.Commands.DeactivateUserResult.CancelBy (`POST account/closure/cancel`), because a closed account cannot sign in.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Account closed — DeactivateUserResult
401Unauthorized, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
503No cancel link could be minted, so nothing was closed — ProblemDetails
POST/api/v1/auth/discover

Global home-realm discovery broker (EPIC 9 FR-09.032/033). Resolves a sign-in identifier — a general user's email, or an org-branded `host` — against the <b>EPIC 3 Global Registry only</b>, and returns where the sign-in should be brokered to complete: the resolved instance's OIDC authorize endpoint, the registry-signed short-TTL realm descriptor, and an opaque continuation `state`.

Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute — discovery necessarily runs BEFORE authentication. <b>No credentials transit Global (FR-09.033).</b> This endpoint issues a REDIRECT TARGET, nothing more. The completing instance authenticates the user and mints the token with its own `iss_instance`, which is what lets EPIC 3's `FederationTrustGate` govern downstream acceptance. Global never sees a password, an authorization code, or key material. <b>Enumeration-safety in body AND timing (NFR-09.020).</b> Every outcome — resolved, unknown identifier, unbound org host, registry unreachable — returns 200 with the identical response shape, and an unresolved lookup is answered with the region-default realm rather than an empty or error result. An unbound org host falls back to the registry's own default-region descriptor (a second registry call) specifically so the fallback carries a real signature: a fallback with an empty `realmToken` would be as good an oracle as a 404. Every response is then padded to a configured floor, because a registry hit does strictly more work than a miss and response time would otherwise leak what the body does not. <b>Keyed on the DOMAIN, never the local-part (#8633).</b> A submitted `email` is reduced to its domain in-process, and only the domain reaches the registry; the address is never stored, logged, or forwarded. Clients that prefer not to send the address at all may supply `domain` directly. Resolution used to key on the SHA-256 of the whole address, which is no less zero-knowledge and was still an account-existence oracle — a hash does not anonymise an input the caller chooses, so the region came back as a statement about that named individual, disclosing which sovereign holds their vault to an anonymous stranger. FR-09.035 already keys org SSO discovery on the work-email domain only, for this reason.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The realm to broker to. Shape is identical for resolved and unresolved. — DiscoverRealmResponse
POST/api/v1/auth/email/resend-otp

(Re)issues an in-app email-verification OTP for the authenticated user (in-app-otp-email-verification). Rate-limited per user per hour.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Code sent (or a non-rate-limit no-op, e.g. already verified). — ResendEmailVerificationOtpResult
401Unauthorized. — ProblemDetails
429Resend rate limit exceeded. — ProblemDetails
POST/api/v1/auth/email/resend-otp/by-email

Sends a fresh registration email-verification code to an address, WITHOUT a session (#7539) — the companion to M:Essence.Identity.Auth.Api.Controllers.AuthController.VerifyEmailOtpByEmail(Essence.Identity.Auth.Api.Controllers.VerifyEmailOtpByEmailRequest,System.Threading.CancellationToken) for a code that expired while the tab was closed.

`[AllowAnonymous]` (SEC-002, explicit) for the same reason as its sibling: no session exists. The answer is the SAME on every path — registered or not, verified or not, inside the account's 5/hr allowance or past it — so this is not an existence oracle and a 200 is never a promise that a message was sent. The account's own allowance still governs delivery, and a per-address burst ceiling inside the handler bounds how fast a stranger can put mail in somebody else's inbox.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

202Request accepted. If that address needs verifying, a code is on its way.
400Malformed body. — ProblemDetails
429Request ceiling reached for this address. — ProblemDetails
POST/api/v1/auth/email/verify-otp

Verifies the authenticated user's email using the in-app OTP code (in-app-otp-email-verification). On success the caller's session tokens are rotated so they reflect the verified state.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Email verified; rotated tokens returned. — VerifyEmailOtpResult
400Incorrect, expired, or exhausted code. — ProblemDetails
401Unauthorized. — ProblemDetails
POST/api/v1/auth/email/verify-otp/by-email

Redeems a registration email-verification code WITHOUT a session (#7539) — the route back for someone who closed the tab at the email gate.

`[AllowAnonymous]` (SEC-002, explicit). The caller has, by definition, no session: that is the entire condition this endpoint exists to serve. Registration emails only the 6-digit code, and until this existed the ONLY endpoint that could spend it was the `[Authorize]` twin above — so closing the browser tab created an account that could neither be signed into (the address is unverified) nor re-registered (the address is taken). AC-44.006 / FR-44.003 promise a sign-up can be resumed after closing the browser; the onboarding session honoured that, this gate could not. <b>It issues no session.</b> On success the email is verified and the caller is told to sign in — no access token, no refresh token, no cookie. Possession of a mailbox proves an address; it does not authenticate a person, and a 6-digit emailed code must never become a factor that mints a session around the password. <b>Uniform negatives.</b> Unknown address, no outstanding code, wrong code, expired code, exhausted attempts and an already-verified address all return the IDENTICAL 400 — one title, no detail — so the response is not an oracle for the account's verification or code state, and since `POST /register` answers uniformly (#7225, on by default since DVS-4.12) it is one of the anonymous sign-up steps that must not tell a registered address from a new one either. Rate-limited twice: the platform default per IP (`essence-default`, SEC-004) and a per-address ceiling inside the handler that is charged before any lookup, so a caller past it costs nothing and an unregistered address reaches it at the same count as a registered one. The outstanding code keeps its own per-code attempt cap underneath both.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Code accepted; the email is now verified. Sign in to continue. — VerifyEmailOtpByEmailResponse
400Malformed body, or the code was not accepted (uniform). — ProblemDetails
429Attempt ceiling reached for this address. — ProblemDetails
POST/api/v1/auth/login

Authenticates a user and returns access/refresh tokens.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

  • LoginCommand as application/*+json, application/json, text/json

Responses

200Login successful — LoginResult
400Invalid request data — ProblemDetails
401Invalid credentials or account locked — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/auth/login-methods

Region-aware login-method presentation policy (EPIC 9 FR-09.036). Returns the ordered list of login methods the completing instance should present for a given region — organisation enterprise SSO first (when a federated + entitled work-email `domain` is supplied), then the region national IdP (AE → UAE PASS, GB → GOV.UK One Login), then passkey + email — honouring the org's SSO-only enforcement. The login UI renders from this list instead of a hardcoded button set. Anti-enumeration: an unknown/unfederated domain simply yields the general-user list (no org SSO), identical to supplying no domain.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
regionquerystringnoCompleting instance region (ISO-3166 alpha-2, e.g. "GB"). Optional — an empty/missing region falls back to the universal method set (passkey + email) rather than a validation error, since ApiController model binding would otherwise reject a non-nullable string as a required field.
domainquerystringnoOptional work-email domain (ZK — domain only, never local-part).

Request body

No request body.

Responses

GET/api/v1/auth/login/device-approval/{token}

Polls the outcome of a Tier A new-device approval request (spec §5.1). The new device calls this with the opaque token from the login response; while a trusted device has not yet decided it returns `{ status: "pending" }`. On the first `approved` poll it issues the session tokens exactly once; subsequent polls return `approved` without re-issuing.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenpathstringyesThe opaque approval-poll token.

Request body

No request body.

Responses

200Current status (with tokens on the first approved poll). — PollDeviceApprovalResult
POST/api/v1/auth/login/device-limit

Continues a sign-in paused at the device allowance (ruling 2026-10-01): signs out the chosen devices and, if that frees a place, issues the session the paused sign-in earned.

Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute (SEC-002, explicit): the person has proved their factors but holds no session on this device yet. Authorisation is possession of the single-use `deviceLimit.challengeToken`, the same footing as `login/mfa`. A choice that frees nothing answers `200` with `deviceLimitReached` and a rotated token.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Session issued, or still at the limit (see `deviceLimitReached`). — LoginResult
400Invalid request data. — ProblemDetails
401The challenge is unknown, used or expired. — ProblemDetails
POST/api/v1/auth/login/mfa

Completes a login that required multi-factor authentication.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200MFA verified; session issued. — LoginResult
400Invalid request data. — ProblemDetails
401Invalid/expired challenge or incorrect code. — ProblemDetails
POST/api/v1/auth/login/mfa/resend

Re-issues the one-time code for a login that is paused on its second factor (#6166).

Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute (SEC-002, explicit): the caller has cleared the password factor but has no session yet, so the authenticated send endpoints (`POST /api/v1/mfa/send/email`) are unreachable to it. Authorisation is possession of the pending challenge token — the same credential `login/mfa` accepts on this same anonymous footing, and the reason the verify screen previously had no resend at all. Always `200`, including when nothing was sent. The outcome is in `status` (an `OtpDeliveryStatus`): the whole point of this endpoint is that a screen can tell a rate limit from an expired attempt from a dead channel and say the right thing, which a bare 4xx cannot express. It also means a caller cannot use the status code to distinguish a live challenge token from a dead one.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Resend outcome — see `status`; `sent` may be false. — ResendLoginMfaCodeResult
400Invalid request data. — ProblemDetails
POST/api/v1/auth/logout

Logs out a user by revoking the session.

The request body is optional. A browser SPA has no refresh token available to JavaScript (it never leaves the httpOnly cookie / server), so its logout call sends NO body at all — it identifies the session purely from the caller's own JWT/cookie. When no refresh token is supplied, the caller MUST be authenticated; the session is then resolved from the authenticated access token's `jti` claim, never from client input. Callers that DO send a valid `{ "refreshToken": "..." }` body keep working exactly as before, without needing to be authenticated (e.g. logging out with an already- expired access token but a still-valid refresh token).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Logout successful — LogoutResult
400Invalid request data — ProblemDetails
401No refresh token supplied and the caller is not authenticated — ProblemDetails
GET/api/v1/auth/org-idp/resolve

Organisation SSO directory resolution (EPIC 9 FR-09.035) — the server side of the frontend `orgSsoResolution.ts` seam. Resolves the org IdP record from a verified work-email `domain` (ZK — keyed on the domain only, never the local-part). Returns `{ "org": null }` uniformly for an unknown OR a non-federated/disabled domain so org existence is not enumerable (NFR-09.020).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
domainquerystringnoVerified work-email domain, lower-cased. Optional — an empty or missing domain yields the same uniform `{ "org": null }` as an unfederated one. The parameter is nullable for the same reason as M:Essence.Identity.Auth.Api.Controllers.AuthController.GetLoginMethods(System.String,System.String,System.Threading.CancellationToken)'s `region` (ISS-5): under `[ApiController]` a non-nullable `string` query parameter is implicitly required, so model validation would reject the empty case with a 400 <i>before</i> the guard below ever runs — leaving that guard unreachable and making the empty domain distinguishable from every other input, contrary to NFR-09.020.

Request body

No request body.

Responses

POST/api/v1/auth/password/change

Changes the authenticated user's password (FR-09.013). Requires the current password for re-authentication. On success ALL of the user's active sessions are revoked and the outstanding access tokens blacklisted — the client must re-authenticate.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Password changed, sessions revoked — ChangePasswordResult
400Current password incorrect or new password invalid — ProblemDetails
401Unauthorized — ProblemDetails
POST/api/v1/auth/password/set

Sets the FIRST password on the authenticated account when it has none (a social / passkey-only account). Sibling of `password/change` (FR-09.013) for accounts with no current credential to re-authenticate against. `passwordHash` is the client-derived hash — exactly as on `register` — never a plaintext password; the server wraps it in Argon2id before persisting. Sessions are NOT revoked.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

204Password set
400Password hash missing or malformed — ProblemDetails
401Unauthorized — ProblemDetails
409Account already has a password — use `password/change` — ProblemDetails
DELETE/api/v1/auth/recovery-phrase

Clears the authenticated user's recovery-phrase proof. Idempotent: clearing an account with no proof enrolled also returns `204`.

Requires a fresh (≤ 5 minutes) `act=recovery-settings-change` elevation (DVS-4.4c): removing the phrase takes a way back into the account away from the holder.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

204Recovery proof cleared (or none was enrolled)
401Unauthorized, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/auth/recovery-phrase/enrol

Enrols (or re-enrols) the authenticated user's recovery-phrase proof. `recoveryProof` is the client-derived proof (hex, ≥ 64 chars) — never the phrase, never the seed; the server wraps it in Argon2id before persisting. Re-enrolment replaces the previous proof.

Requires a fresh (≤ 5 minutes) `act=recovery-settings-change` elevation on `X-Step-Up-Token` (DVS-4.4c): whoever enrols a phrase can later recover the account with it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

204Recovery proof enrolled
400Recovery proof missing or malformed — ProblemDetails
401Unauthorized, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/auth/recovery-phrase/token

Verifies a recovery-phrase proof for a user who has forgotten their password and, on success, mints the one-shot, 5-minute `purpose=recovery-rewrap` token that MultiDeviceSync accepts on `GET /api/v1/keys/wrapped-umk/recovery-phrase` and `POST /api/v1/keys/wrapped-umk/recovery-rewrap`.

`[AllowAnonymous]` (SEC-002, explicit): the caller has, by definition, no session. Rate-limited under the platform default policy (`essence-default`, SEC-004) — the same policy every other anonymous credential surface in this service uses; a wrong proof against a real account also increments the account's brute-force lockout counter (FR-09.010/011), so this surface cannot be used to guess around the login lockout. <b>Enumeration-safe.</b> Unknown email, no recovery phrase enrolled, wrong proof, inactive and locked-out accounts all receive the IDENTICAL `401` ProblemDetails (`title = "Recovery phrase not accepted"`, no `detail`) after a full Argon2id verification, so neither the body nor the timing is an account-existence or recovery-enrolment oracle. <b>Zero-knowledge.</b> The proof is not the phrase and cannot derive the vault KEK; the token carries only opaque identifiers. Auth does not reset the password (FR-05.082).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Proof accepted; one-shot re-wrap token issued — RecoveryRewrapTokenResponse
400Email or proof malformed — ProblemDetails
401Recovery phrase not accepted (uniform) — ProblemDetails
429FR-01.009 attempt ceiling reached for this email — ProblemDetails
POST/api/v1/auth/refresh

Refreshes an access token using a refresh token.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Token refreshed successfully — RefreshTokenResult
400Invalid request data — ProblemDetails
401Invalid or expired refresh token — ProblemDetails
POST/api/v1/auth/register

Registers a new user account.

`[AllowAnonymous]` (SEC-002, explicit): the caller has no account yet, by definition. <b>Uniform answer (#7225, EPIC 9 contract, when `Registration:UniformResponse` is on — the code default since DVS-4.12; staged off on Global, decision P-18).</b> The response is `202``{ "next": "verify-email" }`, byte-identical for a free address and a taken one. The body is a constant built here: it does not depend on anything the handler learned, so the two cases cannot drift apart through it. No tokens and no cookie. The account's first session comes from sign-in, after the emailed code is redeemed at `POST email/verify-otp/by-email`. A per-address ceiling answers `429`, and it is charged before the lookup. <b>Legacy answer (switch off).</b> `200` with tokens, or `409` for a taken address. This is the disclosure #7225 removes. It remains only until the callers that read the tokens have migrated.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Legacy: user registered, tokens issued. — RegisterUserResult
202Accepted: check your email (uniform; says nothing about the address). — RegistrationAcceptedResponse
400Invalid request data — ProblemDetails
409Legacy: email already exists — ProblemDetails
428DVS-4.12: this network has made many sign-ups this hour; solve `proofOfWork` and send again. — ProblemDetails
429Registration ceiling reached for this address (uniform only). — ProblemDetails
POST/api/v1/auth/registration/abandon

Releases the authenticated user's <b>unverified</b> registration (#7964) so the address it holds can be registered again.

The exit from the email-verification gate for someone who mistyped their address. Until this existed the screen offered "sign out and register again", and that advice could not be followed: the unverified `users` row still held the address, so `POST /register` refused it with 409. The address was burned — permanently, and most painfully when the typo landed on somebody else's real address. <b>This releases; it does not amend.</b> FR-44.024 originally asked for an in-place email change. The ruling on #7964 amended it, because on this platform the email is the PBKDF2 salt behind both the stored credential and the UMK: amending it under a hash derived from the old address locks the user out and orphans their keys. Releasing costs the same password re-entry and risks nothing. Subject comes from the bearer token's `sub`, never the body (SEC-002 + the same pattern as `account/deactivate`) — a body-supplied id would make this an arbitrary-account eraser. Idempotent: releasing an already-released registration answers 204, because the effect the caller asked for is already true.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

204Registration released; the address is free.
401Unauthorized. — ProblemDetails
409The address is already verified — changing it is an account-settings credential rotation, not this endpoint. — ProblemDetails
POST/api/v1/auth/users/{userId}/unlock

Unlocks a locked user account. Requires admin role.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesUser ID to unlock

Request body

No request body.

Responses

200Account unlocked successfully — UnlockAccountResult
401Unauthorized — ProblemDetails
404User not found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/auth/validate-token

Validates an access token and returns user information. Used for service-to-service authentication.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Token validated successfully — TokenValidationDto
400Invalid request data — ProblemDetails
GET/api/v1/auth/verify-email

Verifies a user's email address from the link in the verification email.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenquerystringnoThe single-use verification token from the email link.

Request body

No request body.

Responses

200Email verified (or already verified). — VerifyEmailResult
400Token missing, invalid, or expired. — ProblemDetails

BillingProfileDirectory

GET/api/v1/internal/directory/users/{userId}/billing-profile

Resolves the bill-to name and email of a user.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe user the invoice is addressed to.

Request body

No request body.

Responses

200The lookup completed. `exists=false` means no account that has not been erased resolves to the id. — BillingProfileDto
401No valid bearer token. — ProblemDetails
403The caller is not Billing's bill-to service principal. — ProblemDetails

BiometricReenrolment

POST/api/v1/biometric-reenrolment

Opens a re-enrolment session for the caller's biometric-mismatch lockout and raises the re-establishment-required alert. Reachable while locked out: a recovery-scoped step-up token is a validly-signed Essence JWT and passes the bearer scheme, exactly like a full session (mirrors Essence.Identity.Auth.Api.Controllers.TakeoverController). The subject is taken from the caller's own `sub` claim, and the org from the `organization_id` claim when present.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The opened session (opaque reference + deep-link + coarse state). — BiometricReenrolmentResult
400Bad Request — ProblemDetails
401No authenticated subject. — ProblemDetails
GET/api/v1/biometric-reenrolment/oversight

The org oversight worklist: members of the caller's org whose biometric re-enrolment is in-progress / stalled. Scoped strictly to the caller's own `organization_id` claim, so cross-org reads are impossible by construction (no route org to forge).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The in-flight cohort (opaque member ref, coarse status, step, elapsed). — BiometricReenrolmentOversightResult
403The caller has no org context (not an org administrator). — ProblemDetails
POST/api/v1/biometric-reenrolment/{assuranceRef}/advance

Advances the caller's own in-flight session to a new coarse step.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
assuranceRefpathstringyes—

Request body

Not marked as required in the document.

  • StepRequest as application/*+json, application/json, text/json

Responses

200The updated session state. — BiometricReenrolmentResult
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404No such session for this owner. — ProblemDetails
POST/api/v1/biometric-reenrolment/{assuranceRef}/resolve

Resolves the caller's own session terminally — re-established or cancelled.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
assuranceRefpathstringyes—

Request body

Not marked as required in the document.

Responses

200The resolved session state. — BiometricReenrolmentResult
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404No such session for this owner. — ProblemDetails

CookieSession

POST/api/v1/auth/session

Establishes an httpOnly cookie session from the current JWT. The caller must present a valid JWT in the Authorization header. On success, issues: - `essence_auth`: httpOnly + Secure + SameSite=Strict cookie containing the JWT. - `essence_csrf`: readable (non-httpOnly) + Secure + SameSite=Strict cookie containing a random CSRF token. Returns 204 No Content on success.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

204Cookie session established.
401No valid JWT in Authorization header. — ProblemDetails
404Cookie session feature is disabled. — ProblemDetails
GET/api/v1/auth/session/me

Returns the authenticated user's basic identity claims. Used by frontends in cookie-session mode to determine `isAuthenticated` without parsing the JWT (which is httpOnly and invisible to JavaScript).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200User identity claims. — SessionMeResponse
401Not authenticated. — ProblemDetails
404Cookie session feature is disabled. — ProblemDetails
POST/api/v1/auth/session/revoke

Revokes the cookie session by clearing both cookies.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

204Cookie session revoked.
404Cookie session feature is disabled. — ProblemDetails

CustodialEstablishmentPolicy

GET/api/v1/identity/custodial-establishment-policy

Read the policy governing a jurisdiction.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
jurisdictionquerystringnoISO-3166 alpha-2 code.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

CustodialOrders

GET/api/v1/identity/custodial-orders

List the caller's own submitted custodial orders, most recent first.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

POST/api/v1/identity/custodial-orders

Submit a custodial order for verification.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Created — CustodialOrderResult
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/identity/custodial-orders/pending

The identity-authority queue: pending orders awaiting a recorded decision, oldest first (#13747). Every read is audited — who looked, not only who decided — because the list enumerates children subject to live custodial proceedings. The role spans every jurisdiction; jurisdiction can only narrow it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
jurisdictionquerystringno—
cursorquerystringno—
pageSizequeryinteger (int32)no—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
GET/api/v1/identity/custodial-orders/{orderId}

Read a custodial order's verification state.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orderIdpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/custodial-orders/{orderId}/child-identity

Provision the child's new legal identity under this verified order (debt-2026-08-13-220). The new principal carries no attribute, alias or key derived from the pre-adoption identity.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orderIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/custodial-orders/{orderId}/decision

Record, as a platform operator, the decision the external authority made on a pending order. Restricted to identity-authority callers. The verdict is stored as operator-transcribed (#13747) — the operator did not decide, the authority did.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orderIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

DelegateAccess

GET/api/v1/identity/delegate-access/grants

List delegate-access grants. `role=principal` (default) lists the grants the caller has issued ("who can act for me"); `role=delegate` lists the grants the caller holds (the "Act as" selector).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
rolequerystringno—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/delegate-access/grants

Grant delegate access to an assistant / helper. The principal (the account owner delegating) is, by default, the authenticated caller. Idempotent: re-granting for the same delegate + delegation returns `200` with the existing grant id (never a duplicate).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
GET/api/v1/identity/delegate-access/grants/organisation

Every principal↔delegate pair in the caller's organisation, one keyset page at a time (#14066, debt-2026-08-11-791) — the exec office's roster: one assistant covering four executives, an executive's primary and holiday cover, a leaver whose every delegation must end. Ending a pair stays the per-grant revoke, so each keeps its own closure record. Organisation administrators only (`OrgOwner` / `OrgAdmin`). The organisation is bound from the caller's org claim; there is no parameter naming it, and an `X-Organization-Id` header that names a different one is refused rather than ignored.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
cursorquerystringno—
pageSizequeryinteger (int32)no—

Request body

No request body.

Responses

200One page of the roster; an empty page is a true empty state. — OrganisationDelegateAccessPairDtoCursorResult
400The cursor is not one this roster issued. — ProblemDetails
401Unauthorized — ProblemDetails
403Not an administrator, no org claim, or a contradicting org header. — ProblemDetails
POST/api/v1/identity/delegate-access/grants/{id}/revoke

Revoke a delegate-access grant (clean teardown of the acting-as authority). Only the principal, the delegate, the issuer, or an administrator of an organisation both parties belong to may revoke; anyone else gets the same 404 as for an unknown id (#20297).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/delegate-access/sessions

Establish a scoped acting-as session (the "Act as [Principal]" selection). The caller must be the grant's own delegate and the grant must be active. Returns a short-lived delegated-session token plus the acting-as bar context.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
GET/api/v1/identity/delegate-access/sessions/context

Read the live acting-as context the persistent "Acting as [Principal]" bar renders from. Only the grant's own delegate can read it; it degrades the instant the grant is revoked or expires (`isActive=false`).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
grantIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

DelegatedAgents

GET/api/v1/identity/agents

Lists the caller's own agents and their containment state.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/agents

Registers an AI agent to act on the caller's behalf. The credential secret is in the response body and is never retrievable again — only its hash is stored.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
POST/api/v1/identity/agents/token

Exchanges an agent credential for a short-lived agent session. Anonymous because the credential IS the authentication — an agent has no prior session to present.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
PUT/api/v1/identity/agents/{agentReference}/key

Registers — or replaces — the agent's EC P-256 public key (agent-gateway CONTRACTS §1). The body is one public JWK with exactly `kty`, `crv`, `x` and `y`; a JWK carrying private material (`d`) or any other member, key type or curve is refused 400. Once registered, every access token the agent is issued carries `cnf.jkt` = the key's RFC 7638 thumbprint, binding it to proof of possession. Callable only by the agent's own principal. An agent cannot set its own key: its token's `sub` is its reference, not a user id, so it never resolves to a caller.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
agentReferencepathstringyes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/agents/{agentReference}/suspend

Cuts an agent's credential and every live session it holds, for a named EPIC 12 incident, and returns the suspension reference the containment chain records. Callable by the agent's own principal (cutting off their own agent) or by an incident responder. Idempotent: a retried containment leg returns the same suspension reference rather than minting a second suspension.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
agentReferencepathstringyes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails

DeviceApprovals

GET/api/v1/auth/device-approvals

Lists the caller's own pending new-device approval requests.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The caller's pending requests (possibly empty). — PendingDeviceApprovalDto[]
401Unauthorized. — ProblemDetails
POST/api/v1/auth/device-approvals/{id}/approve

Approves a pending new-device request raised against the caller's account.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

204Approved.
401Unauthorized. — ProblemDetails
403The request belongs to another account. — ProblemDetails
404No such request. — ProblemDetails
409The request was already resolved. — ProblemDetails
POST/api/v1/auth/device-approvals/{id}/deny

Denies a pending new-device request raised against the caller's account.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

204Denied.
401Unauthorized. — ProblemDetails
403The request belongs to another account. — ProblemDetails
404No such request. — ProblemDetails
409The request was already resolved. — ProblemDetails

Devices

GET/api/v1/devices

Get all devices for the authenticated user

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200OK — DeviceDto[]
401Unauthorized — ProblemDetails
GET/api/v1/devices/{id}

Get a specific device by ID

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesDevice ID

Request body

No request body.

Responses

200OK — DeviceDto
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
DELETE/api/v1/devices/{id}

Delete a device and revoke all its sessions

Requires a step-up elevation on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IDeviceRevocationStepUpGate, #8641): the revoke is irreversible, so a live session is not sufficient authority for it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesDevice ID
deferRotationquerybooleannoThe FR-01.049 re-keying choice the account holder made (debt-2026-06-18-331, journey `lost-device-revocation-and-session-hygiene`). `false` — the secure default, "Rotate my keys now". `true` — the user explicitly chose "Lock out later" and acknowledged the residual-access window, so the deferral and the window they accepted are recorded on the audit-anchored `DeviceRemovedEvent` (`RekeyAction == "deferred-warned"`) instead. The SPA (`multiDeviceSyncApi.removeDevice`) has always appended `?deferRotation=true` for the deferred path, but this action bound no such parameter, so the user's consent decision about their own device security was discarded while the dialog reported success and promised "this choice is recorded in your activity log". Binding it here keeps that promise, and matches MultiDeviceSync's `DevicesController.RemoveDevice` on the sibling path.
reasonquerystringnoWhy the owner is removing the device (FR-01.049, #11394): `user-initiated` (the default), `lost` or `stolen`. Recorded on the audit-anchored `DeviceRemovedEvent.Reason`; any other value is refused 400.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/devices/{id}/block

Block a device (suspicious activity or user-initiated)

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesDevice ID

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
PUT/api/v1/devices/{id}/name

Update the friendly name of a device

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesDevice ID

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/devices/{id}/trust

Trust a device ("Remember this device" functionality)

Requires a fresh (≤ 5 minutes) `act=recovery-settings-change` elevation on `X-Step-Up-Token` (DVS-4.4c): a trusted device skips new-device verification and can approve other devices' sign-ins, so marking one trusted changes how the account can be got back into.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesDevice ID

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

DomainDetections

GET/api/v1/auth/domain-detections

Returns the accounts detected on one of the caller's organisation's verified domains.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
domainquerystringno—

Request body

No request body.

Responses

200The detection run and the accounts it matched. — DomainDetectionResult
400No domain was supplied. — ProblemDetails
403The caller carries no organisation claim, or the header contradicts it. — ProblemDetails
404The caller's organisation holds no current ownership proof for that domain — which is also the answer when the domain was never proven or belongs to another organisation. — ProblemDetails
POST/api/v1/auth/federated-accounts/uae-pass

Resolves (or provisions) the Essence account behind a verified UAE Pass subject.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The account the subject is linked to; `isNewUser` when this call created it. — UaePassAccountLinkResponse
400The subject is missing or malformed. — ProblemDetails
401No valid bearer token. — ProblemDetails
403The caller is not the UAE Pass account linker, or the linked account is deactivated (`reason: federated_account_deactivated`). — ProblemDetails

FieldAttestations

GET/api/v1/identity/attestations/contact

Lists every contact-field provenance attestation for the authenticated subject so the present primitive can stamp each outbound field in one call.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/attestations/contact

Records (or refreshes) a contact-field provenance attestation for the authenticated subject. Seam: `contactAttestationApi.attest` (debt-2026-07-03-216).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/identity/attestations/contact/{fieldKey}

Reads the provenance attestation for one presented contact field of the authenticated subject. Seam: `contactAttestationApi.get` (debt-2026-07-03-216).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
fieldKeypathstringyes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/attestations/professional

Records (or refreshes) a professional-credential attestation for the authenticated subject. Seam: `professionalAttestationApi.attest` (debt-2026-07-04-024).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/identity/attestations/professional/{fieldKey}

Reads the professional-body attestation metadata for one listing field of the authenticated subject. Seam: `professionalAttestationApi.get` (debt-2026-07-04-024).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
fieldKeypathstringyes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

Guardianships

POST/api/v1/identity/guardianships

Establishes a named guardianship over a supervised minor (Step 1 of the wizard).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201The guardianship was established. — GuardianshipResultDto
400Missing/invalid fields, or the primary-guardian invariant is violated. — ProblemDetails
403Forbidden — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/identity/guardianships/{childId}/guardians

Returns the current guardian roster for a supervised minor (per-child console).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
childIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The guardian roster. — GuardianRosterDto
404No guardianship for this minor that the caller holds an active seat on (the same answer for "not yours" and "does not exist", #19329). — ProblemDetails
POST/api/v1/identity/guardianships/{childId}/guardians

Adds a scoped secondary guardian (co-guardian / successor-guardian / delegated-care-manager) to an active guardianship. A successor is added inactive (standby) until activated.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
childIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The updated guardian roster. — GuardianRosterDto
400Invalid role/relationship, a duplicate guardian, or a transitioned guardianship. — ProblemDetails
403Forbidden — ProblemDetails
404No guardianship for this minor. — ProblemDetails
DELETE/api/v1/identity/guardianships/{childId}/guardians/{guardianId}

Removes a secondary guardian seat (the primary guardian can never be removed).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
childIdpathstring (uuid)yes—
guardianIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The updated guardian roster. — GuardianRosterDto
400The seat is the primary guardian, not found, or the guardianship has transitioned. — ProblemDetails
403Forbidden — ProblemDetails
404No guardianship for this minor. — ProblemDetails
POST/api/v1/identity/guardianships/{childId}/guardians/{guardianId}/activate

Activates a standby successor guardian so it begins to hold authority.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
childIdpathstring (uuid)yes—
guardianIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The updated guardian roster. — GuardianRosterDto
400The seat is not a successor, not found, or the guardianship has transitioned. — ProblemDetails
403Forbidden — ProblemDetails
404No guardianship for this minor. — ProblemDetails
POST/api/v1/identity/guardianships/{childId}/transition

Commits the majority authority-transfer for a supervised minor: revokes guardian authority and anchors the transition audit.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
childIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The transition was recorded. — TransitionAuditResultDto
400Invalid decisions, or the guardianship has already transitioned. — ProblemDetails
404No active guardianship for this minor that the caller may end — only the minor themself or the primary guardian may (the same answer for "not yours" and "does not exist", #22778). — ProblemDetails

IdentityAssurance

GET/api/v1/identity/assurance

Reads the full authoritative assurance record, or 404 when none exists yet.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
GET/api/v1/identity/assurance/community-vouched

Lists accounts whose identity assurance rests on <b>community vouching</b>, with the level they hold and whether their assurance is current, expiring or stale — the oversight worklist for journey `community-vouching-onboarding-no-id` (debt-2026-06-06-143, and the admin half of debt-2026-06-06-140). Admin-scoped: this is a cross-account view, so it is gated on the platform-admin policy rather than on the caller being the subject. It returns no name, no email and no evidence — a level, a provenance, two instants and an opaque anchor reference per row. The <b>attester chain</b> (who vouched, from which organisation, and the anti-collusion verdict on the set) is EPIC 36's evidence and is deliberately not served here; the oversight surface reads it from EPIC 36 and says so when it is unavailable.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
limitqueryinteger (int32)no—
expiringWithinDaysqueryinteger (int32)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
GET/api/v1/identity/assurance/policy

Returns the authoritative proofing policy for the authenticated account, or the documented per-actor default (`isDefault=true`) when none is recorded yet. Capability (b).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
invitedByOrgquerybooleanno—
orgNamequerystringno—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/assurance/proofing

Initiates an identity-proofing session for the authenticated account and returns it (an existing live session is returned rather than duplicated). Capability (c).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/identity/assurance/proofing/{sessionId}/complete

Records the <b>subject-reported</b> outcome of their own proofing session. This endpoint can only record a non-success outcome (failure/abandonment). A successful proofing lifts the account's authoritative assurance level, so it must be adjudicated by the proofing provider — the subject cannot assert their own success. Attempting to do so returns 403.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
sessionIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/assurance/record

Records the identity assurance level the authenticated account has reached at first-run as the authoritative EPIC 9 record, establishing its proofing policy. Idempotent upsert. Capability (a)+(b).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
POST/api/v1/identity/assurance/recovery-decision

Records the account holder's first-run recovery decision (recovery set up vs deferred) on the authoritative assurance record so the compliance-evidence view can retrieve / filter / export it from the authoritative EPIC 9 store (debt-2026-07-09-022). Returns the updated record; 404 when no assurance record has been recorded yet.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

IdentityAttestedReprovision

POST/api/v1/auth/identity-attested-reprovision

Bootstraps a fresh credential set authorised by a completed identity verification, and returns the immutable attestation binding the two together.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The credential set was bootstrapped. The attestation names the verifier, the evidence kinds the platform holds a record of, the level reached, when, and the EPIC 4 audit anchor. — IdentityAttestedReprovisionResult
400The request failed validation. — ProblemDetails
403No completed, in-window verification authorises a re-provision for this account. Returned identically for every cause, deliberately. — ProblemDetails
409Recovery material still survives (or could not be ruled out), the verification fell below the assurance floor, or it has already authorised a re-provision. — ProblemDetails

IdentityDirectory

GET/api/v1/internal/directory/orgs/{organizationId}/sso-coverage

Sizes the population an organisation's domain-keyed sign-in change would reach.

The EPIC 9 IdP calls this for the `affectedMemberCount` on the SSO-enforcement review step (FR-09.041, issue #7264) — the number an org admin is shown immediately before an irreversible, org-wide sign-in change. Auth answers it because enforcement is applied through the domain-keyed org-IdP directory and Auth is the service that holds the accounts on those domains. Carries no PII whatsoever — an aggregate count and the organisation's own proven-domain tally — and so is the least sensitive member of this controller, but it keeps the same in-mesh-only trust boundary and the platform default rate-limit policy (SEC-004) as its siblings rather than opting out of either.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdpathstring (uuid)yesThe organisation whose coverage is being sized.
domainquerystring[]noOptional, repeatable: the `allowed-domains` scope's domain set. Narrows the organisation's proven domains; never extends them. Omit for the whole organisation.

Request body

No request body.

Responses

200The sizing completed. `resolved=false` means the organisation holds no current domain proof in scope, so the population is <b>unknown</b> — the caller must not render it as zero. — OrgSsoCoverageDto
401No valid bearer token. — ProblemDetails
GET/api/v1/internal/directory/professional-advisers/{adviserUserId}/authorisation

Whether a user is an <b>authorised professional adviser</b> right now, and — when a client is named — whether a recognised agency has actually put them on that client's case (journey `debt-relief-order-money-adviser-to-creditor-moratorium`, debt-2026-08-20-030).

<b>The register answers, not the token.</b> A role claim is a cached projection that a still-valid access token carries past a revocation, so an adviser struck off this morning would keep presenting `professional-adviser` until their token expired. The check reads the register at the moment the act is attempted. <b>Four verdicts, not a boolean.</b> A relying service has two decisions to make, and a boolean cannot carry both. `not-registered` — nobody holds a professional mandate over this person — is genuinely different from `not-authorised`, and collapsing them would force the caller to refuse an independent adviser whom a client named individually, breaking a case the journey already supports. `no-live-assignment` is separated again because it is the one failure a supervisor can fix, by assigning the case. <b>Capabilities are a ceiling.</b> The agency permission set on the response must be <i>intersected</i> with what the client's own delegation conveyed. The agency may narrow consent; it may never widen it. Same trust boundary as the sibling routes: service JWT, in-mesh only over Istio STRICT mTLS, never gateway-exposed, platform default rate-limit retained. It is more informative than the safeguarding seam beside it — it names the agency behind a verdict, which the relying service records for attribution — and that is precisely why it stays inside the mesh.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
adviserUserIdpathstring (uuid)yesThe adviser to check.
clientUserIdquerystring (uuid)noThe client they propose to act for. Omit to ask only the general professional-standing question, which then never returns `no-live-assignment`.

Request body

No request body.

Responses

200The authority verdict. — ProfessionalAdviserAuthorisationResult
401No valid bearer token. — ProblemDetails
GET/api/v1/internal/directory/safeguarding-officers/{officerUserId}/authorisation

Whether a user is an <b>authorised safeguarding officer</b> right now — the seam EPIC 57's safeguarding case service resolves before it accepts a decision-maker or a co-authoriser (journey `attorney-abuse-safeguarding-report-to-opg-investigation`, debt-2026-08-18-084).

<b>The register answers, not the token.</b> A role claim is a cached projection that a still-valid access token carries past a revocation. A countersignature recorded against a stale claim would name an officer whose designation had already ended, in the one artefact whose value is that it is true — so the check reads the register at the moment the signature is recorded. <b>Non-enumerable and non-PII.</b> The response is a boolean and an instant. "Never designated", "designated but unverified", "stood down" and "their authority's recognition lapsed" are deliberately indistinguishable, and a 200 is returned for an unknown id, so the endpoint cannot be used to discover who is on a register or why someone is not.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
officerUserIdpathstring (uuid)yesThe user-principal id to check.

Request body

No request body.

Responses

200The authorisation answer. — SafeguardingOfficerAuthorisationResult
401No valid bearer token. — ProblemDetails
GET/api/v1/internal/directory/users/{userId}/assurance-posture

Resolves a party's identity <b>assurance posture</b> — attested or not, at what level, by whom, and when.

Exists so a relying service can establish that a party is identity-attested <b>without that party asserting it</b> and without the service receiving any identity attribute (debt-2026-08-22-005, journey `reciprocal-field-disclosure-negotiation-between-contacts`). EPIC 6's reciprocal atomic-commit gate is the first caller: before two people's fields are disclosed to each other it asks the identity authority, rather than trusting a self-reported badge. <b>Non-PII by contract.</b> The response is a boolean, a level name, an attesting-source label and an instant. It deliberately does NOT carry the proofing policy, provenance, audit anchor or recovery disposition that the account holder's own `assurance` surface returns — a relying party learns that the person was attested, never how. Same trust boundary as the sibling routes on this controller: service JWT, in-mesh only over Istio STRICT mTLS, never gateway-exposed, platform default rate-limit retained because this is an enumeration surface by nature.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe party to resolve.

Request body

No request body.

Responses

200A posture was resolved. `verified=false` is a real answer — the party is known but is not currently identity-attested (never proofed, or the attestation has gone stale) — and callers must treat it as "not attested", never as an error. — AssurancePostureResult
401No valid bearer token. — ProblemDetails
404No assurance record exists for the id at all. — ProblemDetails
GET/api/v1/internal/directory/users/{userId}/identity-attributes

Resolves the matchable identity attributes (email / phone / name) for a user principal.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe user-principal id to resolve.

Request body

No request body.

Responses

200The lookup completed. `exists=false` means no active account resolves to the id — the caller must treat that as "unknown", never as "nothing matched". — UserIdentityAttributesDto
401No valid bearer token. — ProblemDetails
GET/api/v1/internal/directory/users/{userId}/nameability

Whether a principal can be <b>named to a third party</b> — i.e. whether a notice addressed to someone else could say who it is about.

Exists so a service that will later need to name this person can discover, at the moment the user is configuring the thing, that it will not be able to (debt-2026-08-27-145). EPIC 15's dead-man's-switch is the first caller: its welfare check tells a nominated contact who to check on, and fails closed when the holder recorded no name. Asking here moves that failure from the escalation — where nobody is contacted and the holder never learns — to the configuration screen, in front of the one person who can fix it. <b>Non-PII by contract.</b> Two booleans and the echoed id; the name itself is never returned. `GET recipients/{userId}/contact` remains the only route that discloses it, and only to the send path that must render it. That is what makes this one safe to call on an ordinary configuration write. Same trust boundary as the sibling routes: service JWT, in-mesh only over Istio STRICT mTLS, never gateway-exposed. A 200 is returned for an unknown id (`exists=false`) so the route cannot be used to enumerate which ids are real.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe user-principal id to check.

Request body

No request body.

Responses

200The nameability answer. `exists=false` means "unknown", never "this person has no name" — callers must not treat the two the same. — SubjectNameabilityDto
401No valid bearer token. — ProblemDetails

IndividualAssistedRecovery

POST/api/v1/auth/assisted-recovery/individual/requests/{caseRef}/cancel

Cancel from the hold notice's link. Never staged off and never gated by a release stage.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
caseRefpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The recovery was stopped. — IndividualRecoveryCancelResponse
410The link cannot be used — the same answer whatever the reason. — ProblemDetails
POST/api/v1/auth/assisted-recovery/individual/requests/{caseRef}/complete

Complete after the hold: a new password verifier; every old authenticator and session revoked.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
caseRefpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200Recovered. Sign in with the new password and set up a second factor. — IndividualRecoveryCompleteResponse
403Not accepted — the same answer whatever the reason. — ProblemDetails
409The hold has not ended; `holdEndsAt` says when it does. — ProblemDetails
POST/api/v1/auth/assisted-recovery/individual/requests/{caseRef}/proof

Prove both codes. Starts the hold and returns the completion token, once.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
caseRefpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200Both codes were right: the hold has started. — IndividualRecoveryProofResponse
403Not accepted — the same answer whatever the reason. — ProblemDetails

InternalExecutorRoster

GET/api/v1/internal/directory/orgs/{orgId}/executor-officers/{officerUserId}/attestation

Whether an officer is rostered and identity-verified by an organisation right now.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yesThe organisation whose roster to consult.
officerUserIdpathstring (uuid)yesThe officer to resolve.

Request body

No request body.

Responses

200The attestation. `attested=false` means "this organisation does not currently attest this officer" — it does not distinguish an unknown officer from an unverified one, and the caller must treat it as "cannot claim verified", never as "verified elsewhere". — ExecutorOfficerAttestationResult
401No valid bearer token. — ProblemDetails

InternalGuardianshipCorroboration

GET/api/v1/internal/directory/minors/{minorUserId}/guardians/{guardianUserId}/corroboration

Whether a person holds active guardian authority over a minor right now.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
minorUserIdpathstring (uuid)yesThe supervised minor.
guardianUserIdpathstring (uuid)yesThe person claiming to be the minor's guardian.

Request body

No request body.

Responses

200The corroboration. `corroborated=false` means "this person does not currently hold guardian authority over this minor" — it does not say whether the minor has a guardianship at all, and the caller must treat it as "do not supervise", never as "retry". — GuardianshipCorroborationResult
401No valid bearer token. — ProblemDetails
403The bearer is not a service principal. — ProblemDetails

InternalOrgMembershipStanding

GET/api/v1/internal/directory/orgs/{orgId}/members/{userId}/standing

Whether a user is an active member of an organisation, and whether they administer it.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yesThe organisation.
userIdpathstring (uuid)yesThe user.

Request body

No request body.

Responses

200The standing. `activeMember=false` means not a current member with an active account; it does not say why. — OrgMembershipStandingDto
401No valid bearer token. — ProblemDetails
403A token that is not a service principal. — ProblemDetails

Invitations

POST/api/v1/auth/invitations/accept

Accept an invitation: provision the invitee's account from the token + on-device password hash (zero-knowledge) and return an authenticated session.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Account provisioned; authenticated session issued. — AcceptInvitationResult
400Bad Request — ProblemDetails
404No invitation resolves the token. — ProblemDetails
409Invitation not actionable, or an account already exists for the email. — ProblemDetails
POST/api/v1/auth/invitations/decline

Decline an invitation by its token.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Invitation declined. — DeclineInvitationResult
404No invitation resolves the token. — ProblemDetails
409Invitation not actionable (already accepted/declined/expired). — ProblemDetails
POST/api/v1/auth/invitations/register

Register an org invitation with EPIC 9's accountless-acceptance store. This is the service-to-service ingestion the org-side invitation seam calls when it mints the token. Idempotent by invitation id.

Admits only a first-party service principal named in Essence.Identity.Auth.Api.Controllers.InvitationIngestionPolicies.TrustedCallers (#11943). The body names the organisation, the invitee and the roles the accepted account is bound to, and nothing here can check those against a caller's own authority — so a user token, which bare `[Authorize]` admitted, could mint an invitation into any organisation carrying any role.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/auth/invitations/{token}

Read an invitation's detail by its opaque token — the invitation-detail card the essence-web AcceptInvitationPage renders before acceptance.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenpathstringyes—

Request body

No request body.

Responses

200Invitation detail (including sponsored-Premium context when present). — InvitationDetailDto
404No invitation resolves the token. — ProblemDetails

Jwks

GET/.well-known/jwks.json

Get JSON Web Key Set (JWKS) for token validation. This endpoint is called by OAuth clients and resource servers to validate JWT tokens.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
X-Api-Versionheaderstringno—

Request body

No request body.

Responses

200OK — JwksDocument
503Service Unavailable
GET/.well-known/openid-configuration

Get OpenID Connect discovery document.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
X-Api-Versionheaderstringno—

Request body

No request body.

Responses

MediumEnrolmentOptions

GET/api/v1/mfa/enrolment-options

The medium routes the server offers to set up, which are offered, and which the account has.

Held items open only from a medium session (DVS-4.3), so the set-up surfaces offer at least two medium routes — a passkey and an authenticator app — so that losing one does not drop the holder below it. A text-message code is offered once its enrolment is on (DVS-4.3b, `POST /api/v1/mfa/sms/enrolment`, after the number is verified) and listed as `not-available-yet` while it is staged off.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

MemberInvitationAcceptance

POST/api/v1/auth/invitations/accept-as-member

Accept an invitation as the signed-in account it was issued to, joining that organisation.

No account is created, no password is set and no device is registered — the caller already has all three. The response carries a freshly minted access token for the caller's SAME session, so the organisation's `org_id` claim is usable immediately rather than only after the next refresh; the refresh token is untouched and the session continues.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Accepted; the returned access token carries the organisation. — AcceptInvitationAsMemberResult
400No token in the body. — ProblemDetails
401Not signed in. — ProblemDetails
404No invitation of the signed-in account resolves the token. — ProblemDetails
409The invitation is not actionable (already accepted, declined, expired or withdrawn), or the caller already belongs to another organisation. — ProblemDetails
POST/api/v1/auth/invitations/decline-as-member

Decline an invitation as the signed-in account it was issued to.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Declined. — DeclineInvitationResult
400No token in the body. — ProblemDetails
401Not signed in. — ProblemDetails
404No invitation of the signed-in account resolves the token. — ProblemDetails
409The invitation is not actionable (already accepted, declined, expired or withdrawn). — ProblemDetails

Mfa

POST/api/v1/mfa/backup-codes/regenerate

Regenerate backup codes for the authenticated user

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation (DVS-4.4b). A backup code completes a sign-in's second step and satisfies the step-ups that accept one, so issuing a new set adds an authenticator.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
POST/api/v1/mfa/disable

Disable MFA for the authenticated user (requires a fresh step-up and the current password)

Requires a fresh (≤ 5 minutes) `act=second-factor-removal` elevation on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.ISecondFactorRemovalStepUpGate; DVS-4.4d, TF 1.0 §7.3.1.c), proved with a passkey, an authenticator-app code or a text-message code (the factor being removed counts), never the password, an emailed code or a backup code. The password in the body is still checked as well. Without the elevation, a session and the password removed the factor and left the account at the password floor for every other medium gate. Checked before the password, so a refusal says nothing about whether the password was right.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401No acceptable step-up elevation (`step-up-required`). — ProblemDetails
POST/api/v1/mfa/enable/totp

Enable TOTP (Google Authenticator) MFA for the authenticated user

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved with a factor the account already has (DVS-4.4b): the secret returned here IS the authenticator, so whoever receives it holds the factor. Confirming the staged enrolment (`POST /mfa/verify`) is not gated again: it needs a code from this secret, which only the elevated caller of this endpoint received.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/mfa/send/email

Send an OTP code via email to the authenticated user's verified email address

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/mfa/send/sms

Send an OTP code via SMS to the authenticated user's verified phone number

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/mfa/status

Report whether the authenticated account has a second factor, and what remains of its backup codes.

Issue #4714. This surface carried three mutations and no read, so a client could CHANGE the MFA state and never OBSERVE it. Settings → Security consequently hardcoded its two-factor toggle to on — telling every user their authenticator app was enabled, true or not — and let them switch it off with no effect. There is no `enrolledAt`: the domain records no enrolment timestamp, and serving a plausible date for "when did you turn this on" is the class of invention this endpoint exists to remove. See Essence.Identity.Auth.Application.Queries.Mfa.MfaStatusDto.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200OK — MfaStatusDto
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/mfa/verify

Verify an MFA code

Answers with a verdict, so a rejected code is a 200 whose `isValid` AND `success` are both `false` (#7240) — never a 200 that only one field contradicts. A caller must read a flag; the status code alone distinguishes only "we could not check" from "we did". See Essence.Identity.Auth.Application.Commands.Mfa.VerifyMfaResult for why the refusal is not a 401.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200OK — VerifyMfaResult
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

MinorTransition

GET/api/v1/identity/minor-transition/identity-change

Read the minor→adult identity-change record. Seam: `getIdentityChange`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
GET/api/v1/identity/minor-transition/revocation-proof

Read the exportable guardian-revocation proof. Seam: `getRevocationProof`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/minor-transition/safe-recovery

Initiate guided step-up / assisted recovery after a failed majority verification. Seam: `initiateSafeRecovery`. The vault stays locked to the adult; control never reverts to the former guardian.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

NameChangeHistory

GET/api/v1/identity/history/name-change

List the account's committed verified-name-change history records (most recent first).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
GET/api/v1/identity/history/name-change/{auditRecordId}

Read a single committed identity-history record by its audit record id.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
auditRecordIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
GET/api/v1/identity/history/name-change/{auditRecordId}/export

Export a single committed identity-history record (portable, ZK-safe).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
auditRecordIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/auth/takeover/new-device-alert-freeze

Freeze the account a new-device alert's link was minted for, and sign out every device.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The link was live: the account is frozen and every session revoked. — NewDeviceFreezeLinkResponse
410The link cannot be used — the same answer whatever the reason. — ProblemDetails

OAuth

POST/api/v1/auth/oauth/{provider}/authorize

Initiates OAuth authentication flow with an identity provider. Returns authorization URL with PKCE parameters for secure code exchange.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
providerpathstringyesIdentity provider (e.g., UaePass, AzureAD, Google)
X-Api-Versionheaderstringno—

Request body

Not marked as required in the document.

Responses

200Authorization URL generated successfully — InitiateOAuthResult
400Invalid request parameters — ProblemDetails
404Identity provider not supported — ProblemDetails
501Provider is supported by the platform but has no usable credential on this instance, so the hand-off cannot complete and is refused rather than started (#6942). — ProblemDetails
POST/api/v1/auth/oauth/{provider}/callback

Handles OAuth callback after user authorization at identity provider. Exchanges authorization code for tokens and signs in to, or creates, the account the external identity belongs to. It never links: linking an identity to an existing account starts at the authenticated `{provider}/link/authorize` and completes at `{provider}/link`, and a state minted for a link is refused here.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
providerpathstringyesIdentity provider
X-Api-Versionheaderstringno—

Request body

Not marked as required in the document.

Responses

200Authentication successful, tokens issued — OAuthCallbackResult
400Invalid request or authentication failed — ProblemDetails
404Identity provider not supported — ProblemDetails
501Provider is supported by the platform but has no usable credential on this instance, so the hand-off cannot be completed (#6529). — ProblemDetails
POST/api/v1/auth/oauth/{provider}/link

Completes linking an OAuth identity provider to the authenticated user's account. Allows users to sign in using multiple identity providers. The state must have been started at `{provider}/link/authorize` by this same signed-in user; a sign-in state, or another user's link state, is refused before the authorization code is exchanged.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
providerpathstringyesIdentity provider to link
X-Api-Versionheaderstringno—

Request body

Not marked as required in the document.

Responses

200Identity provider linked successfully — OAuthLinkResult
400Invalid request or linking failed — ProblemDetails
401User not authenticated — ProblemDetails
404Identity provider not supported — ProblemDetails
501Provider is supported by the platform but has no usable credential on this instance, so it cannot be linked (#6529). — ProblemDetails
POST/api/v1/auth/oauth/{provider}/link/authorize

Starts linking an identity provider to the signed-in user's account. Same hand-off as `{provider}/authorize`, except the one-time state records the caller (from the bearer token, never the body) as the account to link to — the only way a link can be started. Complete it at `{provider}/link`, signed in as the same user. Requires an `act=account-link` step-up elevation on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IOAuthLinkStepUpGate, D-131): a link is a lasting way into the account, so a session alone is not authority for it. A delegated or otherwise derived token (any bearer carrying `act`) is refused outright.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
providerpathstringyesIdentity provider to link
X-Api-Versionheaderstringno—

Request body

Not marked as required in the document.

Responses

200Authorization URL generated successfully — InitiateOAuthResult
400Invalid request parameters — ProblemDetails
401Not authenticated, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
403The bearer token is a delegated or derived token — ProblemDetails
404Identity provider not supported — ProblemDetails
501Provider is supported by the platform but has no usable credential on this instance, so it cannot be linked (#6529). — ProblemDetails

OpenIdentityChanges

GET/api/v1/identity/primary-contact-changes

The caller's primary-contact changes still in progress (`Requested` / `NewAddressVerified`), most recent first.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
GET/api/v1/identity/verified-name-changes

The caller's verified-name changes still in progress (`Requested` / `Reattested`), most recent first.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails

OrgExecutorOfficers

GET/api/v1/orgs/executor-officers

Returns the caller's organisation's executor roster.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
includeRemovedquerybooleannoInclude removed officers (the audit view). Defaults to false.

Request body

No request body.

Responses

200The roster plus its header counts. — ExecutorRosterResult
403The caller carries no organisation claim. — ProblemDetails
POST/api/v1/orgs/executor-officers

Adds an individual to the roster, unverified. Idempotent: re-adding someone already on the roster returns their existing row, and re-adding a removed officer reinstates them — unverified, because the reason they left may be the reason their evidence no longer holds.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The officer's roster row. — ExecutorOfficerRow
400The request failed validation. — ProblemDetails
403The caller carries no organisation claim. — ProblemDetails
POST/api/v1/orgs/executor-officers/{officerUserId}/removal

Removes an officer from the roster and cascades that removal to every estate grant they hold.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
officerUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The officer's removed roster row. — ExecutorOfficerRow
400The request failed validation. — ProblemDetails
403The caller carries no organisation claim. — ProblemDetails
404No such officer is on this organisation's roster. — ProblemDetails
POST/api/v1/orgs/executor-officers/{officerUserId}/verification

Records that the officer's identity has been verified — the transition that makes the roster attest them to a consuming service.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
officerUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The officer's updated roster row. — ExecutorOfficerRow
400The request failed validation. — ProblemDetails
403The caller carries no organisation claim. — ProblemDetails
404No such officer is on this organisation's roster. — ProblemDetails
409The officer has been removed and cannot be verified. — ProblemDetails

OrgExpiringVerifications

GET/api/v1/orgs/{orgId}/expiring-verifications

Returns the org's expiring-verifications cohort within the look-ahead window (days), sorted by days-to-expiry ascending, with the aggregate counts the worklist header shows.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—
sortByquerystringno—
windowqueryinteger (int32)no—

Request body

No request body.

Responses

200The cohort + aggregate counts. — ExpiringVerificationsCohortResult
403The caller is not an administrator of this org. — ProblemDetails
POST/api/v1/orgs/{orgId}/expiring-verifications/record

Records (upserts) an org member verification into the cohort — the ingestion side of the base capability, called by the org proofing / verification seam so the worklist has data to act on.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The recorded/updated cohort row. — ExpiringVerificationRow
400Bad Request — ProblemDetails
403The caller is not an administrator of this org. — ProblemDetails
POST/api/v1/orgs/{orgId}/expiring-verifications/request-recheck

Requests a recheck for one or more verifications (per-row or bulk).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The action outcome. — VerificationActionResult
400Bad Request — ProblemDetails
403The caller is not an administrator of this org. — ProblemDetails
POST/api/v1/orgs/{orgId}/expiring-verifications/send-reminder

Sends a renewal reminder for one or more verifications (per-row or bulk).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The action outcome. — VerificationActionResult
400Bad Request — ProblemDetails
403The caller is not an administrator of this org. — ProblemDetails

OrgGrantApprovals

GET/api/v1/orgs/{orgId}/grant-approvals

Lists the grants awaiting the signed-in owner's co-sign. This is the collection root: `GET /api/v1/orgs/{orgId}/grant-approvals`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The pending grants, enveloped as `{ data: [...] }`.
403The caller is not an administrator of this org. — ProblemDetails
POST/api/v1/orgs/{orgId}/grant-approvals/{grantId}/decision

Records an approve/reject decision on a pending grant. On the final required approval the grant transitions to `active` and the delegate is notified server-side (outbox-backed integration event).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—
grantIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The updated grant, enveloped as `{ data: {...} }`.
400The decision verb is unknown, or a rejection carries no reason. — ProblemDetails
403The caller is not an admin of this org, or is the grant's own issuer. — ProblemDetails
404No such grant within this org. — ProblemDetails
409The grant is already terminal, or this owner has already co-signed it. — ProblemDetails

OrgMemberInvitations

POST/api/v1/orgs/{orgId}/member-invitations

Invites a person to join this organisation as a member. The invitee receives an acceptance link by email; accepting provisions their account (they set their own password on their own device) and makes them a member, so their access token then carries this organisation's `org_id`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

201The invitation was issued and delivered. — InviteOrganizationMemberResult
400No invitee address, or it is not a valid address. — ProblemDetails
403The caller does not administer this organisation. — ProblemDetails
409The invitation could not be delivered and has been withdrawn. — ProblemDetails

OrgOperationalRoles

POST/api/v1/orgs/{orgId}/operational-roles

Grants an operational role to a member of this organisation.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The member's operational roles after the change. Re-granting a held role is a no-op and still returns 200 — an administrator retrying is not an error. — SetOrgOperationalRoleResult
403The caller does not administer this organisation, the role is not one an organisation may issue (`role-not-grantable`), or the recipient does not currently belong to this organisation (`recipient-not-in-organization`). — ProblemDetails
404No account exists for the recipient (`recipient-unknown`). — ProblemDetails
409The recipient's account is deactivated (`recipient-inactive`), or the role is granted in the organisation portal's Members screen (`issued-through-org-portal`). — ProblemDetails
GET/api/v1/orgs/{orgId}/operational-roles/catalogue

The roles this organisation may issue, with what each one lets the holder do.

Requires org-admin because the catalogue is the menu of authority an administrator is about to hand out; it is not a public description of the platform.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

No request body.

Responses

403The caller does not administer this organisation. — ProblemDetails
GET/api/v1/orgs/{orgId}/operational-roles/holders

The organisation's members who currently hold an operational role.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The holders. `truncated=true` means the roster scan hit its ceiling and the list may be incomplete — it must not be read as "nobody else holds this". — OrgOperationalRoleHoldersResult
403The caller does not administer this organisation. — ProblemDetails
DELETE/api/v1/orgs/{orgId}/operational-roles/{userId}/{role}

Withdraws an operational role from a member.

Accepts a LAPSED membership that M:Essence.Identity.Auth.Api.Controllers.OrgOperationalRolesController.Grant(System.Guid,Essence.Identity.Auth.Api.Controllers.SetOperationalRoleRequest,System.Threading.CancellationToken) would refuse: an organisation must be able to strip a role from somebody it has just offboarded, which is exactly when the relationship is no longer live.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—
userIdpathstring (uuid)yes—
rolepathstringyes—

Request body

No request body.

Responses

200The member's operational roles after the change. — SetOrgOperationalRoleResult
403The caller does not administer this organisation, or the role/recipient is out of scope. — ProblemDetails
404No account exists for the recipient. — ProblemDetails

OrgScopedAdminGrants

POST/api/v1/orgs/{orgId}/scoped-admin-grants

Issues a scoped-admin grant to a staff member. Under approval policy `none` the grant activates immediately (and the delegate is notified via the outbox); under `single-owner` / `dual-owner` it enters the co-sign gate and appears on other owners' approval worklists.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

201The issued grant, enveloped as `{ data: {...} }`.
400The scope is empty, the justification is missing, or the policy/expiry is invalid. — ProblemDetails
403The caller is not an administrator of this org. — ProblemDetails
GET/api/v1/orgs/{orgId}/scoped-admin-grants/mine

The CALLING delegate's own grant lifecycle status — the read behind the delegated-admin console's fail-closed gate (2→3 seam, gaps debt-2026-08-11-474 / debt-2026-08-11-807).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The delegate's current grant status, enveloped as `{ data: {...} }`.
403The caller's token does not belong to this organisation. — ProblemDetails
404The caller holds no scoped-admin grant in this organisation. — ProblemDetails

OrgSharedDevices

GET/api/v1/orgs/{orgId}/shared-devices

Every device the organisation has enrolled, revoked ones included, newest first.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

No request body.

Responses

200The devices. — SharedDeviceDto[]
403The caller does not administer this organisation. — ProblemDetails
POST/api/v1/orgs/{orgId}/shared-devices

Enrols a machine the organisation owns.

The machine generates an EC P-256 key pair and keeps the private half; only the public JWK is sent. A JWK carrying `d` is refused.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

201Enrolled. — SharedDeviceDto
400The key is not an EC P-256 public JWK (`invalid-key`), or the label is missing. — ProblemDetails
403The caller does not administer this organisation. — ProblemDetails
409Another device already holds this key (`key-already-enrolled`). — ProblemDetails
PUT/api/v1/orgs/{orgId}/shared-devices/{deviceId}/key

Replaces a device's key — after a reimage, or when the old key may be exposed.

The device keeps its id, so captures made before the rotation still name it. The old key stops attesting at once.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—
deviceIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The device with its new key. — SharedDeviceDto
400The key is not an EC P-256 public JWK (`invalid-key`). — ProblemDetails
403The caller does not administer this organisation. — ProblemDetails
404No such device in this organisation (`shared-device-not-found`). — ProblemDetails
409The device is revoked (`shared-device-revoked`), or another device holds the key. — ProblemDetails
POST/api/v1/orgs/{orgId}/shared-devices/{deviceId}/revoke

Revokes a device that is decommissioned, sold, lost or stolen. Terminal.

The device never attests again; its row is kept, so what was captured on it stays attributable. Revoking an already revoked device returns it unchanged.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
orgIdpathstring (uuid)yes—
deviceIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The revoked device. — SharedDeviceDto
403The caller does not administer this organisation. — ProblemDetails
404No such device in this organisation (`shared-device-not-found`). — ProblemDetails

OutOfBandProof

GET/api/v1/proof-of-control/challenges

Read every challenge raised under one case reference.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
caseRefquerystringno—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
POST/api/v1/proof-of-control/challenges

Issue a challenge to a named account at that account's own recovery address.

Always returns 201 with a challenge id, whatever the subject turns out to be — an unknown account, an unverified contact and a reachable account are indistinguishable in the response, so this endpoint is not an account-existence oracle. An unreachable account simply never answers and lapses to `Unresponsive`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/proof-of-control/challenges/{challengeId}

Read a challenge's state and the evidence class it currently yields.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
challengeIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/proof-of-control/challenges/{challengeId}/answer

Answer a challenge. Deliberately requires NO authenticated session.

<b>Why anonymous.</b> The holder proving control is by definition someone who may not be able to sign in — that is the whole premise. Requiring a token here would reintroduce the barrier this capability exists to remove. <b>What guards it instead.</b> The challenge id is an unguessable GUID delivered to nobody, the code is a one-time secret delivered only to the account's own address, the comparison is constant-time over keyed hashes (SEC-005), and the aggregate caps wrong answers at `MaxAttempts` before refusing outright. The platform's `essence-default` IP rate limit (SEC-004) applies on top.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
challengeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/proof-of-control/challenges/{challengeId}/cancel

Withdraw an open challenge. Yields `Withdrawn` — no evidence either way.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
challengeIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/proof-of-control/challenges/{challengeId}/extend

Extend the answer window — the generous-timing control.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
challengeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

PasswordBreachRange

POST/api/v1/auth/password/breach-range

Return the padded suffix list for a 5-character SHA-1 prefix.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The range: every suffix sharing the prefix, with counts (0 = padding). — PasswordBreachRangeResponse
400The prefix is not exactly 5 upper-case hexadecimal characters. — ProblemDetails
429Too many lookups from this address. — ProblemDetails
503The range could not be fetched; the device records `not_performed`. — ProblemDetails

PhoneVerification

POST/api/v1/auth/phone/verification

Texts a six-digit code, valid for ten minutes, to the number on the caller's account.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

202Sent; the masked number and when the code expires. — PhoneVerificationSentResponse
409Nothing to send: no number on the account, already verified, or the email not yet verified. — ProblemDetails
429Too many codes for this account, number or network; `Retry-After` says when. — ProblemDetails
503The text could not be sent; ask again. — ProblemDetails
POST/api/v1/auth/phone/verification/confirm

Redeems the code. Single use; five attempts per code; ten attempts per hour per account.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The number is verified. — PhoneVerificationConfirmedResponse
400The code was not accepted: `reason` is `mismatch`, `expired`, `exhausted` or `no-code`. — ProblemDetails
409The number is already verified, or there is none. — ProblemDetails
429Too many attempts; `Retry-After` says when. — ProblemDetails

PrimaryContactChanges

POST/api/v1/identity/primary-contact-changes

Request a primary-contact change; issues a challenge to the new address.

Requires a fresh (≤ 5 minutes) GPG 44 medium step-up elevation, `act=contact-change`, on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IContactChangeStepUpGate; DVS-4.4, TF 1.0 §7.3.1.c).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/identity/primary-contact-changes/{changeId}

Read the change session (masked; ZK-safe).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/primary-contact-changes/{changeId}/cancel

Cancel the change during the trust window (retain the old contact).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/identity/primary-contact-changes/{changeId}/cascade

Read the per-consumer cross-service cascade projection.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/identity/primary-contact-changes/{changeId}/commit

Commit cutover once the trust window has elapsed; emits the cascade event.

The cutover is the moment the contact details change, so it requires its own fresh (≤ 5 minutes) `act=contact-change` step-up elevation (DVS-4.4, TF 1.0 §7.3.1.c) — the one taken to open the change is at least a trust window old by now.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/primary-contact-changes/{changeId}/resend

Re-issue the challenge to the NEW address.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/primary-contact-changes/{changeId}/revalidate-factors

Re-validate recovery factors / active shares during the trust window.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/primary-contact-changes/{changeId}/verify-new-address

Prove control of the NEW address by submitting the one-time code.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

Principals

GET/api/v1/principals/users/{userId}

Validates that a user principal resolves to a real, active account.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe user-principal id to validate.

Request body

No request body.

Responses

200The check completed. `exists=false` means no (non-deleted) account resolves to the id; `exists=true, isActive=false` means the account exists but is deactivated. — PrincipalValidationDto
401No valid bearer token. — ProblemDetails

ProbateRole

GET/api/v1/probate-role/grants

List the Probate Role grants the authenticated partner has assigned.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/probate-role/grants

Grant a Probate Role to a fee-earner. Matches the EPIC 15 → EPIC 9 wire contract: `200 { grantId }` on create, `409 { grantId }` on an idempotent re-grant.

<b>Service principals only</b> (debt-2026-08-25-234). FR-15.009.6 admits a Probate Role on two preconditions — a verified lifecycle event or a registered PoA — and neither is a fact this service holds. EstatePlanning does, and it is the only legitimate caller (`InboundEventConsumers` on PoA activation, and `ExecutorRenunciationService` after a court-recorded replacement). While this endpoint accepted a plain `[Authorize]` token, any authenticated user could POST themselves an Active grant over a stranger's estate — and the grant is not a bookkeeping row: `ProbateStepUpController` treats it as the role basis for reaching AAL2, so a self-issued grant was a working key. Following the `SafeguardingCasesController` precedent, the authority model is enforced here even though <b>provisioning</b>Essence.Platform.Infrastructure.Security.RoleClaims.LifecycleServiceAgent onto the EstatePlanning service account is separate deployment work — so it cannot be bypassed once that lands. The wire contract already anticipated this: the calling client documents `401 / 403 → throw (wrong service credential)` and soft-fails the grant rather than blocking PoA activation, so an unprovisioned token degrades to a logged, retried re-grant rather than an outage.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
409Conflict — ProbateRoleGrantResponse
GET/api/v1/probate-role/grants/active

Does the named attorney currently hold the Probate Role over the named subject?

The authorisation read behind EPIC 15's Probate Dashboard (FR-15.009.2, debt-2026-08-25-233). EPIC 9 owns the grant record, so the predicate is answered here rather than mirrored into EPIC 15 where it would go stale against a revocation. Service-principal gated for the same reason as the grant write: the answer names who holds authority over whose estate, which is not a fact an arbitrary authenticated caller may enumerate.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
attorneyUserIdquerystring (uuid)no—
subjectUserIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
POST/api/v1/probate-role/grants/{id}/revoke

Revoke a Probate Role grant before its expiry.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

ProbateStepUp

POST/api/v1/auth/step-up/probate-grant

Initiate a probate step-up. On success returns an `aal=2` step-up token recording the authority basis.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/auth/step-up/probate-grant/assurance

Return the achieved-vs-required assurance for the current probate session on an estate, for the release-gate surface.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
estateIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/auth/step-up/probate-grant/challenge

Issue a probate step-up challenge for the chosen accessible factor.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

ProfileLocale

GET/api/v1/profile/preferred-locale

Returns the signed-in subject's stored preferred locale (null when unset) and the supported locale set for the selector.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The current preferred-locale state. — PreferredLocaleResult
401No authenticated subject. — ProblemDetails
PUT/api/v1/profile/preferred-locale

Sets (or changes) the signed-in subject's preferred communication locale. Idempotent — re-setting the current value returns 200 with `changed=false` and no event.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The preference was set (or already matched). — PreferredLocaleResult
400The requested tag is malformed or unsupported. — ProblemDetails
401No authenticated subject. — ProblemDetails
GET/api/v1/users/me/locale

Returns the signed-in subject's stored preferred locale (null when unset) and the supported locale set for the selector.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The current preferred-locale state. — PreferredLocaleResult
401No authenticated subject. — ProblemDetails
PUT/api/v1/users/me/locale

Sets (or changes) the signed-in subject's preferred communication locale. Idempotent — re-setting the current value returns 200 with `changed=false` and no event.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The preference was set (or already matched). — PreferredLocaleResult
400The requested tag is malformed or unsupported. — ProblemDetails
401No authenticated subject. — ProblemDetails

ProfileName

GET/api/v1/profile/name

Returns the holder's stored name and whether they may set it themselves.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The stored name and its editability. — ProfileNameResult
401No authenticated subject. — ProblemDetails
404The authenticated subject no longer exists. — ProblemDetails
PUT/api/v1/profile/name

Sets the holder's first and last name. Setting the stored value again is a no-op.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The name was set (or already matched). — ProfileNameResult
400The first name is blank, or a value is too long. — ProblemDetails
401No authenticated subject. — ProblemDetails
404The authenticated subject no longer exists. — ProblemDetails
409A proofed identity holds the name; use the verified name-change flow. — ProblemDetails

ProtectionStatus

GET/api/v1/users/me/protection-status

Returns the authenticated owner's aggregated protection status, or 404 when nothing has been provisioned yet (the client renders a neutral "not set up yet" state on absence).

<b>DVS-4.4g: a session opened with the alternate credential gets the 404.</b> Every component of this read model belongs to the same protection (the alternate passphrase, the backup view it opens, the trusted contact it alerts), so any of them would tell whoever holds that session that the protection exists. The session is answered exactly as an account that has set up nothing, by the same `NotFound()` on the same path, decided on the server from the session's sign-in tag — not left to the web panel hiding itself. The read still runs, so the two answers cost the same.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200OK
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
PUT/api/v1/users/me/protection-status/alternate-credential

Enrols (or replaces) the owner's ALTERNATE credential — the second proof the cold sign-in accepts, for the `duress-passphrase-silent-alarm-and-decoy-unlock` journey (debt-2026-08-10-001).

Owner-scoped like every route on this controller: the subject comes from the JWT, so no caller can enrol an alternate credential onto someone else's account — which would otherwise be a backdoor into another person's sign-in. <b>DVS-4.4f: a fresh step-up first.</b> `LoginCommandHandler` accepts this credential as a sign-in password, so setting it is adding an authenticator (P-31): it needs a fresh (at most 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved at the account's own level (a passkey, authenticator-app or text-message code when it has one, else its password, P-23; never an emailed or backup code), with the P-32 exception for a federated-only account. Without it a stolen session could plant a sign-in password of its own choosing that outlives the session. The gate runs before the credential is read or hashed, and is staged with the other DVS-4.4 gates (`Auth:AuthenticatorEnrolmentStepUp:Enabled`, P-18). An enrolment raises the holder's neutral "a sign-in setting was changed" alert on both channels (DVS-7.4b path).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

204No Content
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
409Conflict — ProblemDetails
DELETE/api/v1/users/me/protection-status/alternate-credential

Withdraws the owner's alternate credential. Idempotent: 204 whether or not one was enrolled, so the response never reveals whether the account had one.

<b>DVS-4.4f: deliberately NOT gated.</b> Withdrawing removes a way in; it lowers no sign-in or recovery path, so it is not the threat P-31 and P-37 answer. A step-up does nothing against a coercer standing over the holder (they can make the holder complete it), and a holder who has lost their factor must still be able to remove one someone else planted. A withdrawal the holder did not make does matter to them, so it raises the same neutral holder alert as enrolment, on both channels (P-26). <b>DVS-4.4g: a session opened with the alternate credential cannot withdraw it.</b> It gets the `204` an account with none gets, and nothing changes and nothing is announced — as for an account with none — while the handler reads, saves and logs as for any other call (Essence.Identity.Auth.Application.Commands.ProtectionStatus.WithdrawDuressCredentialCommand.FromAlternateCredentialSession). Otherwise the withdrawal alert in that session's own inbox would tell a coercer that a credential existed, and the session the protection exists for could disarm it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

204No Content
401Unauthorized — ProblemDetails
POST/api/v1/users/me/protection-status/trusted-contact/reinvite

Re-invites (or re-picks) the owner's trusted contact after their consent lapsed or was revoked. Best-effort: emits the re-invite event for EPIC 66 to dispatch and returns 202.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

202Accepted
401Unauthorized — ProblemDetails

RecipientDirectory

GET/api/v1/internal/directory/organisations/{organizationId}/notification-audience

Resolves who an organisation-addressed notification is for: the organisation's active administrators, as user ids (#11198). EPIC 66 fans the notice out to them and resolves each one's contact through M:Essence.Identity.Auth.Api.Controllers.RecipientDirectoryController.GetRecipientContact(System.Guid,System.Threading.CancellationToken,System.Boolean) at send time.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdpathstring (uuid)yesThe organisation whose audience is resolved.

Request body

No request body.

Responses

200The lookup completed. An empty `recipientIds` means the organisation has no active administrator on record — the caller must record that, never treat it as delivered. — OrganisationNotificationAudienceDto
401No valid bearer token. — ProblemDetails
GET/api/v1/internal/directory/recipients/{userId}/contact

Resolves the deliverable contact (email / phone) for a user principal.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe user-principal id to resolve.
owedToClosedAccountquerybooleannoDVS-7.2b: `true` only for a notice the holder-account procedure owes a closed account (the closure notice with its cancel link, its cancellation, the closure lifecycle notices, the security alerts). Absent or false, a deactivated account is not deliverable (FR-66.127), as before DVS-7.2b.

Request body

No request body.

Responses

200The lookup completed. `exists=false` means no active account resolves to the id (or a deactivated one, unless `owedToClosedAccount=true`); `email`/`phone` are null when the directory holds no verified value. — RecipientContactDto
401No valid bearer token. — ProblemDetails

RecipientLookup

POST/api/v1/auth/recipients/lookup

Resolves an email address to a share-capable user principal.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The lookup completed. `resolved=false` means no active account can receive a share at that address — it does not say whether one exists. — RecipientResolutionDto
400The body carried no email address. — ProblemDetails
401No valid bearer token. — ProblemDetails

ReturningNational

GET/api/v1/identity/returning-national/queue

Returns the business-admin bootstrap-acceptance queue — held cases awaiting approve / hold / decline, oldest first. Admin-only.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
limitqueryinteger (int32)no—

Request body

No request body.

Responses

200The held queue. — ReturningNationalReceiptResult[]
403The caller is not an administrator. — ProblemDetails
POST/api/v1/identity/returning-national/queue/{decisionId}/resolve

Business-admin resolves a held bootstrap case (approve / hold / decline). Approval credits the domestic assurance and meters the implied identity check. Admin-only.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
decisionIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The resolved decision + receipt. — ReturningNationalReceiptResult
400Invalid action. — ProblemDetails
403The caller is not an administrator. — ProblemDetails
404No such decision. — ProblemDetails
POST/api/v1/identity/returning-national/{intakeId}/bootstrap

Runs the returning-national bootstrap acceptance gate for the authenticated caller's intake. The origin jurisdiction, scheme and foreign LoA are those the caller's intake recorded (read from the Instance service) — the body cannot supply them (#14018). Returns the audited decision + user receipt. On an automatic accept the subject's authoritative identity assurance is credited to the mapped domestic level; otherwise the case is held for the business-admin queue.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
intakeIdpathstringyes—

Request body

Not marked as required in the document.

Responses

200The bootstrap decision (accepted or held) + receipt. — ReturningNationalReceiptResult
400Invalid request. — ProblemDetails
401The caller is not authenticated. — ProblemDetails
404No intake with that id was opened by the caller. — ProblemDetails
503The intake could not be read; nothing was credited.

RevocationSnapshot

GET/api/v1/auth/revocation-snapshot

Every revoked access token id that has not yet expired.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails

SafeguardingAuthorities

GET/api/v1/safeguarding-authorities

The register of recognised safeguarding authorities.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
includeWithdrawnquerybooleannoInclude bodies whose recognition was withdrawn (audit view).

Request body

No request body.

Responses

200The register. — SafeguardingAuthorityRow[]
POST/api/v1/safeguarding-authorities

Recognises an organisation as a safeguarding authority.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201The body is now recognised and may designate officers. — SafeguardingAuthorityRow
400The request failed validation. — ProblemDetails
409The organisation already holds a recognition. — ProblemDetails
POST/api/v1/safeguarding-authorities/{organizationId}/standing

Suspends, restores or withdraws a body's recognition.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The body's updated register row. — SafeguardingAuthorityRow
400Unknown action, or a reason is missing where one is required. — ProblemDetails
403The organisation is not on the register at all. — ProblemDetails
409The transition is not available from the body's current standing. — ProblemDetails

SafeguardingOfficers

GET/api/v1/safeguarding-officers

The calling authority's own officer register.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
includeInactivequerybooleannoInclude revoked designations (the audit view).

Request body

No request body.

Responses

200The register plus its header counts. — SafeguardingOfficerRegisterResult
403No organisation claim, or the organisation is not on the register. — ProblemDetails
POST/api/v1/safeguarding-officers

Designates an individual onto the calling authority's register, unverified.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The officer's register row. — SafeguardingOfficerRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised authority. — ProblemDetails
404No account exists for the supplied officer user id. — ProblemDetails
409The authority's recognition is suspended or withdrawn. — ProblemDetails
GET/api/v1/safeguarding-officers/directory

The co-authoriser directory: every currently authorised officer, across every recognised authority, minus the caller.

<b>Gated on the investigator role, not on org administration.</b> The people entitled to see who may countersign are the people who may ask for a countersignature. Exposing it to org administrators generally would publish a list of safeguarding officers to every organisation on the platform. <b>The caller is excluded.</b> Dual control means an investigator may never be their own co-authoriser, so offering themselves would be offering a choice the domain then refuses.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The directory. — CoAuthoriserDirectoryResult
403The caller does not hold the safeguarding-investigator role. — ProblemDetails
POST/api/v1/safeguarding-officers/{officerUserId}/standing

Stands an officer down, reinstates them, or revokes their designation.

A revocation is accepted even while the authority's own recognition is suspended: being unable to withdraw a compromised officer's designation because your recognition lapsed would trap a body at exactly the moment it most needs to act.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
officerUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The officer's updated register row. — SafeguardingOfficerRow
400Unknown action, or a reason is missing where one is required. — ProblemDetails
403No organisation claim, or the organisation is not on the register. — ProblemDetails
404No such officer is on this authority's register. — ProblemDetails
409The transition is unavailable from the current standing. — ProblemDetails
POST/api/v1/safeguarding-officers/{officerUserId}/verification

Records that the officer's identity has been verified, issuing the `safeguarding-investigator` claim and adding them to the co-authoriser directory.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
officerUserIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The officer's updated register row. — SafeguardingOfficerRow
400The request failed validation. — ProblemDetails
403No organisation claim, or the organisation is not a recognised authority. — ProblemDetails
404No such officer is on this authority's register. — ProblemDetails
409The designation has been revoked, or recognition is not in good standing. — ProblemDetails

SessionOperatingJurisdiction

PUT/api/v1/sessions/current/operating-jurisdiction

Declares the jurisdiction the caller is working from, for this session.

Requires a fresh (≤ 5 minutes) `act=operating-jurisdiction-declaration` elevation on `X-Step-Up-Token`, proved with a passkey, an authenticator-app code or a text-message code. Checked before anything is read, so a refusal says nothing about the value. A later declaration replaces an earlier one and starts a new period.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Recorded; the session's next token carries it until `expiresAt`. — OperatingJurisdictionResponse
400Bad Request — ProblemDetails
401No acceptable step-up elevation (`step-up-required`). — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
DELETE/api/v1/sessions/current/operating-jurisdiction

Ends this session's declaration before its period runs out.

The session's next token carries no `operating_jurisdiction`; a token already issued runs to its own expiry. Needs no step-up: it can only remove the claim.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404No such session, or it has no declaration in force (`no-operating-jurisdiction`). — ProblemDetails

Sessions

GET/api/v1/sessions

Get all sessions for the authenticated user

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200OK — SessionDto[]
401Unauthorized — ProblemDetails
DELETE/api/v1/sessions

Revoke all sessions except the current one (logout from all other devices)

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
KeepCurrentquerybooleannoIf true, keeps the current session active. Default is true.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/sessions/wearable/revoke

Scope-revoke a single lost companion watch's delegated session (journey `lost-wearable-delegated-session-revoke`). Revokes ONLY the named watch's delegated JWT — the caller's phone and other devices stay signed in (unlike M:Essence.Identity.Auth.Api.Controllers.SessionsController.RevokeAllSessions(Essence.Identity.Auth.Api.Controllers.RevokeAllSessionsRequest) / FR-09.013). The delegated token is added to the revocation list so a found watch is provably inert immediately (`boundedInertBy`), and a durable `WearableSessionRevokedIntegrationEvent` is emitted on the outbox for incident audit. This is a safety action and is not billing-gated.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
GET/api/v1/sessions/{id}

Get a specific session by ID

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesSession ID

Request body

No request body.

Responses

200OK — SessionDto
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
DELETE/api/v1/sessions/{id}

Revoke a specific session (logout from that session)

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yesSession ID to revoke

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

SharedDeviceAttestations

POST/api/v1/internal/shared-devices/attestations/verify

Decides one attestation.

Always 200 with a verdict, because every verdict is information the caller records: `attested`, `malformed`, `unenrolled`, `signature-invalid`, `revoked`, `binding-mismatch` or `stale`. Only `attested` may be recorded as "made on this device". A capture that carried no attestation at all never reaches this endpoint — "no shared device involved" is the caller's own fact.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400A required field is missing. — ProblemDetails

SmartLaunch

POST/api/v1/identity/smart/launch-contexts

Mint a one-time launch context. Called by a trusted EHR at the moment it launches a SMART app; the returned launch token is handed to the app and is redeemable exactly once.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
POST/api/v1/identity/smart/token-exchange

Exchange an EHR's one-time SMART launch token for a scoped clinician session. The exchange is performed AS the clinician (the caller's bearer token), never as a service principal, so the resulting launch is attributable to a person.

Contracted refusals carry a `code`: `unregistered-iss` (400), `launch-token-invalid` (401), `scope-not-permitted` (403). A consumer distinguishes these from an outage by that code — a refusal is a decision, anything else is an unknown.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
GET/api/v1/identity/smart/trusted-issuers

List the trusted-EHR issuer registry.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
organizationIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
POST/api/v1/identity/smart/trusted-issuers

Register an EHR issuer as trusted. Idempotent: re-registering an existing issuer returns its id rather than failing, so provisioning can be re-run.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
POST/api/v1/identity/smart/trusted-issuers/{issuerId}/status

Suspend, withdraw, or reinstate a trusted issuer. Withdrawal is terminal; a suspension is reinstatable.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
issuerIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

204No Content
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails

SmsEnrolment

POST/api/v1/mfa/sms/enrolment

Use the verified number on the account for sign-in and step-up codes.

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token` (DVS-4.4b). Answers the backup codes once.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Enrolled; the masked number and the backup codes (shown once). — SmsEnrolmentResponse
401A step-up is required (`step-up-required`). — ProblemDetails
403The subscription does not include text-message codes. — ProblemDetails
409Not enrolled: no number, an unverified number, a second factor already on, or text-message enrolment not available yet. — ProblemDetails

StepUp

POST/api/v1/auth/step-up

Initiate a step-up challenge for a privileged action. On success returns a short-lived `aal=2` step-up token, plus — for an irreversible action — the signed assertion its consuming service re-verifies server-side.

The token elevates the SESSION; the assertion authorises one irreversible OPERATION at a service that will not accept a bearer token it did not mint (debt-2026-08-19-008). Actions needing one also require Essence.Identity.Auth.Api.Controllers.InitiateStepUpRequest.PasswordHash: FR-15.008.7 demands password re-entry <i>and</i> a second factor, and the assertion attests to both.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
409Conflict — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/auth/step-up/email-code

Email the one-time code a step-up for `action` will verify with `factor=email` (#8753). Unlike `POST /api/v1/mfa/send/email`, it serves an account whose MFA is off when the action's email floor applies — the only way such an account can obtain a `password-change` elevation.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Outcome of the send (`sent` false with a `status` when declined, e.g. unverified email). — SendEmailOtpResult
400Unknown action. — ProblemDetails
401Unauthorized — ProblemDetails
409Email is not a step-up factor for this action on this account. — ProblemDetails
429The hourly email-code allowance is spent. — ProblemDetails
GET/api/v1/auth/step-up/required-factors

Returns the step-up factors the calling session may use (intersection of the user's enrolled factors and the deployment-allowed factor set). With `?action=`, the factors a step-up for THAT action will accept — which for `password-change` includes the email floor for an account with no other factor (#8753). For `passkey-removal`, `contact-change` (GPG 44 medium, DVS-4.4) and `authenticator-enrolment` (DVS-4.4b) it never includes `email` or `backup-code`; an account with none of TOTP, SMS or a passkey is offered `password` instead.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
actionquerystringno—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

StepUpOtp

POST/api/v1/auth/mfa/otp/request

Send a step-up one-time code over the chosen recovery channel.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/auth/mfa/otp/verify

Verify a delivered step-up one-time code and, on success, receive the `recovery-initiate` elevation token it earns.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

SubjectExportDelegation

POST/api/v1/subject-export-delegation

Mint a delegation credential for the authenticated caller, bound to one queued export.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails

SupportAccessAgents

GET/api/v1/developer/support-access/agents

Every agent of the application, suspended ones included, oldest enrolment first. 404 when the caller does not administer the application; 503 when the Developer Portal cannot be asked.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
appIdquerystring (uuid)no—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable
POST/api/v1/developer/support-access/agents

Invite one address to be an agent: 201 with `status: invited` and no `principalId`, identically whether or not the address has an Essence account (#21852). An address already invited to or enrolled on the application is 409. 400 names a refused field; 404 / 503 as for the list.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Created — SupportAgentDto
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
503Service Unavailable
POST/api/v1/developer/support-access/agents/status

Suspend or reinstate several agents at once, atomically. Every id must be an agent of the application, or nothing changes (404 `support-agent-not-found`). `updated` counts the agents whose status actually changed.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable

SupportAccessOversight

GET/api/v1/developer/support-access/sessions

One page of the application's support-access sessions, newest first, as a JSON array (the shape the console reads). When there are more, the next page's cursor is in `X-Next-Cursor`; pass it back as `cursor`. `from`/`to` bound when the session was granted, `[from, to)`. An application the caller does not administer is the same 404 as an unknown one; 503 when the Developer Portal cannot be asked.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
appIdquerystring (uuid)no—
agentIdquerystring (uuid)no—
subjectquerystring (uuid)no—
fromquerystring (date-time)no—
toquerystring (date-time)no—
cursorquerystringno—
limitqueryinteger (int32)no—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable
GET/api/v1/developer/support-access/sessions/export.csv

Every session matching the filters as CSV — the partner's own audit pack. Refused (422) rather than truncated when it would exceed Essence.Identity.Auth.Application.Queries.DelegateAccess.ExportPartnerSupportSessionsQuery.MaxRows.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
appIdquerystring (uuid)no—
agentIdquerystring (uuid)no—
subjectquerystring (uuid)no—
fromquerystring (date-time)no—
toquerystring (date-time)no—

Request body

No request body.

Responses

200OK
400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
422Unprocessable Content — ProblemDetails
503Service Unavailable

SupportAccessPolicy

GET/api/v1/developer/support-access/policy

The application's policy. An application that has never saved one answers the closed posture (nobody may raise a request) with `configured: false`. 404 when the caller does not administer the application; 503 when the Developer Portal cannot be asked.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
appIdquerystring (uuid)no—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable
PUT/api/v1/developer/support-access/policy

Save (create or replace) the application's policy. Every field is replaced. 400 names the field a value is refused for; 404 / 503 as for the read.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable

SupportAccessRequests

GET/api/v1/developer/support-access/requests

The application's requests, newest first, keyset-paginated (#21871). An administrator of the application sees every request; an agent sees only its own. status and agentId narrow. 404 when the caller is neither an agent nor an administrator of the application, or it does not exist; 503 when the Developer Portal cannot be asked; 400 for a cursor this list did not issue.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
appIdquerystring (uuid)no—
statusquerystringno—
agentIdquerystring (uuid)no—
cursorquerystringno—
pageSizequeryinteger (int32)no—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable
POST/api/v1/developer/support-access/requests

Raise a request. 201 with the request (`pending-supervisor` when the policy requires dual approval, else `pending-customer`); 422 `support-access-request-refused` with every `violations[]` entry when the policy refuses it, and nothing is recorded. 404 when the caller is neither the named agent nor an administrator of the application; 503 when the Developer Portal cannot be asked.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
422Unprocessable Content — ProblemDetails
503Service Unavailable
POST/api/v1/developer/support-access/requests/{requestId}/approve

A supervisor approves a request held `pending-supervisor`; it becomes `pending-customer` (#21869). 200 with the request; 404 when it does not exist or the caller is not on its application's roster; 403 `support-access-supervisor-not-eligible` with a `code` when the caller may not decide it; 409 when it is not awaiting a supervisor.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
requestIdpathstring (uuid)yes—

Request body

No request body.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/developer/support-access/requests/{requestId}/decline

A supervisor declines a request held `pending-supervisor`, naming one of the decline reasons; it ends `declined` and the customer is never asked (#21869). Answers as M:Essence.Identity.Auth.Api.Controllers.SupportAccessRequestsController.Approve(System.Guid,System.Threading.CancellationToken); 400 for a reason that is not one of the decline reasons.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
requestIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

SupportAccessSessions

POST/api/v1/developer/support-access/sessions/{id}/terminate

Force-terminate a support-access session of an application the caller administers. A session that does not exist, is not a support session, or belongs to an application the caller does not administer is the same 404. 503 when the Developer Portal cannot be asked who administers the application.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
503Service Unavailable

SupportAccessSubjectDecision

GET/api/v1/developer/support-access/requests/mine

The support-access requests awaiting the signed-in account holder's own decision, newest first. An empty array genuinely means none are pending.

A request still held for the partner's own supervisor is not listed — the customer has not been asked yet — nor is one past its 72-hour deadline, nor one already decided.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
GET/api/v1/developer/support-access/requests/mine/sessions

The descriptive half of the support sessions over the caller's own account (#22084) — who is in the account, for which company, against which ticket — keyed by the consent ids of the grants they themselves issued.

<b>Why this is here and not on the partner's list.</b> The client used to read `GET …/requests?consentIds=…`, which is the partner-side list: scoped to an administrator of the application or an agent on its roster, and so unanswerable for the one audience that needs it — the customer whose account the session is over. The banner over a live session said "A support agent" with no company as a result. The subject's reads belong beside the subject's decision, under the capability the audience already holds. <b>Carries no authority.</b> No expiry, no status, no scopes — those are the EPIC 9 grant's, and ending the session works from the grant alone. A name that could not be resolved, or a descriptor read that failed outright, therefore cannot hide a live session or weaken its kill-switch. `consentIds` is a comma-separated list; ids naming no session of the caller's are simply absent from the answer, because answering an error for them would disclose which ids exist. An empty list is an empty array, not an error.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
consentIdsquerystringno—

Request body

No request body.

Responses

200One row per consent id that names a session over the caller's own account. — SupportAccessSessionDescriptorDto[]
401Unauthorized — ProblemDetails
POST/api/v1/developer/support-access/requests/{requestId}/decision

Answer a request. `decision: "allow"` creates the time-boxed `support-impersonation` grant over the caller's own account and records it on the request; `decision: "deny"` ends the request and creates nothing.

`grantId` is optional and, when sent, is verified rather than trusted: a client that created the grant itself (as the browser client does) names it, and a value that is not the grant this request's consent binds is `409`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
requestIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

200The decision, with the consent id and — for an approval — the grant and its expiry. — SupportAccessCustomerDecisionDto
400Neither `allow` nor `deny`. — ProblemDetails
401Unauthorized — ProblemDetails
404The request is not awaiting this caller's decision — one answer for decided, lapsed, held for a supervisor, and not theirs. — ProblemDetails
409A `grantId` that is not the grant this request's consent binds. — ProblemDetails

SupportAgentInvitations

GET/api/v1/account/support-agent-invitations

The caller's pending invitations, oldest first. Empty when the caller's address is not verified — an unverified address proves nothing about who holds it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/account/support-agent-invitations/{agentId}/accept

Accept one pending invitation: the caller becomes the application's agent (`status: active`). 404 `support-agent-invitation-not-found` for anything that is not the caller's pending invitation; 409 when the caller is already one of the application's agents.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
agentIdpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/account/support-agent-invitations/{agentId}/decline

Decline one pending invitation: the roster shows it `declined` and nobody is named; only the administrator inviting the address again reopens it. 404 `support-agent-invitation-not-found` for anything that is not the caller's pending invitation — the same single answer as accept.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
agentIdpathstring (uuid)yes—

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

Takeover

POST/api/v1/auth/takeover/emergency-freeze

Place an emergency credential freeze on the caller's own account and terminate every active session. Idempotent: a repeat call returns the original freeze instant.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
404Not Found — ProblemDetails
POST/api/v1/auth/takeover/emergency-freeze/by-signed-link

Place an emergency credential freeze authorised by a <b>signed link</b> rather than a session, and discard the in-flight recovery attempt the link names.

`[AllowAnonymous]` (SEC-002, explicit): the reader of an FR-66.114 "this wasn't me → freeze" alert holds no device, no app and no session — that is the definition of the `account-recovery-lost-devices` population, and requiring a bearer token would make this control unexecutable by everyone it exists for. The HMAC over `(accountId . recoverySessionId . expiresAtUnix)` IS the credential. Rate-limited by IP under the platform default policy (SEC-004), which is what bounds signature guessing on an unauthenticated endpoint. A bad signature and an unknown account both answer <b>401</b>, never 404 — the two must be indistinguishable or the endpoint becomes an account-existence oracle for anyone who can POST JSON. An expired link answers <b>410</b>, which is safe to distinguish because it is only ever reached by a link that already proved genuine.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

401Unauthorized — ProblemDetails
410Gone — ProblemDetails
GET/api/v1/auth/takeover/incident

The caller's own takeover-recovery state: whether the account is frozen right now, and the open incident if there is one (#7393). The hub renders its step rail from this, so a victim who leaves and comes back resumes instead of being offered the freeze again.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

401Unauthorized — ProblemDetails
POST/api/v1/auth/takeover/incident/{incidentId}/progress

Record a completed step (`keys-rotated`, `shares-revoked`, `closed`) on the caller's own open incident (#7393). An incident id that is not the caller's open incident answers 404 whether it belongs to someone else or to no one.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
incidentIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
404Not Found — ProblemDetails

TestTenants

POST/api/v1/admin/test-tenants

Provisions a verified `@browsertest.essence.digital` test-tenant account with the `TestTenant` role. Platform-admin only.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
403Forbidden — ProblemDetails

VerifiedNameChanges

POST/api/v1/identity/verified-name-changes

Open a verified-name-change session (records the old/new name hashes).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
401Unauthorized — ProblemDetails
409Conflict — ProblemDetails
GET/api/v1/identity/verified-name-changes/{changeId}

Read the change session (masked; ZK-safe).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
POST/api/v1/identity/verified-name-changes/{changeId}/cancel

Cancel the change before commit (retain the prior verified name).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

No request body.

Responses

404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/verified-name-changes/{changeId}/commit

Commit cutover; broadcasts the ZK-safe verified-name-change event.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails
POST/api/v1/identity/verified-name-changes/{changeId}/reattest

Record that the new name was re-attested against fresh identity evidence.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
changeIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

400Bad Request — ProblemDetails
404Not Found — ProblemDetails
409Conflict — ProblemDetails

WebAuthn

POST/api/v1/auth/webauthn/authenticate/begin

Begins a WebAuthn authentication ceremony. Returns credential request options including a challenge for the client to pass to navigator.credentials.get(). Supports both identified (user known) and discoverable (passkey) flows.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication options returned — WebAuthnAuthenticationOptions
POST/api/v1/auth/webauthn/authenticate/complete

Completes a WebAuthn authentication ceremony. Verifies the assertion response and issues authentication tokens on success.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication successful, tokens returned — WebAuthnAuthenticationResult
401Assertion verification failed — ProblemDetails
GET/api/v1/auth/webauthn/credentials

Lists the calling user's active passkeys for the Security-settings management surface. Returns an envelope `{ data: [...] }`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Enrolled passkeys returned. — WebAuthnCredentialListResponse
401User not authenticated. — ProblemDetails
DELETE/api/v1/auth/webauthn/credentials/{id}

Removes (deactivates) one of the calling user's passkeys.

Requires a fresh (≤ 5 minutes) GPG 44 medium step-up elevation, `act=passkey-removal`, on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IPasskeyRemovalStepUpGate; DVS-4.4, TF 1.0 §7.3.1.c): removing a way to sign in is not something a bearer session alone may do. Checked before the credential is looked up, so a refusal says nothing about which passkeys exist.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

204Credential removed.
401No acceptable step-up elevation (`step-up-required`, or `step-up-resource-mismatch`). — ProblemDetails
404Credential not found or not owned by the caller. — ProblemDetails
PATCH/api/v1/auth/webauthn/credentials/{id}

Renames one of the calling user's passkeys.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

204Credential renamed.
400Invalid name. — ProblemDetails
404Credential not found or not owned by the caller. — ProblemDetails
POST/api/v1/auth/webauthn/login/complete

Completes a WebAuthn authentication ceremony. Verifies the assertion response and issues authentication tokens on success.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication successful, tokens returned — WebAuthnAuthenticationResult
401Assertion verification failed — ProblemDetails
POST/api/v1/auth/webauthn/login/options

Begins a WebAuthn authentication ceremony. Returns credential request options including a challenge for the client to pass to navigator.credentials.get(). Supports both identified (user known) and discoverable (passkey) flows.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication options returned — WebAuthnAuthenticationOptions
POST/api/v1/auth/webauthn/passwordless/challenge

Issues a passwordless WebAuthn challenge with an EMPTY `allowCredentials` list so the authenticator picks a discoverable credential (passkey). No username is collected at this step; the user is identified by the `userHandle` the authenticator returns at login time.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Challenge issued — PasswordlessLoginChallengeResult
POST/api/v1/auth/webauthn/passwordless/login

Completes a passwordless WebAuthn login by verifying the assertion against the credential identified by the supplied `userHandle`. On success returns full authentication tokens — this is a primary-factor login, no password involved.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Login successful, tokens returned — PasswordlessLoginResult
401Verification failed — ProblemDetails
POST/api/v1/auth/webauthn/register/begin

Begins a WebAuthn registration ceremony. Returns credential creation options including a challenge for the client to pass to navigator.credentials.create().

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved with a factor the account already has (DVS-4.4b): otherwise a bearer session alone could add its own passkey and then pass every other step-up with it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Registration options returned — WebAuthnRegistrationOptions
401User not authenticated, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/auth/webauthn/register/complete

Completes a WebAuthn registration ceremony. Verifies the attestation response from the authenticator and stores the credential.

Requires the same fresh `act=authenticator-enrolment` elevation as `register/begin` (DVS-4.4b), so a ceremony begun with one cannot be finished after it has gone stale.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Credential registered successfully — WebAuthnRegistrationResult
400Attestation verification failed — ProblemDetails
401No acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/auth/webauthn/register/options

Begins a WebAuthn registration ceremony. Returns credential creation options including a challenge for the client to pass to navigator.credentials.create().

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved with a factor the account already has (DVS-4.4b): otherwise a bearer session alone could add its own passkey and then pass every other step-up with it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Registration options returned — WebAuthnRegistrationOptions
401User not authenticated, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/webauthn/authenticate/begin

Begins a WebAuthn authentication ceremony. Returns credential request options including a challenge for the client to pass to navigator.credentials.get(). Supports both identified (user known) and discoverable (passkey) flows.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication options returned — WebAuthnAuthenticationOptions
POST/api/v1/webauthn/authenticate/complete

Completes a WebAuthn authentication ceremony. Verifies the assertion response and issues authentication tokens on success.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication successful, tokens returned — WebAuthnAuthenticationResult
401Assertion verification failed — ProblemDetails
GET/api/v1/webauthn/credentials

Lists the calling user's active passkeys for the Security-settings management surface. Returns an envelope `{ data: [...] }`.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Enrolled passkeys returned. — WebAuthnCredentialListResponse
401User not authenticated. — ProblemDetails
DELETE/api/v1/webauthn/credentials/{id}

Removes (deactivates) one of the calling user's passkeys.

Requires a fresh (≤ 5 minutes) GPG 44 medium step-up elevation, `act=passkey-removal`, on `X-Step-Up-Token` (Essence.Identity.Auth.Api.Security.IPasskeyRemovalStepUpGate; DVS-4.4, TF 1.0 §7.3.1.c): removing a way to sign in is not something a bearer session alone may do. Checked before the credential is looked up, so a refusal says nothing about which passkeys exist.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

No request body.

Responses

204Credential removed.
401No acceptable step-up elevation (`step-up-required`, or `step-up-resource-mismatch`). — ProblemDetails
404Credential not found or not owned by the caller. — ProblemDetails
PATCH/api/v1/webauthn/credentials/{id}

Renames one of the calling user's passkeys.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

204Credential renamed.
400Invalid name. — ProblemDetails
404Credential not found or not owned by the caller. — ProblemDetails
POST/api/v1/webauthn/login/complete

Completes a WebAuthn authentication ceremony. Verifies the assertion response and issues authentication tokens on success.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication successful, tokens returned — WebAuthnAuthenticationResult
401Assertion verification failed — ProblemDetails
POST/api/v1/webauthn/login/options

Begins a WebAuthn authentication ceremony. Returns credential request options including a challenge for the client to pass to navigator.credentials.get(). Supports both identified (user known) and discoverable (passkey) flows.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Authentication options returned — WebAuthnAuthenticationOptions
POST/api/v1/webauthn/passwordless/challenge

Issues a passwordless WebAuthn challenge with an EMPTY `allowCredentials` list so the authenticator picks a discoverable credential (passkey). No username is collected at this step; the user is identified by the `userHandle` the authenticator returns at login time.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Challenge issued — PasswordlessLoginChallengeResult
POST/api/v1/webauthn/passwordless/login

Completes a passwordless WebAuthn login by verifying the assertion against the credential identified by the supplied `userHandle`. On success returns full authentication tokens — this is a primary-factor login, no password involved.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Login successful, tokens returned — PasswordlessLoginResult
401Verification failed — ProblemDetails
POST/api/v1/webauthn/register/begin

Begins a WebAuthn registration ceremony. Returns credential creation options including a challenge for the client to pass to navigator.credentials.create().

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved with a factor the account already has (DVS-4.4b): otherwise a bearer session alone could add its own passkey and then pass every other step-up with it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Registration options returned — WebAuthnRegistrationOptions
401User not authenticated, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/webauthn/register/complete

Completes a WebAuthn registration ceremony. Verifies the attestation response from the authenticator and stores the credential.

Requires the same fresh `act=authenticator-enrolment` elevation as `register/begin` (DVS-4.4b), so a ceremony begun with one cannot be finished after it has gone stale.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Credential registered successfully — WebAuthnRegistrationResult
400Attestation verification failed — ProblemDetails
401No acceptable step-up elevation (`step-up-required`) — ProblemDetails
POST/api/v1/webauthn/register/options

Begins a WebAuthn registration ceremony. Returns credential creation options including a challenge for the client to pass to navigator.credentials.create().

Requires a fresh (≤ 5 minutes) `act=authenticator-enrolment` elevation on `X-Step-Up-Token`, proved with a factor the account already has (DVS-4.4b): otherwise a bearer session alone could add its own passkey and then pass every other step-up with it.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Registration options returned — WebAuthnRegistrationOptions
401User not authenticated, or no acceptable step-up elevation (`step-up-required`) — ProblemDetails

Schemas

AcceptInvitationAsMemberResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
invitationIdstring (uuid)no—
organizationIdstring (uuid)no—
sponsoredEntitlementGrantedbooleanno—

AcceptInvitationCommand

PropertyTypeRequiredDescription
deviceFingerprintstring | nullno—
deviceTypestring | nullno—
firstNamestring | nullno—
ipAddressstring | nullno—
lastNamestring | nullno—
passwordHashstring | nullno—
tokenstring | nullno—
userAgentstring | nullno—

AcceptInvitationResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
homeRegionstring | nullno—
organizationIdstring (uuid)no—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
sponsoredEntitlementGrantedbooleanno—
userIdstring (uuid)no—

AccountActionNoticeDto

PropertyTypeRequiredDescription
actionstring | nullno—
actionIdstring (uuid)no—
appealCaseRefstring | nullno—
appealablebooleanno—
durationstring | nullno—
effectiveAtstring (date-time)no—
policyClausestring | nullno—
reasonCategorystring | nullno—
scopestring | nullno—
statusstring | nullno—

AccountClosureCancelRequest

The two values the closure alert's link carries.

PropertyTypeRequiredDescription
closureIdstring (uuid)noThe closure (the closure event's id).
tokenstring | nullnoThe link's single-use token.

AccountClosureCancelResponse

A live link was used: the closure is cancelled and the account is open.

PropertyTypeRequiredDescription
cancelledbooleanno—

AccountClosureDecisionResult

PropertyTypeRequiredDescription
accountIdstring (uuid)no—
appealRoutestring | nullno—
approvedAtstring (date-time) | nullno—
approvedBystring (uuid) | nullno—
causestring | nullno—
closureEventIdstring (uuid) | nullno—
decidedAtstring (date-time) | nullno—
decidedBystring (uuid) | nullno—
decisionIdstring (uuid)no—
evidenceReferencestring | nullno—
openedAtstring (date-time)no—
reasonCategorystring | nullno—
referencestring | nullno—
rejectedAtstring (date-time) | nullno—
rejectedBystring (uuid) | nullno—
shredNotBeforestring (date-time) | nullno—
statusstring | nullno—

AccountFactorHoldView

A hold on the caller's text-message factor, as the holder sees it. No number, ids and instants only.

PropertyTypeRequiredDescription
canConfirmHerebooleannoWhether this session may end it now.
eventstring | nullnoThe change the operator attested: `sim_swap`, `esim_reprovision`, `port_out` or `port_in`.
factorstring | nullno`sms`.
heldUntilstring (date-time)noWhen it lapses unless ended earlier (UTC).
holdIdstring (uuid)noThe hold.
placedAtstring (date-time)noWhen it came into force (UTC).
releasePathstring | nullnoHow it ended, if it has.
releasePathsstring[] | nullnoHow it can end.
releasedAtstring (date-time) | nullnoWhen it ended (UTC), if it has.

AccountMergeGovernanceResult

PropertyTypeRequiredDescription
modestring | nullno—
orgNamestring | nullno—
reasonstring | nullno—
resolutionstring | nullno—

AccountMergeReversibilityResult

PropertyTypeRequiredDescription
posturestring | nullno—
windowDaysinteger (int32) | nullno—

AccountMergeStatusResult

PropertyTypeRequiredDescription
committedAtstring (date-time) | nullno—
mergeSessionIdstring (uuid)no—
reversedAtstring (date-time) | nullno—
reversibleUntilstring (date-time) | nullno—
stagesMergeStageProgressDto[] | nullno—
statusstring | nullno—

ActingAsContextDto

PropertyTypeRequiredDescription
capabilitiesstring[] | nullno—
delegationIdstring (uuid)no—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid)no—
isActivebooleanno—
principalUserIdstring (uuid)no—
revokedAtstring (date-time) | nullno—
surfacestring | nullno—

ActiveDeviceSummary

PropertyTypeRequiredDescription
deviceIdstring (uuid)no—
deviceTypestring | nullno—
lastUsedAtstring (date-time) | nullno—
namestring | nullno—

ActiveProbateRoleResult

PropertyTypeRequiredDescription
grantIdstring (uuid) | nullno—
hasActiveGrantbooleanno—

AddExecutorOfficerRequest

Request body for adding an individual to the executor roster.

PropertyTypeRequiredDescription
officerReferencestring | nullnoOptional opaque, org-chosen, non-PII reference (e.g. a staff number).
officerUserIdstring (uuid)noThe officer's user-principal id.

AdminUserPageDto

PropertyTypeRequiredDescription
itemsAdminUserSummaryDto[] | nullno—
pageinteger (int32)no—
pageSizeinteger (int32)no—
totalCountinteger (int32)no—

AdminUserSummaryDto

PropertyTypeRequiredDescription
administrativeStatusstring | nullno—
createdAtstring (date-time)no—
currentAccountActionIdstring (uuid) | nullno—
emailstring | nullno—
emailVerifiedbooleanno—
failedLoginAttemptsinteger (int32)no—
firstNamestring | nullno—
homeRegionstring | nullno—
isActivebooleanno—
lastLoginAtstring (date-time) | nullno—
lastNamestring | nullno—
lockoutEndAtstring (date-time) | nullno—
mfaEnabledbooleanno—
phoneVerifiedbooleanno—
preferredLocalestring | nullno—
rolesstring[] | nullno—
userIdstring (uuid)no—

AdviceAgencyRow

PropertyTypeRequiredDescription
adviserCapabilitiesstring[] | nullno—
agencyIdstring (uuid)no—
agencyNamestring | nullno—
isRecognisedbooleanno—
organizationIdstring (uuid)no—
recognisedAtstring (date-time)no—
regulatoryBodystring | nullno—
regulatoryReferencestring | nullno—
statusstring | nullno—
statusChangedAtstring (date-time)no—
statusReasonstring | nullno—

AdviserCaseAssignmentRow

PropertyTypeRequiredDescription
adviserUserIdstring (uuid)no—
assignedAtstring (date-time)no—
assignedByUserIdstring (uuid)no—
assignmentIdstring (uuid)no—
caseReferencestring | nullno—
clientUserIdstring (uuid)no—
endReasonstring | nullno—
endedAtstring (date-time) | nullno—
endedByUserIdstring (uuid) | nullno—
isLivebooleanno—
reassignedToAdviserUserIdstring (uuid) | nullno—
statusstring | nullno—

AdviserCaseloadResult

PropertyTypeRequiredDescription
agencyIdstring (uuid)no—
assignmentsAdviserCaseAssignmentRow[] | nullno—
liveCountinteger (int32)no—
totalCountinteger (int32)no—

AgentKeyResponse

Result of registering an agent key.

PropertyTypeRequiredDescription
agentReferencestring | nullnoThe agent.
replacedbooleannoTrue when an earlier key was replaced.
thumbprintstring | nullnoRFC 7638 thumbprint — the `cnf.jkt` the agent's tokens now carry.

AgentPublicJwkRequest

Body of `PUT …/{agentReference}/key`: one EC P-256 public JWK. Every member other than the four declared lands in Essence.Identity.Auth.Api.Controllers.AgentPublicJwkRequest.AdditionalMembers so it can be refused by name.

PropertyTypeRequiredDescription
crvstring | nullnoCurve — must be `P-256`.
ktystring | nullnoKey type — must be `EC`.
xstring | nullnox coordinate, base64url.
ystring | nullnoy coordinate, base64url.

AgentTokenRequest

Request body for an agent token exchange.

PropertyTypeRequiredDescription
agentReferencestring | nullnoThe agent's opaque reference.
secretstring | nullnoThe credential secret.

AgentTokenResponse

An issued agent session.

PropertyTypeRequiredDescription
expiresAtstring (date-time)noWhen it expires (the token's `exp`).
sessionTokenstring | nullnoThe agent access token — a platform JWT since AG-D1 (it was an opaque secret before). The field keeps its name so existing callers need no change.
tokenTypestring | nullnoHow to present Essence.Identity.Auth.Api.Controllers.AgentTokenResponse.SessionToken: always `Bearer` (CONTRACTS §2).

AnswerOutOfBandProofChallengeResult

PropertyTypeRequiredDescription
attemptsRemaininginteger (int32)no—
challengeIdstring (uuid)no—
outcomeOutOfBandProofOutcomeno—
provenbooleanno—

AnswerProofChallengeRequest

Answer request.

PropertyTypeRequiredDescription
codestring | nullnoThe one-time code as delivered to the account's own recovery address.

AppealCaseDto

PropertyTypeRequiredDescription
caseRefstring | nullno—
expectedResponseBystring (date-time)no—
statusstring | nullno—
submittedAtstring (date-time)no—

ApplyAccountActionRequest

Body for `POST /api/v1/account/actions` (the EPIC 48 moderation decision). The operator id is NOT accepted here — it is stamped server-side from the authenticated principal for un-spoofable due-process attribution.

PropertyTypeRequiredDescription
actionstring | nullnoWire token of the graduated action (`warn`…`reinstate`…`dismiss`).
durationstring | nullnoOptional human/token duration for a time-boxed action.
policyClausestring | nullnoPolicy / ToS clause the action is anchored to (mandatory).
reasonCategorystring | nullnoCategory-level reason disclosed to the user (mandatory).
reasonInternalRefstring | nullnoOpaque pointer to the operator's internal notes; never the note text.
reportIdstring (uuid) | nullnoOriginating abuse-report id, when the action came from a triaged report.
scopestring | nullnoScope token (`account` or a capability); defaults to `account`.
targetUserIdstring (uuid)noThe end-user account the action targets.

ApplyAccountActionResult

PropertyTypeRequiredDescription
actionIdstring (uuid)no—
appealablebooleanno—
statusstring | nullno—

AssignAdviserToCaseRequest

Request body for assigning an adviser to a client's case.

PropertyTypeRequiredDescription
adviserUserIdstring (uuid)noThe adviser taking the case.
caseReferencestring | nullnoThe agency's own opaque case reference.
clientUserIdstring (uuid)noThe client whose case it is.

AssistActionDto

PropertyTypeRequiredDescription
actionIdstring (uuid)no—
actionTypestring | nullno—
assistantUserIdstring (uuid)no—
occurredAtstring (date-time)no—
sessionIdstring (uuid)no—
targetRefstring | nullno—
touchedKeyMaterialbooleanno—

AssistedRecoveryRequestBody

Request body for a delegated assisted-recovery request.

PropertyTypeRequiredDescription
contextstring | nullnoOptional non-PII free-text hint to help the helpdesk verify the subject.
reasonstring | nullnoWhy self-service is impossible — `lost-mfa` | `locked`. Optional: omitted or blank defaults to `locked`. Any OTHER value is refused `400` rather than defaulted, because a reason the subject stated and a reason they did not state are different facts and the helpdesk agent reading the case cannot tell them apart afterwards (#8916).
workEmailstring | nullnoThe subject's work email — routing key into their org helpdesk queue.

AssistedRecoveryRequestResponse

Response for an accepted assisted-recovery request.

PropertyTypeRequiredDescription
requestRefstring | nullnoThe opaque request reference the subject can quote to their helpdesk.

AssistedRecoveryStatusResponse

Subject-facing status of a delegated assisted-recovery case (journey step 1b). Metadata only — see M:Essence.Identity.Auth.Api.Controllers.AssistedRecoveryController.GetStatus(System.Guid,System.Threading.CancellationToken).

PropertyTypeRequiredDescription
canCompletebooleannoTrue when the subject may redeem their recovery token now.
decidedAtstring (date-time) | nullnoUTC instant the case was decided or completed; null while queued.
decisionReasonstring | nullnoMachine reason slug when rejected; null otherwise.
initiatedAtstring (date-time)noUTC instant the request was raised.
reasonstring | nullnoThe subject's own stated reason (`lost-mfa` | `locked`).
requestRefstring | nullnoEcho of the reference queried.
statusstring | nullno`queued` | `authorised` | `rejected` | `completed` | `withdrawn`.

AssurancePostureResult

PropertyTypeRequiredDescription
attestedAtstring (date-time) | nullno—
attestedBystring | nullno—
levelstring | nullno—
verifiedbooleanno—

AssuranceRecordResult

PropertyTypeRequiredDescription
auditAnchorReferencestring | nullno—
authoritystring | nullno—
canProceedbooleanno—
lastProvenancestring | nullno—
levelstring | nullno—
levelRecordedAtstring (date-time)no—
proofingCompletedbooleanno—
proofingDispositionstring | nullno—
proofingPolicystring | nullno—
recoveryDecisionRecordedAtstring (date-time) | nullno—
recoveryDispositionstring | nullno—
subjectUserIdstring (uuid)no—
validUntilstring (date-time) | nullno—

AttestContactFieldRequest

Request body for recording a contact-field provenance attestation.

PropertyTypeRequiredDescription
assurancestring | nullno`self_asserted | verified | attested`.
fieldKeystring | nullno—
signingKeyIdstring | nullno—

AttestProfessionalCredentialRequest

Request body for recording a professional-credential attestation.

PropertyTypeRequiredDescription
assurancestring | nullno`self_asserted | verified | attested`.
bodystring | nullno—
credentialTypestring | nullno—
expiresAtstring (date-time) | nullno—
fieldKeystring | nullno—
signingKeyIdstring | nullno—

BackfillSetupPostureRequest

Request body for the setup-posture backfill.

PropertyTypeRequiredDescription
afterIdstring (uuid) | nullnoKeyset cursor — process accounts with an id strictly greater than this. Omit to start at the beginning; pass back the previous call's `nextAfterId` to continue.
batchSizeinteger (int32) | nullnoAccounts per call. Clamped to Essence.Identity.Auth.Application.Commands.BackfillSetupPostureCommand.MaxBatchSize; a hard ceiling rather than a validation error, so a fat-fingered page size cannot move the whole table in one request.
dryRunbooleannoWhen true, count the match set and publish nothing.

BackfillSetupPostureResult

PropertyTypeRequiredDescription
announcedinteger (int32)no—
completebooleanno—
custodialinteger (int32)no—
examinedinteger (int32)no—
instantStampedinteger (int32)no—
nextAfterIdstring (uuid) | nullno—
totalAccountsinteger (int32)no—
verifiedinteger (int32)no—

BeginWebAuthnAuthenticationRequest

PropertyTypeRequiredDescription
userIdstring (uuid) | nullno—
userVerificationstring | nullno—

BeginWebAuthnRegistrationRequest

PropertyTypeRequiredDescription
authenticatorAttachmentstring | nullno—
requireResidentKeyboolean | nullnoNullable so the controller can distinguish "caller didn't send this" (→ defaults to TRUE, discoverable/passkey) from an explicit `false` opt-out. A plain `bool` here previously defaulted to `false` on every request that omitted the field — which was every FE call site — silently registering non-discoverable credentials that the usernameless passkey login could never find.
userVerificationstring | nullno—

BillingProfileDto

PropertyTypeRequiredDescription
displayNamestring | nullno—
emailstring | nullno—
existsbooleanno—
userIdstring (uuid)no—

BiometricReenrolmentOversightResult

PropertyTypeRequiredDescription
organizationIdstring (uuid)no—
rowsBiometricReenrolmentOversightRow[] | nullno—
stalledCountinteger (int32)no—
totalCountinteger (int32)no—

BiometricReenrolmentOversightRow

PropertyTypeRequiredDescription
currentStepstring | nullno—
detectedAtstring (date-time)no—
elapsedMinutesinteger (int32)no—
memberRefstring | nullno—
statusstring | nullno—

BiometricReenrolmentResult

PropertyTypeRequiredDescription
assuranceRefstring | nullno—
currentStepstring | nullno—
detectedAtstring (date-time)no—
lockoutStatestring | nullno—
mismatchReasonstring | nullno—
reestablishActionstring | nullno—
sessionIdstring (uuid)no—
statusstring | nullno—

BlockDeviceRequest

PropertyTypeRequiredDescription
reasonstring | nullno—

BlockDeviceResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—

BootstrapReturningNationalRequest

Request body for a returning-national bootstrap. It carries no origin jurisdiction, scheme or foreign LoA: those are read from the caller's own intake (#14018), and any such field a client still sends is ignored.

PropertyTypeRequiredDescription
matchedPriorSovereignVaultRefstring | nullno—
residualCheckSatisfiedbooleanno—

CancelPrimaryContactChangeResult

PropertyTypeRequiredDescription
cancelledAtstring (date-time)no—
changeIdstring (uuid)no—
statusstring | nullno—

CancelVerifiedNameChangeResult

PropertyTypeRequiredDescription
cancelledAtstring (date-time)no—
changeIdstring (uuid)no—
statusstring | nullno—

ChangeAdviceAgencyStandingRequest

Request body for changing an agency's recognition standing.

PropertyTypeRequiredDescription
actionstring | nullnoOne of `suspend`, `restore`, `withdraw`.
reasonstring | nullnoRequired for `suspend` and `withdraw`.

ChangePasswordRequest

Request body for `POST /password/change`. Both fields are client-derived PBKDF2 hashes — never plaintext passwords.

PropertyTypeRequiredDescription
breachCheckstring | nullnoThe client's breached-password check of the new password (DVS-4.7): `"passed"`, `"not_performed"`, or absent (recorded as `not_reported`). An honest-client fact.
currentPasswordHashstring | nullno—
newPasswordHashstring | nullno—
passwordPolicyVersioninteger (int32) | nullnoThe client password-policy version (DVS-4.7); optional.

ChangePasswordResult

PropertyTypeRequiredDescription
errorMessagestring | nullno—
sessionsRevokedinteger (int32)no—
successbooleanno—

ChangeProfessionalAdviserStandingRequest

Request body for changing an adviser's standing.

PropertyTypeRequiredDescription
actionstring | nullnoOne of `suspend`, `reinstate`, `revoke`.
reasonstring | nullnoRequired for `suspend` and `revoke`.

ChangeSafeguardingAuthorityStandingRequest

Request body for changing a body's recognition standing.

PropertyTypeRequiredDescription
actionstring | nullnoOne of `suspend`, `restore`, `withdraw`.
reasonstring | nullnoRequired for `suspend` and `withdraw`.

ChangeSafeguardingOfficerStandingRequest

Request body for changing an officer's standing.

PropertyTypeRequiredDescription
actionstring | nullnoOne of `suspend`, `reinstate`, `revoke`.
reasonstring | nullnoRequired for `suspend` and `revoke`.

ClaimVaultContextDto

PropertyTypeRequiredDescription
alreadyClaimedbooleanno—
requiredAssurancestring | nullno—
statusstring | nullno—
subjectIdstring (uuid)no—
whatChangesstring[] | nullno—
whatYouKeepstring[] | nullno—

CoAuthoriserDirectoryEntry

PropertyTypeRequiredDescription
authorisedSincestring (date-time)no—
authorityIdstring (uuid)no—
authorityNamestring | nullno—
officerReferencestring | nullno—
officerUserIdstring (uuid)no—
verificationLevelstring | nullno—

CoAuthoriserDirectoryResult

PropertyTypeRequiredDescription
officersCoAuthoriserDirectoryEntry[] | nullno—
totalCountinteger (int32)no—

CommitAccountMergeRequest

Wire body to commit a merge. The destructive confirm requires Essence.Identity.Auth.Api.Controllers.CommitAccountMergeRequest.AcknowledgeRetirement and a fresh survivor Essence.Identity.Auth.Api.Controllers.CommitAccountMergeRequest.StepUp (WCAG 2.2 SC 3.3.4, debt-2026-07-03-226); grant references stay optional.

PropertyTypeRequiredDescription
acknowledgeRetirementbooleannoThe survivor's affirmative acknowledgement that the folded account is retired.
droppedGrantRefsstring[] | nullnoGrants not carried over — they end with the retired account (debt-2026-08-10-005).
policyDecisionMergePolicyDecisionInputno—
reconfirmRequiredGrantRefsstring[] | nullno—
repointedGrantRefsstring[] | nullno—
stepUpMergeStepUpDtono—
suspendedGrantRefsstring[] | nullnoRegulated grants suspended pending re-confirmation (debt-2026-08-10-005).

CommitAccountMergeResponse

PropertyTypeRequiredDescription
auditRefstring | nullnoThe EPIC 4 / 12 audit anchor reference for this merge (debt-2026-08-10-005) — the same value carried on `AccountMergedIntegrationEvent`, so the member's receipt and the organisation's projection quote one anchor for one merge.
mergeSessionIdstring (uuid)no—
mergedAtstring (date-time)no—
reversibleUntilstring (date-time)no—
statusstring | nullno—

CommitPrimaryContactChangeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
committedAtstring (date-time)no—
statusstring | nullno—

CommitVerifiedNameChangeRequest

Wire body to commit the change (the EPIC 6 recipient split).

PropertyTypeRequiredDescription
notifiedCountinteger (int32)no—
withheldCountinteger (int32)no—

CommitVerifiedNameChangeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
committedAtstring (date-time)no—
notifiedCountinteger (int32)no—
statusstring | nullno—
withheldCountinteger (int32)no—

CommunityVouchedAccount

PropertyTypeRequiredDescription
auditAnchorReferencestring | nullno—
levelstring | nullno—
levelRecordedAtstring (date-time)no—
postureCommunityVouchedPostureno—
provenancestring | nullno—
subjectUserIdstring (uuid)no—
validUntilstring (date-time) | nullno—

CommunityVouchedAccountsResult

PropertyTypeRequiredDescription
accountsCommunityVouchedAccount[] | nullno—
expiringWithinDaysinteger (int32)no—
truncatedbooleanno—

CommunityVouchedPosture

0 | 1 | 2 with no declared properties.

CompleteAssistedRecoveryBody

Request body for completing a delegated assisted recovery (journey step 4).

PropertyTypeRequiredDescription
newPasswordHashstring | nullnoThe <b>client-derived</b> hash of the subject's new credential. Plaintext credentials never reach this service (zero-knowledge).
recoveryTokenstring | nullnoThe opaque, single-use CC-061 authorise-only recovery-token reference the subject holds. A lookup handle bound to them — never key material.

CompleteAssistedRecoveryResponse

Response for a completed assisted recovery.

PropertyTypeRequiredDescription
completedbooleannoTrue when the credential was set and the case closed.
mfaReenrolmentRequiredbooleannoTrue when a lost second factor was cleared and the subject must re-enrol MFA after signing in.

CompleteMfaLoginCommand

PropertyTypeRequiredDescription
challengeTokenstring | nullno—
codestring | nullno—
ipAddressstring | nullno—
methodMfaMethodno—
rememberDeviceboolean | nullno—
userAgentstring | nullno—

CompleteProofingRequest

Body for recording a subject-reported proofing outcome.

PropertyTypeRequiredDescription
failureReasonstring | nullnoShort, non-PII failure reason when Essence.Identity.Auth.Api.Controllers.CompleteProofingRequest.Succeeded is false.
succeededbooleannoDefaults to `false` (fail closed). Sending `true` on the subject endpoint is refused with 403 — a success must be adjudicated by the proofing provider, not asserted by the subject.

CompleteWebAuthnAuthenticationRequest

PropertyTypeRequiredDescription
authenticatorDatastring | nullno—
clientDataJsonstring | nullno—
credentialIdstring | nullno—
deviceFingerprintstring | nullnoThe browser's device fingerprint, as its password sign-in sends it (#17966).
deviceTypestring | nullnoA `DeviceType` name; used only when the fingerprint registers a new device.
sessionIdstring | nullno—
signaturestring | nullno—
userHandlestring | nullno—

CompleteWebAuthnRegistrationRequest

PropertyTypeRequiredDescription
attestationObjectstring | nullno—
clientDataJsonstring | nullno—
deviceNamestring | nullno—
sessionIdstring | nullno—
transportsstring[] | nullno—

ConfirmPhoneVerificationRequest

Body of `POST /api/v1/auth/phone/verification/confirm`.

PropertyTypeRequiredDescription
codestring | nullno—

ConsentToAssistRequest

Wire body for recording consent-to-assist.

PropertyTypeRequiredDescription
assistantUserIdstring (uuid)no—
assistedUserIdstring (uuid) | nullnoThe assisted owner. Must be the authenticated caller when supplied (a mismatch is rejected with 403); omit it and the caller is used. Retained so an existing client that sends its own id keeps working — it is no longer a way to name somebody else.
authorityBasisstring | nullno—
expiresAtstring (date-time) | nullno—
scopestring | nullno—
sessionIdstring (uuid)no—

ConsentToAssistResponse

Response body for the consent call.

PropertyTypeRequiredDescription
alreadyExistedbooleanno—
grantIdstring (uuid)no—
sessionIdstring (uuid)no—

ContactFieldAttestationDto

PropertyTypeRequiredDescription
assurancestring | nullno—
fieldKeystring | nullno—
signingKeyIdstring | nullno—
statusstring | nullno—

ContinueAfterDeviceLimitCommand

PropertyTypeRequiredDescription
challengeTokenstring | nullno—
ipAddressstring | nullno—
signOutDeviceIds(string (uuid))[] | nullno—
userAgentstring | nullno—

CreateTestTenantRequest

Request body for M:Essence.Identity.Auth.Api.Controllers.TestTenantsController.CreateTestTenant(Essence.Identity.Auth.Api.Controllers.CreateTestTenantRequest).

PropertyTypeRequiredDescription
emailstring | nullno—
homeRegionstring | nullno—
passwordHashstring | nullno—

CreateTestTenantResult

PropertyTypeRequiredDescription
userIdstring (uuid)no—

CustodialEvidenceResult

PropertyTypeRequiredDescription
codestring | nullno—
labelstring | nullno—
notestring | nullno—
requiredbooleanno—

CustodialInstrumentResult

PropertyTypeRequiredDescription
codestring | nullno—
labelstring | nullno—
notestring | nullno—

CustodialOrderResult

PropertyTypeRequiredDescription
decidedAtIsostring | nullno—
decisionAuthorityReferencestring | nullno—
decisionProvenancestring | nullno—
grantedRightsstring[] | nullno—
identityProvisionedbooleanno—
instrumentCodestring | nullno—
instrumentLabelstring | nullno—
jurisdictionCodestring | nullno—
orderProofIdstring | nullno—
remediationstring | nullno—
statusstring | nullno—
submittedAtIsostring | nullno—

CustodialPolicyResult

PropertyTypeRequiredDescription
acceptedInstrumentsCustodialInstrumentResult[] | nullno—
authoriserRolestring | nullno—
jurisdictionstring | nullno—
jurisdictionLabelstring | nullno—
minimumAssurancestring | nullno—
requiredEvidenceCustodialEvidenceResult[] | nullno—
sourcestring | nullno—

DeactivateUserResult

PropertyTypeRequiredDescription
cancelBystring (date-time) | nullno—
messagestring | nullno—
shredNotBeforestring (date-time) | nullno—
successbooleanno—

DecideCustodialOrderRequest

The named authoriser's decision on a pending order.

PropertyTypeRequiredDescription
decidedByRefstring | nullnoThe external authority's own reference for its decision (their case or order reference).
remediationstring | nullnoRequired on refusal: what the custodian must do next.
verifiedbooleanno—

DecideFraudClosureRequest

Body of `POST account-closure-decisions/fraud`. The decider is the caller, never a body field.

PropertyTypeRequiredDescription
accountIdstring (uuid)noThe account to close.
evidenceReferencestring | nullnoThe fraud case reference — never the evidence.
reasonCategorystring | nullno`fraudulent-creation`, `synthetic-identity` or `terms-breach-unresolved-after-appeal`.

DeclareOperatingJurisdictionRequest

Body of `PUT /api/v1/sessions/current/operating-jurisdiction`.

PropertyTypeRequiredDescription
jurisdictionstring | nullnoISO 3166-1 alpha-2 code of the jurisdiction the caller is working from.

DeclineInvitationCommand

PropertyTypeRequiredDescription
tokenstring | nullno—

DeclineInvitationResult

PropertyTypeRequiredDescription
declinedbooleanno—
invitationIdstring (uuid)no—

DeclineSupportAccessRequestBody

Request body for declining a held support-access request (#21869).

PropertyTypeRequiredDescription
reasonCodestring | nullno—

DelegateAccessGrantCreatedResponse

Response body for the grant call.

PropertyTypeRequiredDescription
alreadyExistedbooleanno—
grantIdstring (uuid)no—

DelegateAccessGrantDto

PropertyTypeRequiredDescription
authorityBasisstring | nullno—
capabilitiesstring[] | nullno—
delegateUserIdstring (uuid)no—
delegationIdstring (uuid)no—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid)no—
principalUserIdstring (uuid)no—
revokedAtstring (date-time) | nullno—
statusDelegateAccessStatusno—
surfacestring | nullno—

DelegateAccessStatus

0 | 1 | 2 with no declared properties.

DelegatedAgentDto

PropertyTypeRequiredDescription
agentIdstring (uuid)no—
agentReferencestring | nullno—
createdAtstring (date-time)no—
grantedScopesstring[] | nullno—
namestring | nullno—
organisationIdstring (uuid) | nullno—
publicKeyJwkstring | nullno—
publicKeyRegisteredAtstring (date-time) | nullno—
publicKeyThumbprintstring | nullno—
statusDelegatedAgentStatusno—
suspendedAtstring (date-time) | nullno—
suspendedForIncidentIdstring (uuid) | nullno—
suspensionReasonstring | nullno—
suspensionReferencestring | nullno—

DelegatedAgentStatus

0 | 1 | 2 with no declared properties.

DeleteDeviceResult

PropertyTypeRequiredDescription
messagestring | nullno—
sessionsRevokedinteger (int32)no—
successbooleanno—

DesignateSafeguardingOfficerRequest

Request body for designating an officer.

PropertyTypeRequiredDescription
officerReferencestring | nullnoOptional opaque, authority-chosen, non-PII reference (a warrant or staff number).
officerUserIdstring (uuid)noThe officer's user-principal id.

DetectedAccountResult

PropertyTypeRequiredDescription
accountIdstring (uuid)no—
detectedAtstring (date-time)no—
domainstring | nullno—
domainProofIdstring (uuid)no—
emailMaskedstring | nullno—
statestring | nullno—
subjectIdstring (uuid)no—

DeviceDto

PropertyTypeRequiredDescription
createdAtstring (date-time)no—
deviceTypeDeviceTypeno—
fingerprintstring | nullno—
friendlyNamestring | nullno—
idstring (uuid)no—
ipAddressstring | nullno—
lastIpAddressstring | nullno—
lastUsedAtstring (date-time) | nullno—
trustLevelDeviceTrustLevelno—
trustedAtstring (date-time) | nullno—
updatedAtstring (date-time) | nullno—
userAgentstring | nullno—
userIdstring (uuid)no—

DeviceLimitPause

PropertyTypeRequiredDescription
activeDevicesActiveDeviceSummary[] | nullno—
allowanceinteger (int64)no—
challengeTokenstring | nullno—
expiresAtstring (date-time)no—
messagestring | nullno—
upgradeMessagestring | nullno—

DeviceTrustLevel

0 | 1 | 2 | 3 with no declared properties.

DeviceType

0 | 1 | 2 | 3 | 4 | 5 with no declared properties.

DisableMfaCommand

PropertyTypeRequiredDescription
currentPasswordstring | nullno—
userIdstring (uuid)no—

DisableMfaResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—

DiscoverRealmRequest

Request for `POST /discover`. Supply exactly one identifier: `host` for an org-branded sign-in URL, or `email`/`emailHash` for a general user. `host` takes precedence. All fields are optional — a request with none is answered with the region-default realm, the same as any unresolved identifier, so an empty probe is not distinguishable either.

PropertyTypeRequiredDescription
domainstring | nullnoThe sign-in address's email DOMAIN, for clients that prefer not to send the address at all. Wins over the domain derived from Essence.Identity.Auth.Api.Controllers.DiscoverRealmRequest.Email.
emailstring | nullnoGeneral user's sign-in address. Only its DOMAIN is used to resolve a realm and only the domain is forwarded to the registry; the address itself is never stored or forwarded, and its hash is used only as the internal audit trail's subject reference (#8633).
emailHashstring | nullnoPre-computed SHA-256 hex of the lower-cased address. Retained as the audit subject reference for clients that send neither the address nor the domain; it resolves no realm, because a key the caller chooses and the answer varies with is an account-existence oracle (#8633).
hoststring | nullnoOrg-branded sign-in host, e.g. `acme.gb.onessence.digital`.

DiscoverRealmResponse

Response for `POST /discover` — where to broker the sign-in. Deliberately carries no "resolved" flag: whether the identifier was known is exactly what NFR-09.020 forbids disclosing.

PropertyTypeRequiredDescription
authorizeUrlstring | nullnoThe completing instance's OIDC authorize endpoint to redirect to.
realmTokenstring | nullnoRegistry-signed, short-TTL realm-redirect descriptor. Opaque to the client.
regionstring | nullnoISO-3166 alpha-2 region of the completing instance.
statestring | nullnoOpaque continuation value to carry through the redirect as the OIDC `state`.

DomainDetectionResult

PropertyTypeRequiredDescription
accountsDetectedAccountResult[] | nullno—
completedAtstring (date-time)no—
domainstring | nullno—
domainProofIdstring (uuid)no—
runIdstring (uuid)no—

DormancyInfo

PropertyTypeRequiredDescription
effectiveThresholdMonthsinteger (int32) | nullno—
isDormantReactivationbooleanno—
lastActiveLabelstring | nullno—
monthsInactiveinteger (int32)no—
thresholdSourcestring | nullno—

EmergencyFreezeRequest

Request body for the emergency freeze. `reason` is an optional non-PII token.

PropertyTypeRequiredDescription
reasonstring | nullnoWhy the freeze is being placed (e.g. `suspected-account-takeover`).

EmergencyFreezeResponse

Response for a successful emergency freeze.

PropertyTypeRequiredDescription
frozenAtstring (date-time)noUTC instant the freeze is in force from.
incidentIdstring (uuid)noThe takeover incident the freeze opened or joined (#7393).
sessionsTerminatedinteger (int32)noNumber of active sessions terminated by the freeze.

EnableMfaWithTotpResult

PropertyTypeRequiredDescription
backupCodesstring[] | nullno—
qrCodeBase64string | nullno—
qrCodeUristring | nullno—
successbooleanno—
totpSecretstring | nullno—

EndAdviserCaseAssignmentRequest

Request body for closing a case.

PropertyTypeRequiredDescription
reasonstring | nullnoWhy the case is closing.

EnrolAlternateCredentialRequest

Body of `PUT /api/v1/users/me/protection-status/alternate-credential`. Carries the client-derived hash of the alternate passphrase and nothing else — zero-knowledge: the passphrase itself never reaches the server.

PropertyTypeRequiredDescription
passwordHashstring | nullnoClient-derived hash of the alternate passphrase (same derivation as sign-in).

EnrolRecoveryPhraseRequest

Request body for `POST /recovery-phrase/enrol`. Essence.Identity.Auth.Api.Controllers.EnrolRecoveryPhraseRequest.RecoveryProof is the client-derived recovery proof (hex, ≥ 64 chars) — never the 24-word phrase or the seed.

PropertyTypeRequiredDescription
recoveryProofstring | nullno—

EnrolSharedDeviceRequest

Enrolment body. Carries no organisation — that comes from the route.

PropertyTypeRequiredDescription
labelstring | nullnoThe administrator's name for the machine.
publicKeyJwkstring | nullnoThe machine's EC P-256 public JWK, as a JSON string.

EnrolSupportAgentRequestBody

Request body for enrolling a support agent.

PropertyTypeRequiredDescription
appIdstring (uuid)no—
displayNamestring | nullno—
emailstring | nullno—
rolestring | nullno—

EstablishActingAsSessionRequest

Request body for establishing an acting-as session.

PropertyTypeRequiredDescription
grantIdstring (uuid)no—

EstablishActingAsSessionResult

PropertyTypeRequiredDescription
actingAsTokenstring | nullno—
capabilitiesstring[] | nullno—
delegationIdstring (uuid)no—
expiresAtstring (date-time)no—
grantIdstring (uuid)no—
principalUserIdstring (uuid)no—
surfacestring | nullno—
tokenIdstring | nullno—

EstablishGuardianshipRequest

Request body for establishing a guardianship (Step 1 seam).

PropertyTypeRequiredDescription
childDisplayNamestring | nullnoThe guardian-supplied ward display label.
childIdstring (uuid) | nullnoOptional pre-existing minor platform id; when absent a fresh id is minted.
guardiansGuardianLinkDto[] | nullnoThe named guardian links. Must contain exactly one primary.

ExecutorOfficerAttestationResult

PropertyTypeRequiredDescription
attestedbooleanno—
officerUserIdstring (uuid)no—
organizationIdstring (uuid)no—
verifiedAtstring (date-time) | nullno—

ExecutorOfficerRow

PropertyTypeRequiredDescription
attestedbooleanno—
officerReferencestring | nullno—
officerUserIdstring (uuid)no—
removalReasonstring | nullno—
removedAtstring (date-time) | nullno—
rosteredAtstring (date-time)no—
statusstring | nullno—
verificationLevelstring | nullno—
verifiedAtstring (date-time) | nullno—

ExecutorRosterResult

PropertyTypeRequiredDescription
officersExecutorOfficerRow[] | nullno—
organizationIdstring (uuid)no—
totalCountinteger (int32)no—
verifiedCountinteger (int32)no—

ExpiringVerificationRow

PropertyTypeRequiredDescription
checkTypestring | nullno—
daysToExpiryinteger (int32)no—
lastReminderSentAtstring (date-time) | nullno—
recheckRequestedAtstring (date-time) | nullno—
statusstring | nullno—
subjectReferencestring | nullno—
validFromstring (date-time)no—
validUntilstring (date-time)no—
verificationIdstring (uuid)no—

ExpiringVerificationsCohortResult

PropertyTypeRequiredDescription
expiredCountinteger (int32)no—
organizationIdstring (uuid)no—
recheckRequestedCountinteger (int32)no—
rowsExpiringVerificationRow[] | nullno—
totalCountinteger (int32)no—
windowDaysinteger (int32)no—

ExtendProofChallengeRequest

Extension request.

PropertyTypeRequiredDescription
byDaysnumber (double)noHow many more days to allow. Bounded by the aggregate.

FieldAttestationResult

PropertyTypeRequiredDescription
assurancestring | nullno—
attestationIdstring (uuid)no—
fieldKeystring | nullno—
statusstring | nullno—

FreezeBySignedLinkRequest

Request body for the signed-link emergency freeze — the four fields carried by an FR-66.114 freeze deep link (`?account=&session=&exp=&sig=`).

PropertyTypeRequiredDescription
accountIdstring (uuid)noAccount the link authorises a freeze on.
expiresAtUnixinteger (int64)noLink expiry, seconds since the Unix epoch.
recoverySessionIdstring | nullnoThe in-flight recovery attempt the link names.
signaturestring | nullnoLower-case hex HMAC-SHA256 digest minted by EPIC 66.

FreezeBySignedLinkResponse

Response for a signed-link freeze. Every field exists so the landing page can state what it actually stopped rather than a generic success — the reader is deciding whether they still need to ring support tonight.

PropertyTypeRequiredDescription
alreadyFrozenbooleannoWhether the freeze was already in force before this call.
frozenAtstring (date-time) | nullnoUTC instant the freeze is in force from.
recoveryDiscardedbooleannoWhether an in-flight recovery attempt was actually discarded. False when the named attempt had already finished, or is owned by a bounded context Auth cannot halt — never rounded up.
sessionsTerminatedinteger (int32)noActive sessions terminated by the freeze.

GrantApprovalDecisionRequest

Request body for an owner's decision, matching the org-portal's `GrantApprovalDecision`. Deliberately carries NO approver identity — that is resolved from the caller's JWT.

PropertyTypeRequiredDescription
decisionstring | nullno—
reasonstring | nullno—

GrantDelegateAccessRequest

Wire body for granting delegate access.

PropertyTypeRequiredDescription
authorityBasisstring | nullno—
capabilitiesstring[] | nullno—
delegateUserIdstring (uuid)no—
delegationIdstring (uuid)no—
expiresAtstring (date-time) | nullno—
partnerAppIdstring (uuid) | nullnoPartner support impersonation only (`authorityBasis=support-impersonation`): the EPIC 25 partner application the acting agent belongs to. Required for that basis so the dual-identity audit can name the partner, not only the person.
principalUserIdstring (uuid) | nullnoOptional explicit principal. Defaults to the caller; any other value is refused (403).
reasonCodestring | nullnoPartner support impersonation only: the governed reason code from the partner's configured set (an operational token, never free prose).
surfacestring | nullno—
ticketReferencestring | nullnoPartner support impersonation only: the partner's own ticket reference, exactly as shown to the subject on the consent screen.

GrantProbateRoleRequest

Wire body for the EPIC 15 → EPIC 9 probate-role grant call.

PropertyTypeRequiredDescription
attorneyUserIdstring (uuid)no—
estateIdstring (uuid) | nullno—
expiresAtstring (date-time) | nullno—
grantedByUserIdstring (uuid) | nullnoOptional explicit supervising-partner attribution (org-portal direct grants).
grantorUserIdstring (uuid) | nullno—
jurisdictionstring | nullno—
poaIdstring (uuid) | nullno—
poaTypestring | nullno—
scopeProbateRoleScopeRequestno—

GuardianLinkDto

PropertyTypeRequiredDescription
guardianIdstring (uuid)no—
isPrimarybooleanno—
relationshipstring | nullno—
rolestring | nullno—
scopestring | nullno—

GuardianRosterDto

PropertyTypeRequiredDescription
childDisplayNamestring | nullno—
childIdstring | nullno—
guardiansGuardianSeatDto[] | nullno—
guardianshipIdstring | nullno—
statusstring | nullno—

GuardianSeatDto

PropertyTypeRequiredDescription
activatedAtIsostring | nullno—
guardianIdstring | nullno—
isActivebooleanno—
isPrimarybooleanno—
relationshipstring | nullno—
rolestring | nullno—
scopestring | nullno—

GuardianshipCorroborationResult

PropertyTypeRequiredDescription
corroboratedbooleanno—
guardianIdstring (uuid)no—
guardianshipIdstring (uuid) | nullno—
minorSubjectIdstring (uuid)no—

GuardianshipResultDto

PropertyTypeRequiredDescription
childIdstring | nullno—
guardianshipIdstring | nullno—

HandoverConfirmationDto

PropertyTypeRequiredDescription
guardianAccessEndedbooleanno—
revocationDateIsostring | nullno—
revokedGuardianIds(string (uuid))[] | nullno—
statusstring | nullno—
subjectIdstring (uuid)no—
whoHasAccess(string (uuid))[] | nullno—

IdentityAttestation

PropertyTypeRequiredDescription
attestedAtstring (date-time)no—
auditAnchorReferencestring | nullno—
evidenceKindsstring[] | nullno—
levelstring | nullno—
verifierstring | nullno—

IdentityAttestedReprovisionRequest

PropertyTypeRequiredDescription
newPasswordHashstring | nullno—
proofingSessionIdstring (uuid)no—
requestVaultReprovisionbooleanno—
subjectUserIdstring (uuid)no—

IdentityAttestedReprovisionResult

PropertyTypeRequiredDescription
attestationIdentityAttestationno—
recoveryMaterialSurveyedstring | nullno—
reprovisionIdstring (uuid)no—
reprovisionedAtstring (date-time)no—
subjectUserIdstring (uuid)no—
vaultReprovisionRequestedbooleanno—

IdentityChangeRecordDto

PropertyTypeRequiredDescription
changedAtIsostring | nullno—
fromstring | nullno—
guardianshipIdstring (uuid) | nullno—
identityChangeRefstring | nullno—
subjectIdstring (uuid)no—
tostring | nullno—

IndividualRecoveryCancelBody

PropertyTypeRequiredDescription
cancelTokenstring | nullnoThe token from the text message's link.

IndividualRecoveryCancelResponse

PropertyTypeRequiredDescription
cancelledbooleanno—

IndividualRecoveryCompleteBody

PropertyTypeRequiredDescription
completionTokenstring | nullnoThe token the proof step returned.
newPasswordHashstring | nullnoThe CLIENT-DERIVED verifier of the new password; never the password itself.

IndividualRecoveryCompleteResponse

PropertyTypeRequiredDescription
completedbooleannoTrue when the new credential is set.
secondFactorReenrolmentRequiredbooleannoAlways true: every old factor was removed.

IndividualRecoveryProofBody

The two codes: one from the email of record, one from the verified phone.

PropertyTypeRequiredDescription
emailCodestring | nullno—
smsCodestring | nullno—

IndividualRecoveryProofResponse

PropertyTypeRequiredDescription
completeBystring (date-time)noThe latest it can be completed (UTC); after it, start again.
completionTokenstring | nullnoShown once. Keep it: it is the only way to finish this recovery.
holdEndsAtstring (date-time)noThe earliest the recovery can be completed (UTC).

InitiateOAuthLinkRequest

Request model for starting a link flow (`{provider}/link/authorize`). Carries no user id: the account to link is the signed-in caller, read from the bearer token.

PropertyTypeRequiredDescription
redirectUristring | nullnoRedirect URI where the OAuth provider will send the authorization code. Must match exactly with the URI registered with the provider.
scopesstring[] | nullnoOptional scopes to request. If not provided, default scopes will be used.

InitiateOAuthRequest

Request model for initiating OAuth flow.

PropertyTypeRequiredDescription
deviceFingerprintstring | nullnoOptional device fingerprint for device tracking.
homeRegionstring | nullnoOptional sovereign home region chosen on the sign-up surface (ISO 3166-1 alpha-2, e.g. "GB"/"DE"/"AE"; FR-44.040, D-123). Stored in the OAuth state and applied when the callback creates a NEW account, so the account and its default vault are provisioned in the chosen region. "GLOBAL" and blank are not valid regions and fall back to the sovereign default (counted as an onboarding fault).
redirectUristring | nullnoRedirect URI where the OAuth provider will send the authorization code. Must match exactly with the URI registered with the provider.
scopesstring[] | nullnoOptional scopes to request. If not provided, default scopes will be used.

InitiateOAuthResult

PropertyTypeRequiredDescription
authorizationUrlstring | nullno—
codeVerifierstring | nullno—
expiresAtstring (date-time)no—
statestring | nullno—

InitiateProbateStepUpRequest

Request body for initiating a probate step-up. `authorityBasis` and `factor` carry the contract's kebab-case wire values (`court-grant` | `probate-role`; `email` | `sms` | `webauthn` | `phone-call` | `postal-code`) — see Essence.Identity.Auth.Api.Controllers.SendProbateStepUpChallengeRequest for why they are strings.

PropertyTypeRequiredDescription
authorityBasisstring | nullno—
estateIdstring (uuid)no—
factorstring | nullno—
factorProofstring | nullno—
grantDocumentIdstring | nullno—
grantReferencestring | nullno—

InitiateProofingRequest

Body for initiating a proofing session (capability (c)).

PropertyTypeRequiredDescription
providerstring | nullnoThe proofing provider to route to (defaults to `self-serve`).
relyingServiceIdstring | nullnoThe relying service / gated action this run is for (e.g. `loan-drawdown`) — the key the governing org's assurance-threshold policy is resolved by (debt-2026-08-13-211).
requiredLevelstring | nullnoThe level the requesting action says it needs (`loa1`|`loa2`|`loa3`). Advisory only: the org policy resolved server-side may raise it, and a caller can never lower what its organisation demands.

InitiateSafeRecoveryRequestBody

Request body for initiating safe recovery.

PropertyTypeRequiredDescription
reasonstring | nullnoOptional short, non-PII reason.

InitiateSafeRecoveryResult

PropertyTypeRequiredDescription
claimIdstring (uuid)no—
initiatedAtIsostring | nullno—
statusstring | nullno—

InitiateStepUpRequest

Request body for initiating a generic step-up. `action` and `factor` carry the contract's kebab-case wire values (`recovery-initiate` | `password-change` | `verification-renewal`; `totp` | `sms` | `email` | `webauthn`).

PropertyTypeRequiredDescription
actionstring | nullno—
factorstring | nullno—
factorProofstring | nullno—
passwordHashstring | nullnoThe client-derived password hash, REQUIRED for actions that need password re-verification in addition to a second factor — today `account-closure` (FR-15.008.7, debt-2026-08-19-008). Zero-knowledge: the same client-side hash the login and change-password contracts carry. The plaintext password never reaches the server; the comparison is constant-time in the domain. Omit for every action a second factor alone elevates.
reactivationCorrelationIdstring | nullnoOptional correlation id from the flow requesting the elevation (e.g. the dormant-account reactivation). Echoed onto the emitted `SessionElevatedIntegrationEvent` for cross-service audit correlation (debt-2026-07-08-107). Ignored for non-correlated actions.
resourceBindingstring | nullnoOptional opaque reference to the single resource the elevation is for — e.g. the contact card id being re-attested with `action=connection-trust-action` (debt-2026-08-13-009). Stamped onto the token's `rsc` claim so a consumer can refuse an elevation taken for a different resource. Omit for account-wide elevations.

InitiateStepUpResponse

Wire form of Essence.Identity.Auth.Application.Commands.StepUp.InitiateStepUpResult (#10652).

PropertyTypeRequiredDescription
assertionStepUpAssertionResponseno—
expiresAtstring (date-time)no—
maxExpiresAtstring (date-time)no—
sessionIdstring | nullno—
stepUpTokenstring | nullno—
warnAtstring (date-time)no—

InvitationDetailDto

PropertyTypeRequiredDescription
departmentstring | nullno—
emailstring | nullno—
emailMaskedstring | nullno—
expiresAtstring (date-time)no—
homeRegionstring | nullno—
invitationIdstring (uuid)no—
invitedByDisplayNamestring | nullno—
onboardingInvitationOnboardingDtono—
organizationIdstring (uuid)no—
organizationNamestring | nullno—
rolesInvitationRoleDto[] | nullno—
sponsoredPremiumInvitationSponsoredPremiumDtono—
statusstring | nullno—
vaultScopeInvitationVaultScopeDtono—

InvitationOnboardingDto

PropertyTypeRequiredDescription
requiresMfabooleanno—
requiresPhoneVerificationbooleanno—
requiresRecoverybooleanno—

InvitationRoleDto

PropertyTypeRequiredDescription
descriptionstring | nullno—
namestring | nullno—
roleIdstring (uuid)no—

InvitationSponsoredPremiumDto

PropertyTypeRequiredDescription
entitlementLabelstring | nullno—
planLabelstring | nullno—
sponsorNamestring | nullno—

InvitationVaultScopeDto

PropertyTypeRequiredDescription
accessstring | nullno—
descriptionstring | nullno—
vaultLabelstring | nullno—

InviteOrganizationMemberRequest

Request body for inviting an organisation member. Carries the invitee and nothing else: the organisation is in the route, the inviter is in the token, and no role may be pre-assigned.

PropertyTypeRequiredDescription
inviteeEmailstring | nullnoThe person being invited.

InviteOrganizationMemberResult

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
invitationIdstring (uuid)no—

IssueMajorityTransitionRekeyTokenResult

PropertyTypeRequiredDescription
claimIdstring (uuid)no—
expiresAtIsostring | nullno—
purposestring | nullno—
tokenstring | nullno—

IssueOutOfBandProofChallengeResult

PropertyTypeRequiredDescription
challengeIdstring (uuid)no—
channelOutOfBandProofChannelno—
deliveredbooleanno—
deliveryHintstring | nullno—
expiresAtstring (date-time)no—
expiryConsequencestring | nullno—
extensionsRemaininginteger (int32)no—
reusedbooleanno—

IssueProofChallengeRequest

Issuance request. Carries NO destination — see the controller remarks.

PropertyTypeRequiredDescription
caseRefstring | nullnoOpaque correlation handle for the requesting case.
channelOutOfBandProofChannelno—
expiryConsequencestring | nullnoREQUIRED. What the holder is told happens if the window lapses.
purposestring | nullnoBounded slug describing why, e.g. `merge-adjudication`.
subjectAccountIdstring (uuid)noThe account whose control is being tested.
windowDaysnumber (double) | nullnoOptional override of the default (7-day) window, in days.

IssueScopedAdminGrantRequest

Request body for issuing a scoped-admin grant, matching the org-portal's `IssueScopedAdminGrantRequest`. Deliberately carries NO issuer identity — that is resolved from the caller's JWT.

PropertyTypeRequiredDescription
approvalPolicystring | nullnoKebab-case: `none` | `single-owner` | `dual-owner`.
delegateNamestring | nullnoDisplay name shown on the co-sign card.
delegateRefstring | nullnoPseudonymous reference of the staff member receiving the authority.
expiresAtstring (date-time) | nullnoOptional UTC expiry; null issues an open-ended grant.
justificationstring | nullnoThe owner's business rationale (recorded to audit).
roleNamestring | nullnoThe scoped-role display name being granted.
scopeActionsstring[] | nullnoAction verbs the grant confers.
scopeModulesstring[] | nullnoBusiness modules the grant reaches.

IssueSmartLaunchContextRequest

Wire body for minting a launch context.

PropertyTypeRequiredDescription
clientIdstring | nullnoThe SMART app being launched.
encounterRefstring | nullnoOpaque vendor encounter reference, when in context.
issstring | nullnoThe launching EHR's FHIR base URL.
lifetimeSecondsinteger (int32) | nullnoRequested lifetime in seconds (30–900).
offeredScopesstring[] | nullnoExplicit scope array; takes precedence over Essence.Identity.Auth.Api.Controllers.IssueSmartLaunchContextRequest.Scope.
patientRefstring | nullnoOpaque vendor patient reference.
scopestring | nullnoSpace-delimited scopes the EHR authorises for this launch.

IssueSmartLaunchContextResult

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
launchContextIdstring (uuid)no—
launchTokenstring | nullno—

JsonWebKey

JSON Web Key structure (JWK).

PropertyTypeRequiredDescription
algstring | nullnoAlgorithm (RS256).
estring | nullnoRSA public exponent (base64url encoded).
kidstring | nullnoKey ID.
ktystring | nullnoKey type (RSA).
nstring | nullnoRSA modulus (base64url encoded).
usestring | nullnoPublic key use (sig = signature).

JwksDocument

JSON Web Key Set document structure (RFC 7517 §5).

PropertyTypeRequiredDescription
keysJsonWebKey[] | nullno—

LoginCommand

PropertyTypeRequiredDescription
deviceFingerprintstring | nullno—
deviceTypestring | nullno—
emailstring | nullno—
ipAddressstring | nullno—
passwordHashstring | nullno—
preferEmailStepUpbooleanno—
rememberDevicebooleanno—
userAgentstring | nullno—

LoginMethodDto

A single presented login method, in presentation order.

PropertyTypeRequiredDescription
availablebooleannoWhether a sign-in can be completed through this method right now. A method used to have one state — whether it appeared at all — so a region whose national IdP is <b>registered but not switched on here</b> answered byte-identically to a region that has <b>no national IdP</b>, and a US resident was shown a screen that said, in effect, that no federal way into Essence exists (#12291). Those are opposite facts. A named entry with `available: false` is the first one; no entry at all is still the second. An `available: false` method must NOT be rendered as a clickable control — that is the whole of #6945, which this does not relax: a national-IdP button carrying a placeholder `client_id` hands the person to the real IdP, which refuses on its own unbranded page with no route back. It is rendered named, disabled and explained. `true` for every method the policy has always presented, so a client that does not read this field sees exactly the list it saw before.
displayNamestring | nullno—
idstring | nullno—
kindstring | nullno—
providerstring | nullno—
unavailableReasonstring | nullnoWhy the method is unavailable — `"not-configured"` (the provider is registered for this region but this instance holds no usable credential for it, the presentation twin of the authorize route's 501 `federated-provider-not-configured`). Null when Essence.Identity.Auth.Api.Controllers.LoginMethodDto.Available is true.

LoginMethodsResponse

Response for `GET /login-methods` — the ordered presentation list.

PropertyTypeRequiredDescription
methodsLoginMethodDto[] | nullno—
nationalIdpstring | nullnoWhat can be said about the region's national sign-in (EPIC 9 FR-09.060): `available` | `not-configured` | `none-in-region` | `region-not-stated`. `none-in-region` means the platform has no national-IdP connector for the region, which the sign-in screen says in words — before this field that region answered with nothing, the same blank a failed load would leave.
regionstring | nullno—
socialProvidersstring[] | nullnoThe consumer social providers this instance offers at SIGN-UP (FR-44.005) — provider slugs (`Google` / `Apple` / `Microsoft`) the provider picker may present. <b>Always stated, never null.</b> An EMPTY array means this instance offers no consumer social provider — either because the operator disabled them or because none holds a usable credential — and the picker renders that as a real state. It used to carry the operator's raw allow-list, whose `null` ("no restriction configured") the picker read as "offer every provider", so a silent instance advertised three providers it could not serve (#6527). The same resolved set drives the !:LoginMethodKind.Social entries in Essence.Identity.Auth.Api.Controllers.LoginMethodsResponse.Methods, which is the SIGN-IN presentation of the same providers — so the promise onboarding makes ("your provider can sign you back in") cannot come apart from what the sign-in surface offers.

LoginResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
approvalRequiredbooleanno—
approvalTokenstring | nullno—
deviceLimitDeviceLimitPauseno—
deviceLimitReachedbooleanno—
dormancyDormancyInfono—
emailstring | nullno—
emailVerifiedbooleanno—
firstNamestring | nullno—
lastNamestring | nullno—
mfaChallengeTokenstring | nullno—
mfaCodeDeliveredboolean | nullno—
mfaCodeDeliveryStatusstring | nullno—
mfaCodeRetryAfterSecondsinteger (int32) | nullno—
mfaMethodstring | nullno—
mfaRequiredbooleanno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
stepUpMethodstring | nullno—
stepUpReasonstring | nullno—
userIdstring (uuid)no—

LogoutCommand

PropertyTypeRequiredDescription
refreshTokenstring | nullno—
revokeAllSessionsbooleanno—

LogoutResult

PropertyTypeRequiredDescription
sessionsRevokedinteger (int32)no—
successbooleanno—

MediumEnrolmentOptionsDto

PropertyTypeRequiredDescription
enrolledRoutesinteger (int32)no—
minimumRoutesinteger (int32)no—
requiredLevelstring | nullno—
routesMediumEnrolmentRouteDto[] | nullno—

MediumEnrolmentRouteDto

PropertyTypeRequiredDescription
enrolledbooleanno—
levelstring | nullno—
methodstring | nullno—
notOfferedReasonstring | nullno—
offeredbooleanno—
prerequisitestring | nullno—
setUpEndpointstring | nullno—

MemberInvitationTokenRequest

Request body for the two authenticated invitation actions. Carries the token and nothing else: the account, the device and the session all come from the caller's JWT, so there is no field here by which a caller could name somebody other than themselves.

PropertyTypeRequiredDescription
tokenstring | nullnoThe opaque token from the invitation link.

MergePolicyDecisionInput

PropertyTypeRequiredDescription
acknowledgedDisclosurebooleanno—
decidedAtstring (date-time) | nullno—
orgNamestring | nullno—
overriddenbooleanno—
reasonstring | nullno—
templateInForcestring | nullno—

MergeStageProgressDto

PropertyTypeRequiredDescription
stagestring | nullno—
statestring | nullno—

MergeStepUpDto

A step-up factor + proof value supplied with the destructive merge confirm.

PropertyTypeRequiredDescription
factorstring | nullnoThe step-up factor name (Totp | Sms | Email | WebAuthn), case-insensitive.
valuestring | nullnoThe proof value: an OTP code, or a WebAuthn assertion JSON payload.

MfaMethod

0 | 1 | 2 | 3 | 4 | 5 with no declared properties.

MfaStatusDto

PropertyTypeRequiredDescription
backupCodesIssuedinteger (int32)no—
backupCodesRemaininginteger (int32)no—
emailEnabledbooleanno—
smsEnabledbooleanno—
totpEnabledbooleanno—

NameBearingCredentialInput

PropertyTypeRequiredDescription
credentialClassstring | nullno—
credentialIdstring (uuid)no—
labelstring | nullno—

NameChangeHistoryExport

PropertyTypeRequiredDescription
accountIdstring (uuid)no—
auditAnchorRefstring | nullno—
auditRecordIdstring (uuid)no—
committedAtstring (date-time)no—
exportedAtstring (date-time)no—
formatstring | nullno—
newNameHashstring | nullno—
notifiedCountinteger (int32)no—
previousNameDispositionstring | nullno—
previousNameHashstring | nullno—
reattestedAtstring (date-time)no—
recordTypestring | nullno—
withheldCountinteger (int32)no—

NewDeviceFreezeLinkRequest

The two values the alert's link carries.

PropertyTypeRequiredDescription
alertIdstring (uuid)noThe alert (new-device event) id.
tokenstring | nullnoThe link's single-use token.

NewDeviceFreezeLinkResponse

A live link was used: the account is frozen.

PropertyTypeRequiredDescription
frozenbooleanno—

NonCustodyAttestationDto

PropertyTypeRequiredDescription
actionCountinteger (int32)no—
asOfstring (date-time)no—
assistantUserIdstring (uuid)no—
assistedUserIdstring (uuid)no—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid)no—
keyMaterialAccessedbooleanno—
nonCustodyAttestedbooleanno—
sessionIdstring (uuid)no—
statementstring | nullno—
statusstring | nullno—

OAuthCallbackRequest

Request model for OAuth callback. Carries no link target: whether a callback links, and to whom, is decided by the one-time state (see `{provider}/link/authorize`), never the body.

PropertyTypeRequiredDescription
authorizationCodestring | nullnoAuthorization code received from the OAuth provider.
codeVerifierstring | nullnoPKCE code verifier generated during authorization initiation.
deviceFingerprintstring | nullnoOptional device fingerprint for device creation/tracking.
homeRegionstring | nullnoFallback sovereign home region for a NEW account (ISO 3166-1 alpha-2; FR-44.040, D-123). The region carried in the OAuth state (chosen before redirect) wins; this is used only when the state carries none. Ignored when the identity resolves to an existing or linked account.
redirectUristring | nullnoRedirect URI used in the authorization request. Must match exactly for security.
statestring | nullnoState parameter for CSRF protection.

OAuthCallbackResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
accountLinkedbooleanno—
deviceLimitDeviceLimitPauseno—
deviceLimitReachedbooleanno—
emailstring | nullno—
emailVerifiedbooleanno—
grantedScopesstring[] | nullno—
homeRegionstring | nullno—
isNewUserbooleanno—
isRelayEmailbooleanno—
mfaChallengeTokenstring | nullno—
mfaCodeDeliveredboolean | nullno—
mfaCodeDeliveryStatusstring | nullno—
mfaCodeRetryAfterSecondsinteger (int32) | nullno—
mfaMethodstring | nullno—
mfaRequiredbooleanno—
namestring | nullno—
providerstring | nullno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
userIdstring (uuid)no—

OAuthLinkResult

Response model for OAuth provider linking.

PropertyTypeRequiredDescription
messagestring | nullnoSuccess or error message.
providerstring | nullnoIdentity provider that was linked.
successbooleannoWhether the linking was successful.

OpenBiometricReenrolmentRequest

Body for opening a re-enrolment session (all optional — the subject is from the token).

PropertyTypeRequiredDescription
lockoutStatestring | nullno—
memberReferencestring | nullno—
mismatchReasonstring | nullno—

OpenIdConfiguration

OpenID Connect discovery document (OIDC Discovery 1.0 §3 / RFC 8414 §2).

PropertyTypeRequiredDescription
authorization_endpointstring | nullno—
claims_supportedstring[] | nullno—
id_token_signing_alg_values_supportedstring[] | nullno—
issuerstring | nullno—
jwks_uristring | nullno—
response_types_supportedstring[] | nullno—
scopes_supportedstring[] | nullno—
subject_types_supportedstring[] | nullno—
token_endpointstring | nullno—
token_endpoint_auth_methods_supportedstring[] | nullno—
userinfo_endpointstring | nullno—

OperatingJurisdictionEndedResponse

A declaration that was ended early.

PropertyTypeRequiredDescription
endedAtstring (date-time)noWhen it was ended (UTC).
jurisdictionstring | nullnoThe jurisdiction that had been in force.

OperatingJurisdictionResponse

The declaration as recorded on the session.

PropertyTypeRequiredDescription
corroboratedbooleannoWhether the request located to the same jurisdiction.
declaredAtstring (date-time)noWhen it was recorded (UTC).
expiresAtstring (date-time)noWhen the session's tokens stop carrying it (UTC). Declare again to continue.
jurisdictionstring | nullnoThe normalised code.

OperationalRoleCatalogueEntryDto

One grantable role as shown on the administration screen.

PropertyTypeRequiredDescription
capabilitystring | nullnoThe operational capability it belongs to.
descriptionstring | nullnoWhat holding it lets the person do.
displayNamestring | nullnoHuman label.
issuedThroughOrgPortalbooleannoThe role is granted in the organisation portal's Members screen (Module roles), and a grant here is refused with `issued-through-org-portal`. Carried on the catalogue so the administration screen can send the administrator there instead of offering a grant that is certain to be refused (#6191).
rolestring | nullnoThe canonical kebab-case claim value.

OrganisationDelegateAccessPairDto

PropertyTypeRequiredDescription
capabilitiesstring[] | nullno—
delegateLabelstring | nullno—
delegateUserIdstring (uuid)no—
delegationIdstring (uuid)no—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid)no—
grantedAtstring (date-time)no—
lastActivityAtstring (date-time) | nullno—
principalLabelstring | nullno—
principalUserIdstring (uuid)no—
revokedAtstring (date-time) | nullno—
statusDelegateAccessStatusno—
surfacestring | nullno—

OrganisationDelegateAccessPairDtoCursorResult

PropertyTypeRequiredDescription
hasMorebooleanno—
itemsOrganisationDelegateAccessPairDto[] | nullno—
nextCursorstring | nullno—
pageSizeinteger (int32)no—
previousCursorstring | nullno—

OrganisationNotificationAudienceDto

PropertyTypeRequiredDescription
organisationRegionstring | nullno—
organizationIdstring (uuid)no—
recipientIds(string (uuid))[] | nullno—
truncatedbooleanno—

OrgIdpRecordDto

Wire shape matching `orgSsoResolution.ts::OrgIdpRecord` (camel-cased by the serializer).

PropertyTypeRequiredDescription
displayNamestring | nullno—
domainstring | nullno—
enterpriseEntitlementbooleanno—
organizationIdstring | nullno—
protocolstring | nullno—
providerstring | nullno—
ssoOnlybooleanno—

OrgIdpResolveResponse

Response for `GET /org-idp/resolve`. `Org` is null when not federated.

PropertyTypeRequiredDescription
orgOrgIdpRecordDtono—

OrgMembershipStandingDto

PropertyTypeRequiredDescription
activeMemberbooleanno—
administersbooleanno—
organizationIdstring (uuid)no—
userIdstring (uuid)no—

OrgOperationalRoleHolder

PropertyTypeRequiredDescription
rolesstring[] | nullno—
userIdstring (uuid)no—

OrgOperationalRoleHoldersResult

PropertyTypeRequiredDescription
holdersOrgOperationalRoleHolder[] | nullno—
membersScannedinteger (int32)no—
truncatedbooleanno—

OrgSsoCoverageDto

PropertyTypeRequiredDescription
coveredDomainCountinteger (int32)no—
memberCountinteger (int32) | nullno—
organizationIdstring (uuid)no—
resolvedbooleanno—

OutcomeRequest

Body for resolving a session terminally.

PropertyTypeRequiredDescription
outcomestring | nullno—

OutOfBandProofChallengeStatus

0 | 1 | 2 | 3 | 4 with no declared properties.

OutOfBandProofChallengeView

PropertyTypeRequiredDescription
answeredAtstring (date-time) | nullno—
canExtendbooleanno—
caseRefstring | nullno—
challengeIdstring (uuid)no—
channelOutOfBandProofChannelno—
expiresAtstring (date-time)no—
expiryConsequencestring | nullno—
extensionsGrantedinteger (int32)no—
extensionsRemaininginteger (int32)no—
issuedAtstring (date-time)no—
outcomeOutOfBandProofOutcomeno—
purposestring | nullno—
resolvedAtstring (date-time) | nullno—
statusOutOfBandProofChallengeStatusno—
subjectAccountIdstring (uuid)no—

OutOfBandProofChannel

0 | 1 with no declared properties.

OutOfBandProofOutcome

0 | 1 | 2 | 3 | 4 with no declared properties.

PartnerSupportSessionDto

PropertyTypeRequiredDescription
agentDisplayNamestring | nullno—
agentIdstring (uuid)no—
applicationIdstring (uuid)no—
consentIdstring (uuid)no—
endedAtstring (date-time) | nullno—
expiresAtstring (date-time) | nullno—
reasonCodestring | nullno—
scopesstring[] | nullno—
sessionIdstring (uuid)no—
startedAtstring (date-time)no—
statusstring | nullno—
subjectUserReferencestring | nullno—
terminationReasonstring | nullno—
ticketReferencestring | nullno—

PasswordBreachRangeEntryDto

One suffix of the range.

PropertyTypeRequiredDescription
countinteger (int32)noHow often it occurs in the corpus; 0 marks padding.
suffixstring | nullnoThe remaining 35 upper-case hex characters of a SHA-1 in the corpus.

PasswordBreachRangeRequest

The request body: the prefix, and nothing else.

PropertyTypeRequiredDescription
prefixstring | nullnoThe first 5 upper-case hex characters of SHA-1(password).

PasswordBreachRangeResponse

The range for one prefix, padding included (wire names fixed regardless of host JSON options).

PropertyTypeRequiredDescription
suffixesPasswordBreachRangeEntryDto[] | nullnoEvery suffix sharing the prefix.

PasswordlessLoginChallengeRequest

PropertyTypeRequiredDescription
userVerificationstring | nullnoOptional override for user verification. Defaults to `required` on the command side — overriding down to `preferred` is tolerated but not encouraged.

PasswordlessLoginChallengeResult

PropertyTypeRequiredDescription
challengestring | nullno—
rpIdstring | nullno—
sessionIdstring | nullno—
timeoutinteger (int32)no—
userVerificationstring | nullno—

PasswordlessLoginRequest

PropertyTypeRequiredDescription
authenticatorDatastring | nullno—
clientDataJsonstring | nullno—
credentialIdstring | nullno—
sessionIdstring | nullno—
signaturestring | nullno—
userHandlestring | nullnoBase64url-encoded userHandle returned by the authenticator.

PasswordlessLoginResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
deviceLimitDeviceLimitPauseno—
deviceLimitReachedbooleanno—
errorMessagestring | nullno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
successbooleanno—
userIdstring (uuid)no—

PendingCustodialOrderItem

PropertyTypeRequiredDescription
documentNamestring | nullno—
effectiveDateIsostring | nullno—
evidenceCodesstring[] | nullno—
hasDocumentbooleanno—
instrumentCodestring | nullno—
instrumentLabelstring | nullno—
issuingAuthoritystring | nullno—
jurisdictionCodestring | nullno—
orderIdstring | nullno—
orderReferencestring | nullno—
requiredAuthoriserstring | nullno—
submittedAtIsostring | nullno—

PendingCustodialOrderItemCursorResult

PropertyTypeRequiredDescription
hasMorebooleanno—
itemsPendingCustodialOrderItem[] | nullno—
nextCursorstring | nullno—
pageSizeinteger (int32)no—
previousCursorstring | nullno—

PendingDeviceApprovalDto

PropertyTypeRequiredDescription
comparisonCodestring | nullno—
expiresAtstring (date-time)no—
idstring (uuid)no—
newDeviceIdstring (uuid)no—
requestedAtstring (date-time)no—
requesterIpstring | nullno—
requesterUserAgentstring | nullno—

PendingSupportAccessRequestDto

PropertyTypeRequiredDescription
agentDisplayNamestring | nullno—
agentPrincipalIdstring (uuid)no—
consentIdstring (uuid)no—
expiresAtstring (date-time)no—
partnerAppIdstring (uuid)no—
partnerApprovedbooleanno—
partnerNamestring | nullno—
partnerNameStatusstring | nullno—
publisherNamestring | nullno—
publisherVerifiedboolean | nullno—
reasonCodestring | nullno—
requestIdstring (uuid)no—
requestedAtstring (date-time)no—
requestedDurationMinutesinteger (int32)no—
requestedScopesstring[] | nullno—
ticketReferencestring | nullno—

PhoneVerificationConfirmedResponse

The number is verified.

PropertyTypeRequiredDescription
verifiedbooleanno—

PhoneVerificationSentResponse

The masked number the code went to, and when it expires.

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
maskedNumberstring | nullno—

PollDeviceApprovalResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time) | nullno—
comparisonCodestring | nullno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time) | nullno—
statusstring | nullno—

PreAssignedRoleInput

PropertyTypeRequiredDescription
descriptionstring | nullno—
namestring | nullno—
roleIdstring (uuid)no—

PreferredLocaleResult

PropertyTypeRequiredDescription
changedbooleanno—
preferredLocalestring | nullno—
reserveAuditRefstring | nullno—
supportedLocalesstring[] | nullno—

PrimaryContactCascadeEntry

PropertyTypeRequiredDescription
affectedRefCountinteger (int32)no—
consumerstring | nullno—
epicinteger (int32)no—
statusstring | nullno—

PrimaryContactCascadeView

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
committedAtstring (date-time) | nullno—
consumersPrimaryContactCascadeEntry[] | nullno—
statusstring | nullno—

PrimaryContactChangeView

PropertyTypeRequiredDescription
accountIdstring (uuid)no—
cancelledAtstring (date-time) | nullno—
changeIdstring (uuid)no—
channelstring | nullno—
committedAtstring (date-time) | nullno—
factorsRevalidatedAtstring (date-time) | nullno—
newContactMaskedstring | nullno—
previousContactMaskedstring | nullno—
recoveryFactorStatesstring[] | nullno—
resendCountinteger (int32)no—
reverifiedAtstring (date-time) | nullno—
statusstring | nullno—
trustWindowClosesAtstring (date-time) | nullno—
trustWindowOpenedAtstring (date-time) | nullno—
trustedContactOfRecordMaskedstring | nullno—

PrincipalValidationDto

PropertyTypeRequiredDescription
existsbooleanno—
homeRegionstring | nullno—
isActivebooleanno—
userIdstring (uuid)no—

ProbateAssuranceResult

PropertyTypeRequiredDescription
achievedAalstring | nullno—
authorityBasisstring | nullno—
requiredstring | nullno—
shortfallstring | nullno—

ProbateRoleGrantDto

PropertyTypeRequiredDescription
attorneyUserIdstring (uuid)no—
estateIdstring (uuid) | nullno—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid)no—
jurisdictionstring | nullno—
poaIdstring (uuid) | nullno—
poaTypestring | nullno—
revokedAtstring (date-time) | nullno—
scopeCategoryCountinteger (int32)no—
scopeDocumentCountinteger (int32)no—
scopeFieldCountinteger (int32)no—
statusProbateRoleStatusno—

ProbateRoleGrantResponse

Response body for the grant call.

PropertyTypeRequiredDescription
grantIdstring (uuid)no—

ProbateRoleScopeRequest

Scope counts the grant is bounded to.

PropertyTypeRequiredDescription
categoryCountinteger (int32)no—
documentCountinteger (int32)no—
fieldCountinteger (int32)no—

ProbateRoleStatus

0 | 1 | 2 with no declared properties.

ProbateStepUpChallengeResponse

Wire response for a probate step-up challenge. Exists so `factor` leaves as the published `phone-call`-style string rather than the enum's ordinal — the outbound half of #8134.

PropertyTypeRequiredDescription
deliveryHintstring | nullno—
expiresAtstring (date-time)no—
factorstring | nullno—
sentbooleanno—
webAuthnChallengestring | nullno—
webAuthnSessionIdstring | nullno—

ProbateStepUpResponse

Wire response for a successful probate step-up. `authorityBasis` leaves as `court-grant` | `probate-role` — the same vocabulary the token's `authority_basis` claim and the assurance endpoint already publish, rather than the enum's ordinal (#8134).

PropertyTypeRequiredDescription
achievedAalstring | nullno—
authorityBasisstring | nullno—
estateIdstring (uuid)no—
expiresAtstring (date-time)no—
maxExpiresAtstring (date-time)no—
stepUpTokenstring | nullno—
warnAtstring (date-time)no—

ProblemDetails

PropertyTypeRequiredDescription
detailstring | nullno—
instancestring | nullno—
statusinteger (int32) | nullno—
titlestring | nullno—
typestring | nullno—

ProfessionalAdviserAuthorisationResult

PropertyTypeRequiredDescription
adviserUserIdstring (uuid)no—
agencyCapabilitiesstring[] | nullno—
agencyIdstring (uuid) | nullno—
agencyNamestring | nullno—
authorisedSincestring (date-time) | nullno—
caseReferencestring | nullno—
regulatedBodystring | nullno—
verdictstring | nullno—

ProfessionalAdviserRegisterResult

PropertyTypeRequiredDescription
adviserCapabilitiesstring[] | nullno—
advisersProfessionalAdviserRow[] | nullno—
agencyIdstring (uuid)no—
agencyNamestring | nullno—
agencyStatusstring | nullno—
authorisedCountinteger (int32)no—
organizationIdstring (uuid)no—
totalCountinteger (int32)no—

ProfessionalAdviserRow

PropertyTypeRequiredDescription
adviserReferencestring | nullno—
adviserUserIdstring (uuid)no—
authorisedbooleanno—
liveCaseCountinteger (int32)no—
registeredAtstring (date-time)no—
regulatedBodystring | nullno—
regulatedReferencestring | nullno—
revocationReasonstring | nullno—
revokedAtstring (date-time) | nullno—
roleIssuedAtstring (date-time) | nullno—
statusstring | nullno—
suspendedAtstring (date-time) | nullno—
suspensionReasonstring | nullno—
verificationLevelstring | nullno—
verifiedAtstring (date-time) | nullno—

ProfessionalAttestationDto

PropertyTypeRequiredDescription
assurancestring | nullno—
bodystring | nullno—
credentialTypestring | nullno—
expiresAtIsostring | nullno—
fieldKeystring | nullno—
signingKeyIdstring | nullno—
statusstring | nullno—

ProfileNameResult

PropertyTypeRequiredDescription
changedbooleanno—
editablebooleanno—
firstNamestring | nullno—
lastNamestring | nullno—

ProofingPolicyResult

PropertyTypeRequiredDescription
authoritystring | nullno—
isDefaultbooleanno—
proofingPolicystring | nullno—
subjectUserIdstring (uuid)no—

ProofingSessionResult

PropertyTypeRequiredDescription
completedAtstring (date-time) | nullno—
expiresAtstring (date-time)no—
failureReasonstring | nullno—
providerstring | nullno—
reachedLevelstring | nullno—
relyingServiceIdstring | nullno—
requiredLevelstring | nullno—
satisfiesRequirementbooleanno—
sessionIdstring (uuid)no—
shortfallReasonstring | nullno—
statusstring | nullno—
subjectUserIdstring (uuid)no—

ProveAccountMergeRequest

Wire body to bind proof-of-control for one account: which account, and a second-factor proof enrolled on it. Matches the delivered client's `bindRetiring` payload.

PropertyTypeRequiredDescription
accountIdstring (uuid) | nullnoWhich account (retiring or surviving) this proof is for. Optional — omit it to prove the session's retiring account, which is what the merge flow's proof step is for.
factorstring | nullnoThe step-up factor name (Totp | Sms | Email | WebAuthn), case-insensitive.
valuestring | nullnoThe proof value: an OTP code, or a WebAuthn assertion JSON payload.

ProveAccountMergeResponse

PropertyTypeRequiredDescription
bothAccountsProvenbooleanno—
mergeSessionIdstring (uuid)no—
statusstring | nullno—

ProvisionChildIdentityRequest

New-legal-identity provisioning body.

PropertyTypeRequiredDescription
authorityReferencestring | nullnoThe order reference the caller believes it is acting under.
caseReferencestring | nullnoThe caller's opaque case reference. One case provisions one identity.
contactEmailstring | nullnoOptional contact address for the new identity. Omit when the child is a minor with no credentials of their own; the principal is then provisioned without a sign-in and credentials are enrolled later.
passwordHashstring | nullnoOptional client-derived password hash, paired with Essence.Identity.Auth.Api.Controllers.ProvisionChildIdentityRequest.ContactEmail.

ProvisionChildIdentityResult

PropertyTypeRequiredDescription
alreadyProvisionedbooleanno—
caseReferencestring | nullno—
credentialsEnrolledbooleanno—
identityRefstring | nullno—
provisionedAtIsostring | nullno—
provisioningIdstring | nullno—

RaiseSupportAccessRequestBody

Request body for raising a support-access request — `ImpersonationRequestDraft` in `partner-dashboard/src/features/support-access/types.ts`.

PropertyTypeRequiredDescription
agentIdstring (uuid)no—
appIdstring (uuid)no—
durationMinutesinteger (int32)no—
reasonCodestring | nullno—
scopesstring[] | nullno—
subjectUserReferencestring | nullno—
ticketReferencestring | nullno—

ReassignAdviserCaseRequest

Request body for handing a case over.

PropertyTypeRequiredDescription
reasonstring | nullnoWhy the case is moving.
successorAdviserUserIdstring (uuid)noThe adviser taking the case on.

ReattestVerifiedNameChangeRequest

Wire body to re-attest the new name.

PropertyTypeRequiredDescription
credentialsNameBearingCredentialInput[] | nullnoOptional: the name-bearing official credentials to reissue under the new name. Carried onto the 9→2 re-attestation event; the cascade is provisioned either way.
reattestationRefstring | nullno—

ReattestVerifiedNameChangeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
reattestedAtstring (date-time)no—
statusstring | nullno—

RecipientContactDto

PropertyTypeRequiredDescription
displayNamestring | nullno—
emailstring | nullno—
existsbooleanno—
phonestring | nullno—
userIdstring (uuid)no—

RecipientLookupRequest

Request body for M:Essence.Identity.Auth.Api.Controllers.RecipientLookupController.Lookup(Essence.Identity.Auth.Api.Controllers.RecipientLookupRequest,System.Threading.CancellationToken).

PropertyTypeRequiredDescription
emailstring | nullnoThe recipient's email address, as the grantor typed it.

RecipientResolutionDto

PropertyTypeRequiredDescription
resolvedbooleanno—
userIdstring (uuid) | nullno—

RecogniseAdviceAgencyRequest

Request body for recognising an advice agency.

PropertyTypeRequiredDescription
adviserCapabilitiesstring[] | nullnoThe agency-level adviser permission ceiling. At least one.
agencyNamestring | nullnoInstitutional name, e.g. "Citizens Advice Cardiff".
organizationIdstring (uuid)noThe organisation the recognition attaches to.
regulatoryBodystring | nullnoThe body under whose permission it advises, e.g. `FCA`.
regulatoryReferencestring | nullnoThe agency's opaque reference with that body.

RecogniseSafeguardingAuthorityRequest

Request body for recognising a safeguarding authority.

PropertyTypeRequiredDescription
authorityNamestring | nullnoInstitutional name, e.g. "Office of the Public Guardian".
organizationIdstring (uuid)noThe organisation being recognised.
statutoryReferencestring | nullnoOptional reference to the instrument granting the office.

ReConsentChoiceDto

PropertyTypeRequiredDescription
choicestring | nullno—
grantIdstring | nullno—

RecordAdviserAccreditationRequest

Request body for recording an adviser's professional accreditation.

PropertyTypeRequiredDescription
regulatedBodystring | nullnoThe adviser's regulator, e.g. `IMA` or `FCA`.
regulatedReferencestring | nullnoTheir opaque reference with that body.

RecordAssistActionRequest

Wire body for recording a delegate-attributed assist action.

PropertyTypeRequiredDescription
actionTypestring | nullno—
sessionIdstring (uuid)no—
targetRefstring | nullno—
touchedKeyMaterialbooleanno—

RecordAssistActionResponse

Response body for the action call.

PropertyTypeRequiredDescription
actionIdstring (uuid)no—
sessionIdstring (uuid)no—

RecordAssuranceRequest

Body for recording first-run assurance (capability (a)+(b)).

PropertyTypeRequiredDescription
emailVerifiedbooleannoWhether the account's email is verified (the LOA1 precondition). Defaults true.
invitedByOrgbooleannoWhether the account is onboarding under an org invitation.
orgNamestring | nullnoInviting organisation display name (for the authority label).
proofingCompletedbooleannoRefused when true with 403 `proofing-outcome-not-adjudicated` (#14295): the subject cannot certify its own proofing. Completion is recorded only by a provider-adjudicated proofing session.
proofingPolicystring | nullnoExplicit proofing policy (`required`|`deferred`|`optional`); null → per-actor default.

RecordRecoveryDecisionRequest

Body for recording the first-run recovery decision (debt-2026-07-09-022).

PropertyTypeRequiredDescription
recoverySetUpbooleannoTrue if the holder set up account recovery; false if they deferred it.

RecordTakeoverProgressRequest

Request body for reporting a completed takeover-recovery step (#7393).

PropertyTypeRequiredDescription
countinteger (int32) | nullnoFor `shares-revoked`: how many shares were revoked.
stepstring | nullnoOne of `keys-rotated`, `shares-revoked`, `closed`.

RecordVerificationRequest

Request body for recording an org member verification into the cohort.

PropertyTypeRequiredDescription
checkTypestring | nullno—
subjectReferencestring | nullno—
validFromstring (date-time)no—
validUntilstring (date-time)no—

RecoveryOtpRequestDto

Wire body for `POST /auth/mfa/otp/request`.

PropertyTypeRequiredDescription
actionstring | nullnoThe step-up action discriminator; must be "recovery-initiate".
channelstring | nullnoThe recovery channel: "email" or "sms".

RecoveryOtpRequestResponse

Response for a recovery OTP request — mirrors the client's expected shape.

PropertyTypeRequiredDescription
maskedDestinationstring | nullno—
sentbooleanno—

RecoveryOtpVerifyDto

Wire body for `POST /auth/mfa/otp/verify`.

PropertyTypeRequiredDescription
actionstring | nullnoThe step-up action discriminator; must be "recovery-initiate".
channelstring | nullnoThe recovery channel: "email" or "sms".
codestring | nullnoThe one-time code the user received.

RecoveryOtpVerifyResponse

Response for a recovery OTP verify — mirrors the client's `MfaVerifyResponse`.

PropertyTypeRequiredDescription
expiresAtstring (date-time) | nullnoAbsolute UTC expiry of StepUpToken.
stepUpTokenstring | nullnoThe FR-01.045 `aal=2` / `act=recovery-initiate` elevation token to present as `stepUpToken` on `POST /api/v1/recovery/initiate`. Null when Verified is false (debt-2026-08-24-055 — before this, the surface confirmed the proof and handed back nothing the recovery endpoint could consume).
verifiedbooleannoWhether the delivered code matched.

RecoveryPhraseTokenRequest

Request body for `POST /recovery-phrase/token` — the anonymous recovery entry for a user who has forgotten their password. Essence.Identity.Auth.Api.Controllers.RecoveryPhraseTokenRequest.RecoveryProof is the client-derived recovery proof (hex, ≥ 64 chars) — never the phrase.

PropertyTypeRequiredDescription
emailstring | nullno—
recoveryProofstring | nullno—

RecoveryRewrapTokenResponse

Response for `POST /recovery-phrase/token`: the one-shot, 5-minute `purpose=recovery-rewrap` token and its absolute UTC expiry. Carries no key material.

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
purposestring | nullno—
tokenstring | nullno—

RefreshTokenCommand

PropertyTypeRequiredDescription
deviceFingerprintstring | nullno—
ipAddressstring | nullno—
refreshTokenstring | nullno—

RefreshTokenResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—

RegenerateMfaBackupCodesResult

PropertyTypeRequiredDescription
backupCodesstring[] | nullno—
messagestring | nullno—
successbooleanno—

RegisterDelegatedAgentRequest

Request body for agent registration.

PropertyTypeRequiredDescription
consentGrantIdstring (uuid) | nullnoEPIC 6 grant the agent acts under, when consent-backed.
grantedScopesstring[] | nullnoScope slugs the delegation conveys.
namestring | nullnoName the principal recognises the agent by.
organisationIdstring (uuid) | nullnoGoverning organisation, when there is one.

RegisterDelegatedAgentResponse

Registration response. The secret appears here and nowhere else, ever.

PropertyTypeRequiredDescription
agentIdstring (uuid)noThe aggregate id.
agentReferencestring | nullnoThe opaque cross-service reference.
secretstring | nullnoThe credential secret. Store it now; it cannot be retrieved.

RegisterOrgInvitationCommand

PropertyTypeRequiredDescription
departmentstring | nullno—
expiresAtstring (date-time)no—
homeRegionstring | nullno—
invitationIdstring (uuid)no—
invitedByDisplayNamestring | nullno—
invitedByUserIdstring (uuid)no—
inviteeEmailstring | nullno—
organizationIdstring (uuid)no—
organizationNamestring | nullno—
preAssignedRolesPreAssignedRoleInput[] | nullno—
requireMfabooleanno—
requireRecoverySetupbooleanno—
sponsoredPremiumSponsoredPremiumInputno—
tokenstring | nullno—
vaultScopeVaultScopeInputno—

RegisterOrgInvitationResult

PropertyTypeRequiredDescription
alreadyExistedbooleanno—
invitationIdstring (uuid)no—

RegisterProfessionalAdviserRequest

Request body for registering an adviser.

PropertyTypeRequiredDescription
adviserReferencestring | nullnoOpaque, agency-chosen, non-PII reference (a staff number).
adviserUserIdstring (uuid)noThe adviser's user-principal id.
regulatedBodystring | nullnoThe adviser's own regulator, when known at registration.
regulatedReferencestring | nullnoTheir opaque reference with that regulator.

RegisterTrustedEhrIssuerRequest

Wire body for registering a trusted EHR issuer.

PropertyTypeRequiredDescription
allowedClientIdsstring[] | nullnoSMART app client ids permitted to launch from this issuer.
displayNamestring | nullnoOperator-facing vendor or instance name.
grantableScopesstring[] | nullnoThe ceiling of scopes launches from this issuer may obtain.
issstring | nullnoThe EHR's FHIR base URL.
organizationIdstring (uuid) | nullnoOwning organisation, when org-scoped.

RegisterTrustedEhrIssuerResponse

Response to a trusted-issuer registration.

PropertyTypeRequiredDescription
issuerIdstring (uuid)noIdentifier of the registration.

RegisterUserCommand

PropertyTypeRequiredDescription
breachCheckstring | nullno—
deviceFingerprintstring | nullno—
deviceTypestring | nullno—
emailstring | nullno—
firstNamestring | nullno—
homeRegionstring | nullno—
ipAddressstring | nullno—
lastNamestring | nullno—
passwordHashstring | nullno—
passwordPolicyVersioninteger (int32) | nullno—
phoneNumberstring | nullno—
proofOfWorkSignUpProofOfWorkno—
userAgentstring | nullno—

RegisterUserResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time)no—
emailstring | nullno—
emailVerifiedbooleanno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
userIdstring (uuid)no—
verificationPendingbooleanno—

RegistrationAcceptedResponse

The uniform body of `POST /register` (#7225). There is exactly one value, so a free address and a taken one serialise to the same bytes.

PropertyTypeRequiredDescription
nextstring | nullnoThe step the caller goes to next: always `verify-email`.

RemoveExecutorOfficerRequest

Request body for removing an officer from the roster.

PropertyTypeRequiredDescription
reasonstring | nullnoWhy the officer was removed. Travels with the cascade onto every estate they held, so it is the only explanation a later auditor sees for why those assignments ended.

RenameWebAuthnCredentialRequest

Request body for renaming a passkey.

PropertyTypeRequiredDescription
namestring | nullnoNew user-facing name for the passkey.

RequestAccountMergeApprovalRequestBody

Wire body to enqueue a merge for org approval (EPIC 7 governance seam, debt-2026-07-09-284): names the organisation whose require-approval policy gates it.

PropertyTypeRequiredDescription
organizationIdstring (uuid)noThe organisation whose require-approval policy gates this merge.
policyDecisionMergePolicyDecisionInputno—

RequestAccountMergeApprovalResponse

The result of enqueuing a merge for org approval: the merge session, its lifecycle status, its new approval status (`Pending`), and the approving organisation.

PropertyTypeRequiredDescription
approvalStatusstring | nullno—
mergeSessionIdstring (uuid)no—
organizationIdstring (uuid)no—
statusstring | nullno—

RequestPrimaryContactChangeRequest

Wire body to request a primary-contact change.

PropertyTypeRequiredDescription
affectedConsentRefsstring[] | nullnoOpaque consent-grant references EPIC 6 must re-validate on cutover.
channelstring | nullno`Email` or `Phone`.
currentContactstring | nullnoPlaintext current primary contact — hashed + masked, then discarded.
newContactstring | nullnoPlaintext new primary contact — hashed + masked, then discarded.
syncedConnectionRefsstring[] | nullnoOpaque synced-connection references EPIC 19 must repoint on cutover.

RequestPrimaryContactChangeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
newContactMaskedstring | nullno—
statusstring | nullno—

RequestVerifiedNameChangeRequest

Wire body to open a verified-name-change.

PropertyTypeRequiredDescription
affectedConsentRefsstring[] | nullnoOpaque consent-grant references EPIC 6 evaluates for the recipient split.
deedPollDocumentIdstring (uuid) | nullnoOptional reference to the deed-poll / legal instrument evidencing the change. Echoed on the change record and carried onto the credential-reissue cascade as its evidence.
newNameHashstring | nullnoClient-computed SHA-256 hash (lowercase hex) of the NEW verified name.
newNameMaskedstring | nullnoIrreversible masked display hint of the NEW name (e.g. `J••• S•••`).
previousNameDispositionstring | nullno`KeepAlias`, `Redact` or `FormerlyKnownAs` (default).
previousNameHashstring | nullnoClient-computed SHA-256 hash (lowercase hex) of the OLD verified name.
previousNameMaskedstring | nullnoOptional irreversible masked display hint of the PREVIOUS name (e.g. `J••• H•••`), so a surface can state both halves of the change rather than falling back to literals.
syncedConnectionRefsstring[] | nullnoOpaque synced-connection references EPIC 19 must update on commit.

RequestVerifiedNameChangeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
newNameMaskedstring | nullno—
previousNameMaskedstring | nullno—
statusstring | nullno—

RequiredFactorsResponse

The factors available for step-up for the calling session.

PropertyTypeRequiredDescription
factorsstring[] | nullno—

ResendEmailVerificationOtpByEmailRequest

Request body for `POST /email/resend-otp/by-email` (#7539).

PropertyTypeRequiredDescription
emailstring | nullnoThe address to send a fresh verification code to.

ResendEmailVerificationOtpResult

PropertyTypeRequiredDescription
expiresAtstring (date-time) | nullno—
messagestring | nullno—
sentbooleanno—

ResendKeyClaimCodeResult

PropertyTypeRequiredDescription
challengeIdstring (uuid)no—
claimIdstring (uuid)no—
resendCountinteger (int32)no—

ResendLoginMfaCodeCommand

PropertyTypeRequiredDescription
challengeTokenstring | nullno—

ResendLoginMfaCodeResult

PropertyTypeRequiredDescription
messagestring | nullno—
retryAfterSecondsinteger (int32) | nullno—
sentbooleanno—
statusstring | nullno—

ResendPrimaryContactChallengeRequest

Wire body to resend the challenge (re-supply the new contact).

PropertyTypeRequiredDescription
newContactstring | nullno—

ResendPrimaryContactChallengeResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
resendCountinteger (int32)no—
statusstring | nullno—

ResolveReturningNationalBootstrapRequest

Request body for a business-admin resolution of a held bootstrap case.

PropertyTypeRequiredDescription
actionstring | nullno—
creditLevelstring | nullno—
notestring | nullno—

ReturningNationalReceiptResult

PropertyTypeRequiredDescription
decidedAtstring (date-time)no—
decisionstring | nullno—
decisionBasisstring | nullno—
decisionIdstring (uuid)no—
foreignLoastring | nullno—
intakeIdstring | nullno—
mappedDomesticAssurancestring | nullno—
matchedPriorSovereignVaultRefstring | nullno—
originJurisdictionstring | nullno—
originSchemestring | nullno—
policyIdstring | nullno—
ranIdentityCheckbooleanno—
residualCheckRequiredbooleanno—
resolvedAtstring (date-time) | nullno—
subjectUserIdstring (uuid)no—

RevalidatePrimaryContactFactorsRequest

Wire body to re-validate recovery factors.

PropertyTypeRequiredDescription
factorStatesstring[] | nullno—

RevalidatePrimaryContactFactorsResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
factorsRevalidatedAtstring (date-time)no—
recoveryFactorStatesstring[] | nullno—
statusstring | nullno—

ReverseMergeResponse

The reversal receipt returned by `POST /api/v1/account/merge/{id}/reverse` — the exact shape the delivered client's `ReverseMergeResult` renders on the Step-7 "Undo merge" affordance (debt-2026-07-07-104).

PropertyTypeRequiredDescription
auditRefstring | nullnoAudit anchor reference for the reversal record (EPIC 4 / 12).
grantsRevertedinteger (int32)noNumber of repointed grants reverted onto the restored account.
noticesRetractedinteger (int32)noNumber of org notices retracted by the reversal.
restoredAccountIdstring (uuid)noThe account restored by the reversal (previously retired).
reversedAtstring (date-time)noUTC instant the reversal was recorded.
survivorAccountIdstring (uuid)noThe surviving account retained after the reversal.

RevocationProofDto

PropertyTypeRequiredDescription
exportablebooleanno—
revocationDateIsostring | nullno—
revocationProofRefstring | nullno—
revokedGuardianIds(string (uuid))[] | nullno—
subjectIdstring (uuid)no—

RevocationSnapshotDto

PropertyTypeRequiredDescription
entriesRevocationSnapshotEntryDto[] | nullno—
generatedAtstring (date-time)no—

RevocationSnapshotEntryDto

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
tokenIdstring | nullno—

RevokeAllSessionsResult

PropertyTypeRequiredDescription
messagestring | nullno—
sessionsRevokedinteger (int32)no—
successbooleanno—

RevokeAssistRequestBody

Request body for revoking a grant.

PropertyTypeRequiredDescription
reasonstring | nullno—

RevokeAssistResult

PropertyTypeRequiredDescription
alreadyRevokedbooleanno—
grantIdstring (uuid)no—

RevokeDelegateAccessRequestBody

Request body for revoking a grant.

PropertyTypeRequiredDescription
reasonstring | nullno—

RevokeDelegateAccessResult

PropertyTypeRequiredDescription
alreadyRevokedbooleanno—
grantIdstring (uuid)no—

RevokeProbateRoleRequest

Request body for revoking a grant.

PropertyTypeRequiredDescription
reasonstring | nullno—
revokedByUserIdstring (uuid) | nullnoOptional explicit revoking-party attribution, mirroring Essence.Identity.Auth.Api.Controllers.GrantProbateRoleRequest.GrantedByUserId. Additive and optional: an org-portal caller omits it and keeps attributing to its own claims.

RevokeProbateRoleResult

PropertyTypeRequiredDescription
grantIdstring (uuid)no—
revokedbooleanno—

RevokeSessionResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—

RevokeSharedDeviceRequest

Revocation body.

PropertyTypeRequiredDescription
reasonstring | nullnoOptional: why, e.g. "stolen from the Leeds branch".

RevokeWearableSessionRequest

Request body for scope-revoking a single lost companion watch's delegated session. The subject is always the authenticated caller (from the JWT), never the body.

PropertyTypeRequiredDescription
delegateFromstring (uuid) | nullnoThe phone principal the watch token was delegated from (FR-65.051); optional.
reasonstring | nullnoNon-PII reason token (e.g. `reported-lost`). Defaults server-side when omitted.
watchDeviceIdstring (uuid)noStable id of the paired watch device to sign out.

RevokeWearableSessionResult

PropertyTypeRequiredDescription
boundedInertBystring (date-time) | nullno—
revokedbooleanno—
revokedAtstring (date-time)no—

RotateSharedDeviceKeyRequest

Key-rotation body.

PropertyTypeRequiredDescription
publicKeyJwkstring | nullnoThe machine's new EC P-256 public JWK, as a JSON string.

SafeguardingAuthorityRow

PropertyTypeRequiredDescription
authorityIdstring (uuid)no—
authorityNamestring | nullno—
isRecognisedbooleanno—
organizationIdstring (uuid)no—
recognisedAtstring (date-time)no—
statusstring | nullno—
statusChangedAtstring (date-time)no—
statusReasonstring | nullno—
statutoryReferencestring | nullno—

SafeguardingOfficerAuthorisationResult

PropertyTypeRequiredDescription
authorisedbooleanno—
authorisedSincestring (date-time) | nullno—
officerUserIdstring (uuid)no—

SafeguardingOfficerRegisterResult

PropertyTypeRequiredDescription
authorisedCountinteger (int32)no—
authorityIdstring (uuid)no—
authorityNamestring | nullno—
authorityStatusstring | nullno—
officersSafeguardingOfficerRow[] | nullno—
organizationIdstring (uuid)no—
totalCountinteger (int32)no—

SafeguardingOfficerRow

PropertyTypeRequiredDescription
authorisedbooleanno—
designatedAtstring (date-time)no—
officerReferencestring | nullno—
officerUserIdstring (uuid)no—
revocationReasonstring | nullno—
revokedAtstring (date-time) | nullno—
roleIssuedAtstring (date-time) | nullno—
statusstring | nullno—
suspendedAtstring (date-time) | nullno—
suspensionReasonstring | nullno—
verificationLevelstring | nullno—
verifiedAtstring (date-time) | nullno—

SendEmailOtpResult

PropertyTypeRequiredDescription
expiresAtstring (date-time) | nullno—
messagestring | nullno—
retryAfterSecondsinteger (int32) | nullno—
sentbooleanno—
statusstring | nullno—

SendProbateStepUpChallengeRequest

Request body for issuing a probate step-up challenge. `factor` carries the contract's kebab-case wire value (`email` | `sms` | `webauthn` | `phone-call` | `postal-code`) — a `string`, not the domain enum, because this service registers no global `JsonStringEnumConverter` and an enum property would bind only integer ordinals (#8134).

PropertyTypeRequiredDescription
estateIdstring (uuid)no—
factorstring | nullno—

SendSmsOtpResult

PropertyTypeRequiredDescription
expiresAtstring (date-time) | nullno—
messagestring | nullno—
retryAfterSecondsinteger (int32) | nullno—
sentbooleanno—
statusstring | nullno—

SessionDto

PropertyTypeRequiredDescription
accessTokenExpiresAtstring (date-time)no—
createdAtstring (date-time)no—
deviceFriendlyNamestring | nullno—
deviceIdstring (uuid)no—
deviceTypeDeviceTypeno—
idstring (uuid)no—
ipAddressstring | nullno—
isActivebooleanno—
isCurrentbooleanno—
lastRefreshAtstring (date-time) | nullno—
lastRefreshIpAddressstring | nullno—
refreshTokenExpiresAtstring (date-time)no—
statusSessionStatusno—
userAgentstring | nullno—
userIdstring (uuid)no—

SessionMeResponse

Response DTO for the session identity endpoint.

PropertyTypeRequiredDescription
accessTokenstring | nullnoESS-QA-007 (sovereign-routing reload fix): a fresh SHORT-LIVED access token minted from the cookie-authenticated principal. The SPA holds it in memory only (never persisted) to (a) route data-plane calls to the user's sovereign edge via its `home_region` claim and (b) present a cross-origin bearer to that edge. Null when the account could not be resolved to mint a token (the client then falls back to cookie-only mode).
accessTokenExpiresAtstring (date-time) | nullnoAbsolute expiry (UTC) of Essence.Identity.Auth.Api.Controllers.SessionMeResponse.AccessToken, so the client can proactively re-exchange the cookie for a fresh token before it lapses.
emailstring | nullno—
emailVerifiedbooleannoESS-QA-007 (I-3): whether the account's email is verified. Sourced from the `email_verified` JWT claim. Lets a cookie-mode reload restore the client's `emailVerified` flag so a verified user is not wrongly re-routed to verify-email.
firstNamestring | nullno—
hasPasswordbooleannoTrue when the account has a client-side password set. False for social/passkey-only accounts.
homeRegionstring | nullnoThe user's home sovereign region (e.g. `GB`) — the routing pointer, non-PII — matching the `home_region` claim on Essence.Identity.Auth.Api.Controllers.SessionMeResponse.AccessToken. Null when no token was minted.
instanceIdstring | nullno—
isPasswordlessbooleannoTrue when the account has no password but at least one passkey — i.e. it can authenticate without a password.
lastNamestring | nullno—
onboardingPendingbooleannoESS-QA-007 (I-3): whether first-run onboarding is still pending. Now means "email not yet verified" (computed as `!EmailVerified`) — the only server-sourced onboarding gate a reload must honour. The account setup checklist (password / passkeys / MFA / recovery) reads Essence.Identity.Auth.Api.Controllers.SessionMeResponse.SetupPosture instead, so an email-verified user with an incomplete setup is never re-gated to the onboarding wizard.
organizationIdstring | nullnoThe organisation this session is scoped to, resolved from the token's canonical organisation claim (Essence.Platform.Infrastructure.Security.OrgClaims.ClaimNames). `null` means the session has no organisation — a personal account — and nothing else: a token whose aliases disagree is refused by the action rather than reported here as absent (#13852).
passkeyCountinteger (int32)noNumber of active WebAuthn/passkey credentials enrolled.
rolestring | nullno—
rolesstring[] | nullnoEvery role the session's token carries, in claim order (#13747). Essence.Identity.Auth.Api.Controllers.SessionMeResponse.Role is only the first of them, so a client that gates on it cannot see a second role: a platform admin who is also granted `identity-authority` was refused the custodial-order console that the server would have served them. Empty for an account with no role.
setupPostureSetupPostureDtono—
userIdstring | nullno—

SessionStatus

0 | 1 | 2 | 3 with no declared properties.

SetAdviceAgencyCapabilitiesRequest

Request body for replacing an agency's adviser permission ceiling.

PropertyTypeRequiredDescription
adviserCapabilitiesstring[] | nullnoThe replacement set. At least one.

SetOperationalRoleRequest

Request body for a grant. Carries no organisation — that comes from the route.

PropertyTypeRequiredDescription
rolestring | nullnoA catalogue role value.
userIdstring (uuid)noThe member receiving the role.

SetOrgOperationalRoleOutcome

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 with no declared properties.

SetOrgOperationalRoleResult

PropertyTypeRequiredDescription
operationalRolesstring[] | nullno—
outcomeSetOrgOperationalRoleOutcomeno—

SetPasswordRequest

Request body for `POST /password/set`. Essence.Identity.Auth.Api.Controllers.SetPasswordRequest.PasswordHash is the client-derived hash (as on `register`) — never a plaintext password.

PropertyTypeRequiredDescription
passwordHashstring | nullno—

SetPreferredLocaleRequest

Body for `PUT /api/v1/users/me/locale` and `PUT /api/v1/profile/preferred-locale`. The subject is resolved from the authenticated principal, never the body.

PropertyTypeRequiredDescription
localestring | nullnoThe requested BCP-47 language tag (e.g. `ar-AE`).

SetProfileNameRequest

Body for `PUT /api/v1/profile/name`. The subject is resolved from the authenticated principal, never the body.

PropertyTypeRequiredDescription
firstNamestring | nullnoThe first name. Required.
lastNamestring | nullnoThe last name. Optional.

SetSupportAgentStatusRequestBody

Request body for a bulk agent status change.

PropertyTypeRequiredDescription
agentIds(string (uuid))[] | nullno—
appIdstring (uuid)no—
statusstring | nullno—

SetTrustedEhrIssuerStatusRequest

Wire body for changing a trusted issuer's status.

PropertyTypeRequiredDescription
reasonstring | nullnoOperator-supplied reason, recorded for audit.
statusstring | nullnoOne of `Active`, `Suspended`, `Withdrawn`.

SetupPostureDto

Account setup posture nested in Essence.Identity.Auth.Api.Controllers.SessionMeResponse — what the account has configured so the client can render a setup checklist authoritatively (password → `POST /auth/password/set`, passkeys, MFA, recovery).

PropertyTypeRequiredDescription
accountCreatedAtstring (date-time) | nullnoUTC creation timestamp of the account; null when unresolved.
hasPasswordbooleannoTrue when the account has a client-side password set.
mfaEnabledbooleannoTrue when a second factor (TOTP/SMS/Email) is enrolled.
passkeyCountinteger (int32)noNumber of active WebAuthn/passkey credentials enrolled.
recoveryConfiguredbooleannoTrue when a <b>recovery-phrase proof</b> is enrolled on this account (`POST /api/v1/auth/recovery-phrase/enrol`; EPIC 44 D-126 phase 2, FR-05.082) — i.e. the 24-word phrase can recover the vault after a forgotten password. This reflects the recovery PHRASE only. Shamir share configuration (FR-01.096) is owned by the ShamirRecovery module in a different service and is not resolved cross-service here; the client still reads that from `GET /api/v1/recovery/configuration/{userId}`.

SetUserRoleRequest

Request body for M:Essence.Identity.Auth.Api.Controllers.AdminUserRolesController.GrantRole(System.String,Essence.Identity.Auth.Api.Controllers.SetUserRoleRequest,System.Threading.CancellationToken).

PropertyTypeRequiredDescription
rolestring | nullno—

SetUserRoleResult

PropertyTypeRequiredDescription
rolesstring[] | nullno—
userIdstring (uuid)no—

SharedDeviceAttestationVerdictDto

The verdict, and the device it names when one was resolved.

PropertyTypeRequiredDescription
labelstring | nullnoThe device's label, when one was resolved.
outcomestring | nullnoOne of the kebab-case verdicts listed on the endpoint.
revokedAtstring (date-time) | nullnoWhen the device was revoked, for a `revoked` verdict.
sharedDeviceIdstring (uuid) | nullnoThe device; present whenever the attestation's key resolved to one.

SharedDeviceDto

PropertyTypeRequiredDescription
enrolledAtstring (date-time)no—
enrolledByUserIdstring (uuid)no—
idstring (uuid)no—
keyRotatedAtstring (date-time) | nullno—
keyThumbprintstring | nullno—
labelstring | nullno—
organizationIdstring (uuid)no—
publicKeyJwkstring | nullno—
revocationReasonstring | nullno—
revokedAtstring (date-time) | nullno—
revokedByUserIdstring (uuid) | nullno—
statusstring | nullno—

SignUpProofOfWork

PropertyTypeRequiredDescription
challengestring | nullno—
solutionstring | nullno—

SmartTokenExchangeRequest

Wire body for the SMART launch-token exchange.

PropertyTypeRequiredDescription
clientIdstring | nullnoThe registered SMART app's client id.
issstring | nullnoThe EHR's FHIR base URL.
launchTokenstring | nullnoThe EHR's one-time opaque launch token.
requestedScopesstring[] | nullnoExplicit scope array; takes precedence over Essence.Identity.Auth.Api.Controllers.SmartTokenExchangeRequest.Scope when present.
scopestring | nullnoSpace-delimited OAuth scope string (the SMART-native shape).

SmartTokenExchangeResponse

Contracted success body of the SMART launch-token exchange.

PropertyTypeRequiredDescription
accessTokenstring | nullnoScoped FHIR access token, audience-bound to the EHR.
encounterstring | nullnoOpaque vendor encounter reference (`launch/encounter`), when launched.
expiresIninteger (int32)noAccess-token lifetime in seconds.
grantedScopesstring[] | nullnoThe scopes identity was willing to grant.
idTokenstring | nullnoClinician identity token, audience-bound to the SMART app.
patientstring | nullnoOpaque vendor patient reference (`launch/patient`).

SmsEnrolmentResponse

Text-message codes are on: the masked number they go to, and the backup codes (shown once).

PropertyTypeRequiredDescription
backupCodesstring[] | nullno—
enrolledbooleanno—
maskedNumberstring | nullno—

SponsoredPremiumInput

PropertyTypeRequiredDescription
entitlementLabelstring | nullno—
planLabelstring | nullno—
sponsorNamestring | nullno—

StartAccountMergeRequest

Wire body to start a merge session.

PropertyTypeRequiredDescription
retiredAccountIdstring (uuid)noThe account being retired (folded away).
retiringAccountIdentifierstring | nullnoThe sign-in address naming the account to retire, when its id is unknown. Opens a `PendingBinding` session: the address is resolved and bound at `prove`, after a second factor enrolled on that account verifies — never at open, so opening a session cannot be used to test whether an address holds an Essence account.

StartAccountMergeResponse

PropertyTypeRequiredDescription
mergeSessionIdstring (uuid)no—
statusstring | nullno—

StartKeyClaimRequestBody

Request body for starting the key claim.

PropertyTypeRequiredDescription
guardianshipIdstring (uuid) | nullnoOptional link to the originating guardianship.

StartKeyClaimResult

PropertyTypeRequiredDescription
challengeIdstring (uuid)no—
claimIdstring (uuid)no—
requiredAssurancestring | nullno—

StepRequest

Body for advancing a session to a coarse step.

PropertyTypeRequiredDescription
stepstring | nullno—

StepUpAssertionResponse

Wire form of the signed irreversible-action step-up assertion (FR-15.008.7).

PropertyTypeRequiredDescription
actionstring | nullno—
challengeIdstring | nullno—
factorstring | nullno—
issuedAtUtcstring (date-time)no—
passwordReverifiedbooleanno—
signaturestring | nullno—
userIdstring (uuid)no—

StepUpEmailCodeRequest

Request body for `POST /api/v1/auth/step-up/email-code` (#8753).

PropertyTypeRequiredDescription
actionstring | nullnoThe step-up action the code will elevate for, e.g. `password-change`.

SubjectExportDelegationRequest

Request to mint a subject-export delegation credential for the caller.

PropertyTypeRequiredDescription
exportRequestIdstring (uuid)noThe queued export the credential is bound to.
lifetimeSecondsinteger (int32)noLifetime the caller's compilation SLA needs. Clamped at mint time to the credential's own ceiling — a caller cannot widen it by asking.

SubjectExportDelegationResponse

A minted subject-export delegation credential.

PropertyTypeRequiredDescription
expiresAtstring (date-time)noAbsolute UTC expiry.
tokenstring | nullnoThe signed JWT to present to subject-export source endpoints.
tokenIdstring | nullnoIts `jti`, for audit correlation.

SubjectNameabilityDto

PropertyTypeRequiredDescription
existsbooleanno—
hasRecordedNamebooleanno—
userIdstring (uuid)no—

SubmitAppealByTokenRequest

Body for `POST /api/v1/account/appeals/by-token` — the sessionless appeal.

PropertyTypeRequiredDescription
statementstring | nullnoThe appellant's statement.
tokenstring | nullnoThe single-purpose notice token issued at the sign-in refusal.

SubmitAppealRequest

Body for `POST /api/v1/account/appeals` (the appellant's statement).

PropertyTypeRequiredDescription
actionIdstring (uuid)noThe account-action decision being appealed.
statementstring | nullnoThe appellant's statement.

SubmitCustodialOrderRequest

Submission body. Matches the shipped client's `submitOrderProof` payload.

PropertyTypeRequiredDescription
childUserIdstring (uuid) | nullnoThe child's existing subject id, when custody is being taken of an existing record.
documentNamestring | nullno—
documentRefstring | nullnoOpaque reference to the client-encrypted order document, when stored.
effectiveDatestring | nullnoISO-8601 date the order took effect.
evidenceCodesstring[] | nullno—
instrumentCodestring | nullno—
issuingAuthoritystring | nullno—
jurisdictionCodestring | nullno—
orderReferencestring | nullno—

SupportAccessCustomerDecisionDto

PropertyTypeRequiredDescription
consentIdstring (uuid)no—
decidedAtstring (date-time)no—
expiresAtstring (date-time) | nullno—
grantIdstring (uuid) | nullno—
requestIdstring (uuid)no—
statusstring | nullno—

SupportAccessDecisionBody

The customer's decision — the body `essence-web/src/features/support-access/api/supportAccessApi.ts` already posts.

PropertyTypeRequiredDescription
decisionstring | nullno`allow` or `deny`.
grantIdstring (uuid) | nullnoThe grant the caller's own client created, when it did. Verified, not trusted.
reasonstring | nullnoThe customer's own words when denying. Never required.

SupportAccessRequestDto

PropertyTypeRequiredDescription
agentIdstring (uuid)no—
durationMinutesinteger (int32)no—
partnerAppIdstring (uuid)no—
raisedAtstring (date-time)no—
requestIdstring (uuid)no—
scopesstring[] | nullno—
statusstring | nullno—

SupportAccessRequestListItemDto

PropertyTypeRequiredDescription
agentIdstring (uuid)no—
agentPrincipalIdstring (uuid)no—
consentIdstring (uuid) | nullno—
decidedAtstring (date-time) | nullno—
declineReasonCodestring | nullno—
durationMinutesinteger (int32)no—
grantIdstring (uuid) | nullno—
partnerAppIdstring (uuid)no—
raisedAtstring (date-time)no—
raisedByUserIdstring (uuid)no—
reasonCodestring | nullno—
requestIdstring (uuid)no—
scopesstring[] | nullno—
statusstring | nullno—
subjectUserReferencestring | nullno—
supervisorAgentIdstring (uuid) | nullno—
supervisorDecidedAtstring (date-time) | nullno—
supervisorPrincipalIdstring (uuid) | nullno—
ticketReferencestring | nullno—

SupportAccessRequestListItemDtoCursorResult

PropertyTypeRequiredDescription
hasMorebooleanno—
itemsSupportAccessRequestListItemDto[] | nullno—
nextCursorstring | nullno—
pageSizeinteger (int32)no—
previousCursorstring | nullno—

SupportAccessSessionDescriptorDto

PropertyTypeRequiredDescription
agentDisplayNamestring | nullno—
agentPrincipalIdstring (uuid)no—
consentIdstring (uuid)no—
partnerAppIdstring (uuid)no—
partnerNamestring | nullno—
partnerNameStatusstring | nullno—
publisherNamestring | nullno—
publisherVerifiedboolean | nullno—
reasonCodestring | nullno—
ticketReferencestring | nullno—

SupportAgentDto

PropertyTypeRequiredDescription
agentIdstring (uuid)no—
displayNamestring | nullno—
emailstring | nullno—
enrolledAtstring (date-time)no—
principalIdstring (uuid) | nullno—
rolestring | nullno—
statusstring | nullno—

SupportAgentInvitationDto

PropertyTypeRequiredDescription
acceptedAtstring (date-time) | nullno—
agentIdstring (uuid)no—
displayNamestring | nullno—
emailstring | nullno—
invitedAtstring (date-time)no—
partnerAppIdstring (uuid)no—
partnerAppNamestring | nullno—
partnerNameStatusstring | nullno—
publisherNamestring | nullno—
publisherVerifiedboolean | nullno—
rolestring | nullno—
statusstring | nullno—

SupportAgentStatusChangeDto

PropertyTypeRequiredDescription
updatedinteger (int32)no—

SupportImpersonationPolicyDto

PropertyTypeRequiredDescription
allowedScopesstring[] | nullno—
appIdstring (uuid)no—
configuredbooleanno—
dailyRequestLimitPerAgentinteger (int32)no—
dualApprovalRequiredbooleanno—
eligibleRolesstring[] | nullno—
maxDurationMinutesinteger (int32)no—
reasonCodesstring[] | nullno—
updatedAtstring (date-time) | nullno—

SupportImpersonationPolicyRequestBody

Request body for saving a support-impersonation policy (the dashboard's `ImpersonationPolicy`).

PropertyTypeRequiredDescription
allowedScopesstring[] | nullno—
appIdstring (uuid)no—
dailyRequestLimitPerAgentinteger (int32)no—
dualApprovalRequiredbooleanno—
eligibleRolesstring[] | nullno—
maxDurationMinutesinteger (int32)no—
reasonCodesstring[] | nullno—

SuspendDelegatedAgentRequest

Request body for incident-driven suspension.

PropertyTypeRequiredDescription
incidentIdstring (uuid)noThe EPIC 12 incident driving containment.
reasonstring | nullnoA closed-vocabulary suspension reason.

SuspendDelegatedAgentResponse

Suspension response — the EPIC 9 containment leg's return value.

PropertyTypeRequiredDescription
sessionsRevokedinteger (int32)noHow many live sessions were cut.
suspensionReferencestring | nullnoThe reference the containment chain records.
wasAlreadySuspendedbooleannoTrue when the agent's access had already been cut.

TakeoverIncidentView

PropertyTypeRequiredDescription
incidentIdstring (uuid)no—
keysRotatedAtstring (date-time) | nullno—
openedAtstring (date-time)no—
sessionsTerminatedinteger (int32)no—
sharesRevokedAtstring (date-time) | nullno—
sharesRevokedCountinteger (int32)no—

TakeoverStateView

PropertyTypeRequiredDescription
frozenbooleanno—
frozenAtstring (date-time) | nullno—
incidentTakeoverIncidentViewno—

TerminatePrincipalAccessRequest

Request body for an FR-09.044 administrative access termination. The acting operator is deliberately absent — it comes from the caller's token.

PropertyTypeRequiredDescription
campaignRefstring | nullnoThe recertification campaign this termination is anchored to. Required.
deviceIdstring (uuid) | nullnoRequired when Essence.Identity.Auth.Api.Controllers.TerminatePrincipalAccessRequest.Scope is `device`.
grantIdstring (uuid) | nullnoThe access grant being revoked, if the campaign named one.
reasonstring | nullnoNon-PII reason token (e.g. `recertification-deadline-unattested`). Required.
scopestring | nullno`all` (default), `device`, or `sessions`.
sessionIds(string (uuid))[] | nullnoRequired when Essence.Identity.Auth.Api.Controllers.TerminatePrincipalAccessRequest.Scope is `sessions`.
subjectUserIdstring (uuid)noThe staff principal whose access is being terminated.
systemCodestring | nullnoThe EPIC 87 access-bearing system code the revocation is on behalf of, if named.

TerminatePrincipalAccessResult

PropertyTypeRequiredDescription
credentialsRevokedinteger (int32)no—
recordIdstring (uuid) | nullno—
refusedReasonstring | nullno—
sessionsRevokedinteger (int32)no—
terminatedbooleanno—
terminatedAtstring (date-time) | nullno—

TerminateSupportAccessSessionRequestBody

Request body for a partner force-terminate.

PropertyTypeRequiredDescription
reasonstring | nullno—

TerminateSupportAccessSessionResult

PropertyTypeRequiredDescription
alreadyEndedbooleanno—
sessionIdstring (uuid)no—

TokenValidationDto

PropertyTypeRequiredDescription
deviceIdstring (uuid) | nullno—
emailstring | nullno—
emailVerifiedbooleanno—
errorMessagestring | nullno—
isValidbooleanno—
mfaEnabledbooleanno—
userIdstring (uuid) | nullno—

TransitionAuditResultDto

PropertyTypeRequiredDescription
auditRecordIdstring | nullno—
recordedAtIsostring | nullno—

TransitionGuardianshipRequest

Request body for committing the majority transition.

PropertyTypeRequiredDescription
reConsentDecisionsReConsentChoiceDto[] | nullnoThe young adult's per-grant re-consent decisions from the affirmative gate.

TrustDeviceResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—

TrustedEhrIssuerDto

PropertyTypeRequiredDescription
allowedClientIdsstring[] | nullno—
displayNamestring | nullno—
distrustReasonstring | nullno—
distrustedAtstring (date-time) | nullno—
grantableScopesstring[] | nullno—
idstring (uuid)no—
issstring | nullno—
organizationIdstring (uuid) | nullno—
statusstring | nullno—

UaePassAccountLinkRequest

Body of `POST auth/federated-accounts/uae-pass`.

PropertyTypeRequiredDescription
homeRegionstring | nullnoThe sovereign region a new account is homed in (the caller's, `AE`).
subjectstring | nullnoThe verified UAE Pass `sub`.

UaePassAccountLinkResponse

Response of `POST auth/federated-accounts/uae-pass`.

PropertyTypeRequiredDescription
isNewUserbooleannoTrue when this call provisioned the account.
userIdstring (uuid)noThe Essence user id the subject is linked to.

UndoAccountMergeResponse

PropertyTypeRequiredDescription
mergeSessionIdstring (uuid)no—
reversedAtstring (date-time)no—
statusstring | nullno—

UnlockAccountResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—
userNotFoundbooleanno—

UpdateDeviceNameRequest

PropertyTypeRequiredDescription
friendlyNamestring | nullno—

UpdateDeviceNameResult

PropertyTypeRequiredDescription
messagestring | nullno—
successbooleanno—

UserIdentityAttributesDto

PropertyTypeRequiredDescription
emailstring | nullno—
emailVerifiedbooleanno—
existsbooleanno—
firstNamestring | nullno—
lastNamestring | nullno—
nameAssuredbooleanno—
phonestring | nullno—
phoneVerifiedbooleanno—
userIdstring (uuid)no—

ValidateTokenQuery

PropertyTypeRequiredDescription
accessTokenstring | nullno—

VaultScopeInput

PropertyTypeRequiredDescription
accessstring | nullno—
descriptionstring | nullno—
vaultLabelstring | nullno—

VerificationActionResult

PropertyTypeRequiredDescription
appliedinteger (int32)no—
appliedVerificationIds(string (uuid))[] | nullno—
requestedinteger (int32)no—

VerificationIdsRequest

Request body carrying the target verification ids for a bulk recheck / reminder.

PropertyTypeRequiredDescription
verificationIds(string (uuid))[] | nullno—

VerifiedNameChangeView

PropertyTypeRequiredDescription
accountIdstring (uuid)no—
affectedConsentRefsstring[] | nullno—
auditAnchorRefstring | nullno—
cancelledAtstring (date-time) | nullno—
changeIdstring (uuid)no—
committedAtstring (date-time) | nullno—
deedPollDocumentIdstring (uuid) | nullno—
newNameHashstring | nullno—
newNameMaskedstring | nullno—
notifiedCountinteger (int32)no—
previousNameDispositionstring | nullno—
previousNameHashstring | nullno—
previousNameMaskedstring | nullno—
reattestationRefstring | nullno—
reattestedAtstring (date-time) | nullno—
statusstring | nullno—
syncedConnectionRefsstring[] | nullno—
withheldCountinteger (int32)no—

VerifyEmailOtpByEmailRequest

Request body for `POST /email/verify-otp/by-email` (#7539) — the sessionless redemption. Carries the address because an anonymous caller has nothing else to identify itself with.

PropertyTypeRequiredDescription
codestring | nullnoThe 6-digit code from the verification email.
emailstring | nullnoThe address the account was registered with.

VerifyEmailOtpByEmailResponse

Response body for a successful `POST /email/verify-otp/by-email`.

PropertyTypeRequiredDescription
verifiedbooleannoAlways true when this body is returned.

VerifyEmailOtpRequest

Request body for `POST /email/verify-otp` — the in-app email-verification OTP the user typed into the app.

PropertyTypeRequiredDescription
codestring | nullno—

VerifyEmailOtpResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
accessTokenExpiresAtstring (date-time) | nullno—
attemptsExhaustedbooleanno—
codeExpiredbooleanno—
messagestring | nullno—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time) | nullno—
verifiedbooleanno—

VerifyEmailResult

PropertyTypeRequiredDescription
userIdstring (uuid) | nullno—
verifiedbooleanno—

VerifyExecutorOfficerRequest

Request body for recording an officer's identity verification.

PropertyTypeRequiredDescription
verificationLevelstring | nullnoThe assurance level reached (e.g. `medium`, `high`).
verificationReferencestring | nullnoNon-PII reference to the identity-assurance record that verified the officer.

VerifyKeyClaimRequestBody

Request body for verifying the key claim.

PropertyTypeRequiredDescription
codestring | nullnoThe one-time code the subject received.
rewrappedVaultKeyEnvelopestring | nullnoThe device-produced re-wrapped vault UMK envelope (private half never leaves the device).

VerifyKeyClaimResult

PropertyTypeRequiredDescription
claimIdstring (uuid)no—
identityChangeRefstring | nullno—
remainingAttemptsinteger (int32)no—
revocationProofRefstring | nullno—
verifiedbooleanno—
verifiedAtIsostring | nullno—

VerifyMfaCommand

PropertyTypeRequiredDescription
allowWhenMfaDisabledbooleanno—
codestring | nullno—
methodMfaMethodno—
userIdstring (uuid)no—

VerifyMfaResult

PropertyTypeRequiredDescription
isValidbooleanno—
messagestring | nullno—
successbooleanno—

VerifyNewPrimaryContactAddressRequest

Wire body to verify the new address.

PropertyTypeRequiredDescription
codestring | nullno—

VerifyNewPrimaryContactAddressResult

PropertyTypeRequiredDescription
changeIdstring (uuid)no—
statusstring | nullno—
trustWindowClosesAtstring (date-time)no—

VerifyProfessionalAdviserRequest

Request body for recording an adviser's identity verification.

PropertyTypeRequiredDescription
verificationLevelstring | nullnoThe assurance level reached, e.g. `high`.
verificationReferencestring | nullnoNon-PII reference to the identity-assurance record.

VerifySafeguardingOfficerRequest

Request body for recording an officer's identity verification.

PropertyTypeRequiredDescription
verificationLevelstring | nullnoThe assurance level reached, e.g. `high`.
verificationReferencestring | nullnoNon-PII reference to the identity-assurance record.

VerifySharedDeviceAttestationRequest

The check's input. Organisation, user and session come from the worker's token.

PropertyTypeRequiredDescription
attestationstring | nullno—
organizationIdstring (uuid)no—
sessionIdstring (uuid)no—
userIdstring (uuid)no—

WebAuthnAuthenticationOptions

PropertyTypeRequiredDescription
allowCredentialsWebAuthnCredentialDescriptor[] | nullno—
challengestring | nullno—
rpIdstring | nullno—
sessionIdstring | nullno—
timeoutinteger (int32)no—
userVerificationstring | nullno—

WebAuthnAuthenticationResult

PropertyTypeRequiredDescription
accessTokenstring | nullno—
deviceLimitDeviceLimitPauseno—
deviceLimitReachedbooleanno—
errorMessagestring | nullno—
expiresIninteger (int32)no—
mfaRequiredbooleanno—
refreshTokenstring | nullno—
successbooleanno—
userIdstring (uuid)no—

WebAuthnAuthenticatorSelection

PropertyTypeRequiredDescription
authenticatorAttachmentstring | nullno—
requireResidentKeybooleanno—
residentKeystring | nullno—
userVerificationstring | nullno—

WebAuthnCredentialDescriptor

PropertyTypeRequiredDescription
idstring | nullno—
transportsstring[] | nullno—
typestring | nullno—

WebAuthnCredentialListResponse

Envelope for the passkey list, matching the client's `{ data: [...] }` shape.

PropertyTypeRequiredDescription
dataWebAuthnCredentialSummary[] | nullno—

WebAuthnCredentialSummary

PropertyTypeRequiredDescription
aaguidstring | nullno—
authenticatorModelstring | nullno—
certificationstring | nullno—
certificationWithdrawnReasonstring | nullno—
createdAtstring (date-time)no—
idstring | nullno—
lastUsedstring (date-time) | nullno—
namestring | nullno—
transportsstring[] | nullno—
typestring | nullno—
webAuthnCredentialIdstring | nullno—

WebAuthnPubKeyCredParam

PropertyTypeRequiredDescription
alginteger (int32)no—
typestring | nullno—

WebAuthnRegistrationOptions

PropertyTypeRequiredDescription
attestationstring | nullno—
authenticatorSelectionWebAuthnAuthenticatorSelectionno—
challengestring | nullno—
excludeCredentialsWebAuthnCredentialDescriptor[] | nullno—
pubKeyCredParamsWebAuthnPubKeyCredParam[] | nullno—
relyingPartyWebAuthnRelyingPartyno—
sessionIdstring | nullno—
timeoutinteger (int32)no—
userWebAuthnUserEntityno—

WebAuthnRegistrationResult

PropertyTypeRequiredDescription
createdAtstring (date-time)no—
credentialIdstring (uuid)no—
credentialTypestring | nullno—
deviceNamestring | nullno—
errorMessagestring | nullno—
successbooleanno—
vaultBindingTokenstring | nullno—

WebAuthnRelyingParty

PropertyTypeRequiredDescription
idstring | nullno—
namestring | nullno—

WebAuthnUserEntity

PropertyTypeRequiredDescription
displayNamestring | nullno—
idstring | nullno—
namestring | nullno—

WithdrawAccountMergeApprovalResponse

The result of retracting a queued approval request (gap G-withdraw, `uxf-2026-08-12-017`): the merge session and the approval state the SERVER now holds. Exactly the two fields the member's client reads before releasing its override — it branches on this outcome rather than on anything it stored locally.

PropertyTypeRequiredDescription
approvalStatusstring | nullno—
mergeSessionIdstring (uuid)no—

Built with ❤️ for developers · Service status