Skip to content

Shamir Recovery Service API ​

All OpenAPI documents

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

API for Shamir Secret Sharing key recovery workflows. All endpoints require a Bearer token (SEC-001).

Generated from the ShamirRecovery service's code at build time (api-specs/generated/ShamirRecovery/Essence.Core.ShamirRecovery.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.

GuardianAttestation

GET/api/v1/recovery/attest/{token}

Loads an attestation challenge by its single-use token (FR-01.083a). The attestation page (essence-web `/recovery/guardian/attest`) calls this on load; the server stamps the page-loaded observation, records the first load as `attestation-page-loaded` on the recovery audit chain, and returns the bound nonce + expiry.

SEC-001/002 exception — see the controller remarks.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenpathstringyes—

Request body

No request body.

Responses

200Challenge resolved. — GuardianAttestationChallengeResponse
404Token is unknown, already used, or expired. — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/attest/{token}

Submits a guardian attestation (FR-01.083 / FR-01.083a): the client-derived Ed25519 signature over the challenge nonce. The server verifies it against the share's enrolled public key.

SEC-001/002 exception — see the controller remarks. Zero-knowledge: only the signature is submitted.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
tokenpathstringyes—

Request body

Not marked as required in the document.

Responses

200Submission processed (see `verified`). — GuardianAttestationResultResponse
400Malformed signature. — ProblemDetails
404Token is unknown, already used, or expired. — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/shares/{shareId}/attestation/challenge

Issues a fresh attestation challenge for an enrolled share (FR-01.083). Authenticated path for an in-app (account-holder) guardian who requests an on-demand attestation.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
shareIdpathstring (uuid)yes—

Request body

No request body.

Responses

200Challenge issued. — GuardianAttestationChallengeResponse
401Unauthorized — ProblemDetails
404Share not found. — ProblemDetails
409Share has no enrolled attestation key. — ProblemDetails
POST/api/v1/recovery/shares/{shareId}/attestation/enrol

Enrols (or re-enrols) the guardian's Ed25519 attestation public key for a share (FR-01.083). Authenticated — the owning user / account-holder guardian registers the public key derived client-side from the share.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
shareIdpathstring (uuid)yes—

Request body

Not marked as required in the document.

Responses

204Attestation key enrolled.
400Malformed public key or cadence out of range. — ProblemDetails
401Unauthorized — ProblemDetails
404Share not found. — ProblemDetails

InternalRecoveryCustody

GET/api/v1/internal/recovery/custody/{userId}

Whether the subject still holds startable recovery material.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesThe subject to answer about.

Request body

No request body.

Responses

200The posture. `hasSurvivingConfiguration=false` is a real answer — EPIC 1 holds no startable configuration for this subject — and is never a substitute for an error: a caller that receives no response at all must treat the question as unanswered, not as "false". — RecoveryCustodyPostureResult
401No valid bearer token. — ProblemDetails

RecoveryConfiguration

GET/api/v1/recovery/configuration

Lists all recovery configurations for the authenticated user.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Recovery configurations retrieved successfully — RecoveryConfigurationResponse[]
400Invalid user identity — ProblemDetails
POST/api/v1/recovery/configuration

Creates a new recovery configuration for a user.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Recovery configuration created successfully — RecoveryConfigurationResponse
400Invalid request — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
409Recovery configuration already exists for user — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/configuration/guardians/{shareId}/replace

Replaces ONE guardian, keeping every other guardian's acceptance (#4718 item 3).

Every share is reissued, which Shamir makes unavoidable — one secret is split, and old pieces cannot be mixed with new ones. What this avoids is making the unchanged guardians say yes again to a commitment they already made to the same person; they are told instead. The live configuration keeps serving until the replacement's shares reach the threshold, so there is no window in which the account holder has no way back.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
shareIdpathstring (uuid)yesThe share slot whose guardian is leaving.

Request body

Not marked as required in the document.

Responses

201Replacement recorded; the new guardian has been invited and the rest told. — RecoveryContactNominationResponse
400The replacement is the same guardian, or the set breaks an FR-01.079 constraint. — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
404No active configuration, or that share is not on it. — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/configuration/nominations

Nominates the named people who will hold this user's recovery shares (FR-01.079), creating the recovery configuration when the caller does not yet have one, and dispatching each nominee's invitation (FR-01.070).

The scheme-only M:Essence.Core.ShamirRecovery.Api.Controllers.RecoveryConfigurationController.CreateRecoveryConfiguration(Essence.Core.ShamirRecovery.Contracts.Requests.CreateRecoveryConfigurationRequest,Essence.Core.ShamirRecovery.Application.Services.IRecoverySettingsStepUpGate,System.Threading.CancellationToken) endpoint records <em>how many</em> shares exist but nothing about <em>who</em> holds them, and share generation requires a checksum and an account id per guardian — so before this endpoint a user's chosen contacts had nowhere to be recorded. Zero-knowledge: only scheme parameters and contact metadata cross the wire; shares are split and wrapped on the device.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Recovery contacts nominated and invitations dispatched. — RecoveryContactNominationResponse
400Invalid scheme, or the guardian set violates an FR-01.079 constraint. — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
409The caller's configuration already has a nominated guardian set. — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/configuration/redistributed

Registers a new-generation recovery configuration in the non-serving `Distributed` state during post-rotation share redistribution (FR-01.068 / AC-01.061). The caller's existing `Active` configuration keeps serving recovery sessions until the new shares reach the k-of-n threshold and are atomically promoted.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

201Distributed configuration registered. — RecoveryConfigurationResponse
400Invalid request or no user identity. — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
409No Active configuration exists to redistribute from. — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/configuration/redistributed/promote

Records the client-verified established-share count for a `Distributed` configuration and, when the k-of-n threshold is reached, performs the FR-01.068 atomic swap (AC-01.061): the new configuration is promoted to `Active` and the previously-active configuration is invalidated in a single transaction. If the threshold is not met, the old configuration is retained as the read-valid fallback and a recovery-degraded warning is emitted.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Establishment recorded; swap performed or deferred. — PromoteRedistributedRecoveryConfigurationResult
400Invalid request or no user identity. — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
404Target configuration not found for the caller. — ProblemDetails
409Target configuration is not in the Distributed state. — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/configuration/resolve

Resolves the address a locked-out reader typed into the `recoveryConfigurationId` that `POST /api/v1/recovery/initiate` requires (debt-2026-08-15-106, journey `account-recovery-lost-devices`).

<b>Always HTTP 200, and deliberately so.</b> Someone who has lost every device holds no session and no user id, so this is necessarily an unauthenticated read against the platform's highest-risk surface — which means it must not become a membership oracle. Unknown account, known account with no recovery configuration, and configuration-not-startable all return the SAME body: `{ resolved: false, recoveryConfigurationId: null }`. A 404 for one of them would be exactly the signal being withheld. <b>Rate-limited by IP</b> (SEC-004) at the same cap as recovery initiation, since there is no principal to partition by; and the address is never a log field on any path.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Resolution completed — inspect `resolved`. — RecoveryConfigurationResolutionResponse
429Too many resolution attempts from this address. — ProblemDetails
PUT/api/v1/recovery/configuration/{configId}

Updates an existing recovery configuration's threshold scheme.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
configIdpathstring (uuid)yesRecovery configuration identifier

Request body

Not marked as required in the document.

Responses

200Recovery configuration updated successfully — RecoveryConfigurationResponse
400Invalid scheme parameters — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
404Recovery configuration not found — ProblemDetails
423Locked — ProblemDetails
DELETE/api/v1/recovery/configuration/{configId}

Deactivates a recovery configuration (soft delete per DAT-002).

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
configIdpathstring (uuid)yesRecovery configuration identifier

Request body

No request body.

Responses

204Recovery configuration deactivated successfully
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
404Recovery configuration not found — ProblemDetails
423Locked — ProblemDetails
GET/api/v1/recovery/configuration/{userId}

Gets the authenticated caller's recovery configuration.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
userIdpathstring (uuid)yesRoute value retained for backward-compatible URLs (and the M:Essence.Core.ShamirRecovery.Api.Controllers.RecoveryConfigurationController.CreateRecoveryConfiguration(Essence.Core.ShamirRecovery.Contracts.Requests.CreateRecoveryConfigurationRequest,Essence.Core.ShamirRecovery.Application.Services.IRecoverySettingsStepUpGate,System.Threading.CancellationToken) Location header). It is ignored: the configuration returned is always the caller's own, resolved from the JWT principal.

Request body

No request body.

Responses

200Recovery configuration retrieved successfully — RecoveryConfigurationResponse
404Recovery configuration not found — ProblemDetails

RecoveryEnrolmentPosture

POST/api/v1/internal/recovery-enrolment/events/lookup

The recovery-attempt lifecycle events of the named users in an inclusive window (#22121): `Initiated` at each initiation, `Completed` or `Failed` at each termination.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The events, oldest first; empty when no named user had recovery activity in the window. — RecoveryLifecycleEvent[]
400More than 500 users, an empty GUID, a missing bound, or the window end before its start. — ProblemDetails
401No valid bearer token. — ProblemDetails
403The caller is not a service principal. — ProblemDetails
POST/api/v1/internal/recovery-enrolment/guardian-links/lookup

Which of the named members depend on which of the named guardians, one edge per (guardian, member) whose share on the member's startable configuration can contribute (#22122).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The edges, ordered by guardian then member; empty when nobody depends on a named guardian. — RecoveryGuardianLink[]
400More than 500 of either, or an empty GUID. — ProblemDetails
401No valid bearer token. — ProblemDetails
403The caller is not a service principal. — ProblemDetails
POST/api/v1/internal/recovery-enrolment/posture/lookup

The recovery enrolment posture of each named user, one row per distinct user.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200One row per distinct requested user; an unconfigured user is a row with zero guardians. — RecoveryEnrolmentPosture[]
400More than 500 users, or an empty GUID. — ProblemDetails
401No valid bearer token. — ProblemDetails
403The caller is not a service principal. — ProblemDetails
POST/api/v1/internal/recovery-enrolment/self-service-link

Sends the member a link that starts their own guardian recovery.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200The link was committed for delivery to the member's channel of record. — SelfServiceRecoveryLinkResponse
400An empty organisation or user reference. — ProblemDetails
401No valid bearer token. — ProblemDetails
403The caller is not a service principal. — ProblemDetails
409The member cannot self-serve (no startable configuration with a contributing guardian); nothing was sent. — ProblemDetails
429The member has already been sent the maximum number of links in the window; nothing was sent. — ProblemDetails

RecoveryWorkflow

GET/api/v1/recovery/attempts/dry-run

Reads the caller's current recovery dry run (#4718).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200The dry run's current state. — RecoveryDryRunResponse
404The caller has no dry run. — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/attempts/dry-run

Extracts the authenticated user identifier from the JWT principal. Reads the standard `NameIdentifier` / `sub` claims. Returns false when no authenticated user id is present or it is not a GUID, so callers can short-circuit with 401 rather than trusting request input (A01 IDOR hardening, sf-2026-05-26-006 / sf-2026-05-26-009).

Nothing is reconstructed and no share is collected. The rehearsal has no transport key, so there is no path from here to key material — the impossibility is structural rather than checked.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

202Dry run started; guardians are being asked. — RecoveryDryRunResponse
404The caller has no active recovery configuration. — ProblemDetails
409A dry run is already running, or no guardian has enrolled a key. — ProblemDetails
429Dry-run rate limit exceeded. — ProblemDetails
POST/api/v1/recovery/attempts/dry-run/cancel

Stops the caller's dry run early (#4718).

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

No request body.

Responses

200Dry run cancelled. — RecoveryDryRunResponse
409There is no dry run to cancel. — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/recovery/attempts/{attemptId}

Gets a recovery attempt by its ID.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
attemptIdpathstring (uuid)yesRecovery attempt identifier

Request body

No request body.

Responses

200Recovery attempt retrieved successfully — RecoveryInitiationQuorumResponse
404Recovery attempt not found — ProblemDetails
GET/api/v1/recovery/attempts/{attemptId}/guardian-context

Serves a token-bearing guardian the request context they need in order to re-wrap their share under FR-01.062 (debt-2026-08-15-107): who is asking, when they asked, which share this link is for, and the recovering device's transport public key to wrap to.

<b>This read does NOT consume the token.</b> The submission it precedes needs the same single-use token, so spending it here would make the read fatal to the write it exists to enable. Replay is still reported (409) — the ledger is read, never written — and `POST submit-share/by-guardian-token` remains the sole atomic authority for single-use. <b>Zero-knowledge.</b> Display name only, never an email; no guardian roster, no other guardian's state. The recovering user's own screen anonymises their guardians (Decision D-254), and this must not disclose more to a third party than to the account holder.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
attemptIdpathstring (uuid)yesThe recovery attempt the token is bound to.
X-Guardian-TokenheaderstringnoThe per-share bearer token (header).

Request body

No request body.

Responses

200Context returned; the token is untouched. — GuardianRecoveryContextResponse
401Forged / malformed / expired token. — ProblemDetails
403Wrong-scope token, or a token bound to a different recovery. — ProblemDetails
404The recovery attempt is unknown or has ended. — ProblemDetails
409The token has already been used to submit. — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/recovery/audit/verify

Verifies the tamper-evident social-recovery audit chain (FR-01.040). Re-computes every entry's hash and confirms the forward-only chain is contiguous, so a stakeholder/auditor can detect any historical edit. An optional sessionId scopes the check to a single recovery session's subchain; omit it to verify the whole chain from genesis.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
sessionIdquerystring (uuid)noOptional recovery-session scope; verifies the full chain when null.

Request body

No request body.

Responses

200Verification completed (see `isValid`). — RecoveryAuditChainVerificationResponse
POST/api/v1/recovery/configuration/{configId}/guardians/invitation

Records a guardian's FR-01.070 invitation accept/decline decision, authenticated by an FR-01.007a guardian <b>invitation-acceptance</b> bearer token (debt-2026-06-21-1423) — the path an <b>email-only guardian</b> (no Essence account session) uses. The token is carried in the `X-Guardian-Token` header and is HMAC-bound to `{guardianIdentity, configurationId, nominatedShareIndices}`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
configIdpathstring (uuid)yesRecovery configuration the nomination belongs to (token-bound).
X-Guardian-TokenheaderstringnoThe invitation-acceptance bearer token (header).

Request body

Not marked as required in the document.

Responses

200Decision recorded; token consumed. — RespondToGuardianInvitationResponse
401Forged / malformed / expired token. — ProblemDetails
403Wrong-scope token (e.g. a share-submission token), or an identity/configuration binding mismatch. — ProblemDetails
404Configuration not found, or no share is nominated to this guardian. — ProblemDetails
409Token already consumed (replay). — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/recovery/guardians/invitation-context

Reads what design board 4d must show a nominated guardian before they answer — who the scheme belongs to, what they would hold, and how many others hold a share — authenticated by the FR-01.007a <b>invitation-acceptance</b> token WITHOUT consuming it (#5723).

<b>This read does NOT consume the token.</b> The accept/decline it precedes needs the same single-use token, so spending it to render the page would make answering impossible. Replay is still reported (409) — the ledger is read, never written — and `POST configuration/{configId}/guardians/invitation` remains the sole atomic authority for single-use. Exactly the split the share-submission pair already makes. <b>The route takes no ids.</b> Everything is derived from the token's MAC-trusted claims: a reader holding only an emailed link asserts no identity and must not be able to name a configuration of their own. That also keeps the emailed URL to a single `?token=` parameter, which is what the notification can actually construct. <b>Zero-knowledge.</b> The arrangement, never the vault: no document count, no field name, nothing derived from contents, and a COUNT of the other holders rather than a roster — board 4b's promise that a guardian never learns "who the other guardians are".

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
X-Guardian-TokenheaderstringnoThe invitation-acceptance bearer token (header).

Request body

No request body.

Responses

200Context returned; the token is untouched. — GuardianInvitationContextResponse
401Forged / malformed / expired token. — ProblemDetails
403Wrong-scope token (e.g. a share-submission token). — ProblemDetails
404Configuration unknown, no nomination for this identity, or the share was invalidated. — ProblemDetails
409The invitation has already been answered. — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/recovery/guardians/recovery-context

The same guardian request context, for a guardian holding ONLY the token — which is all the approval email (board 7g) can carry (#12292). The recovery attempt, the guardian identity and the share index all come from the token's MAC-trusted claims, and the response hands back the attempt id, identity and provenance id the submission needs.

The emailed link was `/recovery/guardian/submit?token=` while the page required four further parameters no producer could supply, so every real approval email dead-ended. The route takes no ids for the reason M:Essence.Core.ShamirRecovery.Api.Controllers.RecoveryWorkflowController.GetGuardianInvitationContext(System.String,System.Threading.CancellationToken) takes none: a reader holding only a link asserts no identity and must not be able to name a recovery of their own. <b>This read does NOT consume the token</b>; replay is reported (409), never caused.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
X-Guardian-TokenheaderstringnoThe per-share bearer token (header).

Request body

No request body.

Responses

200Context returned; the token is untouched. — GuardianRecoveryContextResponse
401Forged / malformed / expired token. — ProblemDetails
403A genuine token of the wrong scope. — ProblemDetails
404The recovery attempt is unknown or has ended. — ProblemDetails
409The token has already been used to submit. — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/initiate

Initiates a key recovery attempt.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200FR-01.103: `withdrawGuardianQuorumId` — the request is withdrawn; nothing initiated — RecoveryInitiationQuorumResponse
201Recovery attempt initiated successfully — RecoveryAttemptResponse
202FR-01.103: `requestGuardianQuorum` — the guardians have been asked to confirm; nothing initiated yet
400Invalid request — ProblemDetails
401FR-01.045 step-up elevation absent or unverifiable — ProblemDetails
404Recovery configuration not found — ProblemDetails
409An attempt is already in progress (FR-01.064) or a key rotation is active (FR-01.067) — ProblemDetails
429Too Many Requests — ProblemDetails
GET/api/v1/recovery/initiation-quorums/{quorumId}

Gets a recovery attempt by its ID.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
quorumIdpathstring (uuid)yesFR-01.103 initiation-quorum id, on the `initiation-quorums/{quorumId}` route only.

Request body

No request body.

Responses

200Recovery attempt retrieved successfully — RecoveryInitiationQuorumResponse
404Recovery attempt not found — ProblemDetails
POST/api/v1/recovery/reconstruct

Reconstructs the secret from submitted shares. CRITICAL: Returns shares to the client for client-side reconstruction. Two phases since #17586: a relay (the default) returns the shares and KEEPS them; a confirm (`"confirm": true`) completes the attempt and erases them.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Shares relayed, or the reconstruction confirmed — ReconstructSecretResponse
400Insufficient shares — ProblemDetails
404Recovery attempt not found — ProblemDetails
409The attempt already ended, or a confirm of shares never relayed — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/rehearse

Rehearses (dry-runs) a reconstruction without reconstructing the secret. CRITICAL: returns only a readiness verdict — no share material, no UMK unwrap, no data release. This is the EPIC 18 → EPIC 1 pre-mortem seam (journey executor-plan-pre-mortem-rehearsal-dry-run, debt-2026-06-18-295). The rehearsal emits an auditable RecoveryRehearsalCompletedIntegrationEvent (run-type=rehearsal) asserting the zero-knowledge boundary held.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Rehearsal completed; verdict returned — RehearseReconstructionResponse
400Invalid request — ProblemDetails
404Recovery attempt not found — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/submit-share

Submits a share during a recovery attempt.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Share submitted successfully — SubmitShareResponse
400Invalid share — ProblemDetails
404Recovery attempt not found — ProblemDetails
429Too Many Requests — ProblemDetails
POST/api/v1/recovery/submit-share/by-guardian-token

Submits a wrapped recovery share authenticated by an FR-01.007a guardian per-share bearer token (debt-2026-06-21-1423) — the path an <b>email-only guardian</b> (no Essence account session) uses. The token is carried in the `X-Guardian-Token` header and is HMAC-bound to `{recoverySessionId, shareIndex, guardianIdentity}`.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
X-Guardian-TokenheaderstringnoThe per-share bearer token (header).

Request body

Not marked as required in the document.

Responses

200Share submitted; token consumed. — SubmitShareResponse
401Forged / malformed / expired token. — ProblemDetails
403Wrong-scope token, or a cross-share / identity binding mismatch. — ProblemDetails
404Recovery attempt not found. — ProblemDetails
409Token already consumed (replay). — ProblemDetails
429Too Many Requests — ProblemDetails

ShareManagement

POST/api/v1/recovery/shares/generate

Generates share metadata for distribution.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Share metadata generated successfully — GenerateSharesResponse
400Invalid request — ProblemDetails
401No fresh `act=recovery-settings-change` elevation (`step-up-required`, DVS-4.4c).
404Recovery configuration not found — ProblemDetails
423Locked — ProblemDetails
POST/api/v1/recovery/shares/verify

Verifies share integrity by comparing its checksum against stored metadata. This is a zero-knowledge verification — the server only sees checksums, never actual share data.

Authentication:Bearer (the document-wide requirement)

Parameters

Takes no parameters.

Request body

Not marked as required in the document.

Responses

200Share verification completed — ShareVerificationResponse
400Invalid request — ProblemDetails
404Recovery configuration not found — ProblemDetails
GET/api/v1/recovery/shares/{recoveryId}/status

Gets the share collection status for a recovery attempt.

Authentication:Bearer (the document-wide requirement)

Parameters

NameInTypeRequiredDescription
recoveryIdpathstring (uuid)yesRecovery attempt identifier

Request body

No request body.

Responses

200Status retrieved successfully — ShareCollectionStatusResponse
404Recovery attempt not found — ProblemDetails

Schemas

CreateRecoveryConfigurationRequest

PropertyTypeRequiredDescription
schemeTypestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

EnrolGuardianAttestationKeyRequest

PropertyTypeRequiredDescription
attestationPublicKeystring | nullno—

GenerateSharesRequest

PropertyTypeRequiredDescription
recoveryConfigurationIdstring (uuid)no—
shareMetadataShareMetadataInput[] | nullno—

GenerateSharesResponse

PropertyTypeRequiredDescription
recoveryConfigurationIdstring (uuid)no—
shareMetadataShareMetadataDto[] | nullno—
sharesCreatedinteger (int32)no—

GuardianAttestationChallengeResponse

PropertyTypeRequiredDescription
challengeNoncestring | nullno—
expiresAtstring (date-time)no—
purposestring | nullno—
tokenstring | nullno—

GuardianAttestationResultResponse

PropertyTypeRequiredDescription
nextAttestationDueAtstring (date-time) | nullno—
verifiedbooleanno—

GuardianInvitationContextResponse

PropertyTypeRequiredDescription
configurationIdstring (uuid)no—
expiresAtstring (date-time)no—
guardianDisplayNamestring | nullno—
guardianIdentitystring | nullno—
invitationStatusstring | nullno—
nominatedAtstring (date-time) | nullno—
otherGuardiansCountinteger (int32)no—
requesterDisplayNamestring | nullno—
requesterUserIdstring (uuid)no—
shareIndexinteger (int32)no—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

GuardianRecoveryContextResponse

PropertyTypeRequiredDescription
guardianIdentitystring | nullno—
initiatedAtstring (date-time)no—
recoveryAttemptIdstring (uuid)no—
recoveryTransportPublicKeyJwkRsaPublicKeyJwkno—
requesterDisplayNamestring | nullno—
shareIndexinteger (int32)no—
submittedByContactIdstring (uuid)no—

InitiateRecoveryRequest

PropertyTypeRequiredDescription
guardianQuorumIdstring (uuid) | nullno—
recoveryConfigurationIdstring (uuid)no—
recoveryTransportPublicKeystring | nullno—
requestGuardianQuorumbooleanno—
stepUpTokenstring | nullno—
withdrawGuardianQuorumIdstring (uuid) | nullno—

NominateRecoveryContactsRequest

PropertyTypeRequiredDescription
contactsRecoveryContactNominationInput[] | nullno—
schemeTypestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

ProblemDetails

PropertyTypeRequiredDescription
detailstring | nullno—
instancestring | nullno—
statusinteger (int32) | nullno—
titlestring | nullno—
typestring | nullno—

PromoteRedistributedRecoveryConfigurationRequest

PropertyTypeRequiredDescription
establishedShareCountinteger (int32)no—
newConfigurationIdstring (uuid)no—

PromoteRedistributedRecoveryConfigurationResult

PropertyTypeRequiredDescription
activeConfigurationIdstring (uuid)no—
establishedShareCountinteger (int32)no—
invalidatedConfigurationIdstring (uuid)no—
newConfigurationIdstring (uuid)no—
swappedbooleanno—
thresholdinteger (int32)no—
userIdstring (uuid)no—

ReconstructSecretRequest

PropertyTypeRequiredDescription
confirmbooleanno—
recoveringDeviceFingerprintstring | nullno—
recoveryAttemptIdstring (uuid)no—

ReconstructSecretResponse

PropertyTypeRequiredDescription
accessTokenstring | nullno—
alreadyConfirmedbooleanno—
completedAtstring (date-time)no—
confirmedbooleanno—
recoveryAttemptIdstring (uuid)no—
refreshTokenstring | nullno—
refreshTokenExpiresAtstring (date-time) | nullno—
sessionExpiresAtstring (date-time) | nullno—
sharesSubmittedShareDto[] | nullno—
sharesHeldbooleanno—
sharesReturnedinteger (int32)no—
successbooleanno—

RecoveryAttemptResponse

PropertyTypeRequiredDescription
anchorConfirmedboolean | nullno—
assuranceLevelstring | nullno—
completedAtstring (date-time) | nullno—
hasSufficientSharesbooleanno—
idstring (uuid)no—
initiatedAtstring (date-time)no—
ipAddressstring | nullno—
recoveryConfigurationIdstring (uuid)no—
recoveryTransportPublicKeystring | nullno—
relayedAtstring (date-time) | nullno—
sharesHeldbooleanno—
sharesSubmittedinteger (int32)no—
statusstring | nullno—
thresholdRequiredinteger (int32)no—
userAgentstring | nullno—
userIdstring (uuid)no—

RecoveryAuditChainPrefixResponse

PropertyTypeRequiredDescription
anchorEntryIdstring (uuid)no—
declaredAtstring (date-time)no—
declaredEntriesinteger (int32) | nullno—
entriesBeforeAnchorinteger (int32)no—
reasonstring | nullno—
verdictstring | nullno—

RecoveryAuditChainVerificationResponse

PropertyTypeRequiredDescription
entriesCheckedinteger (int32)no—
failureReasonstring | nullno—
firstFailureEntryIdstring (uuid) | nullno—
firstFailureIndexinteger (int32) | nullno—
isValidbooleanno—
prefixRecoveryAuditChainPrefixResponseno—

RecoveryConfigurationResolutionResponse

PropertyTypeRequiredDescription
recoveryConfigurationIdstring (uuid) | nullno—
resolvedbooleanno—

RecoveryConfigurationResponse

PropertyTypeRequiredDescription
acceptedContactCountinteger (int32)no—
contactsRecoveryContactStateDto[] | nullno—
createdAtstring (date-time)no—
declinedContactCountinteger (int32)no—
establishedShareCountinteger (int32)no—
idstring (uuid)no—
isActivebooleanno—
lastUpdatedAtstring (date-time) | nullno—
nominatedContactCountinteger (int32)no—
pendingContactCountinteger (int32)no—
schemeTypestring | nullno—
shareMetadataShareMetadataDto[] | nullno—
statestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—
usableShareCountinteger (int32)no—
userIdstring (uuid)no—

RecoveryContactNominationInput

PropertyTypeRequiredDescription
distributionMethodstring | nullno—
emailstring | nullno—
essenceAccountIdstring (uuid) | nullno—
namestring | nullno—
phonestring | nullno—

RecoveryContactNominationResponse

PropertyTypeRequiredDescription
configurationIdstring (uuid)no—
invitationsSentAtIsostring (date-time) | nullno—
nominationsRecoveryContactNominationState[] | nullno—
schemestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

RecoveryContactNominationState

PropertyTypeRequiredDescription
awaitingShareGenerationbooleanno—
emailstring | nullno—
guardianIdentityTypestring | nullno—
invitationDispatchedAtstring (date-time) | nullno—
invitationStatusstring | nullno—
namestring | nullno—
shareIndexinteger (int32)no—
shareMetadataIdstring (uuid)no—

RecoveryContactStateDto

PropertyTypeRequiredDescription
acceptedbooleanno—
awaitingShareGenerationbooleanno—
canContributeToRecoverybooleanno—
contactEmailstring | nullno—
displayNamestring | nullno—
guardianIdentityTypestring | nullno—
invitationDispatchedbooleanno—
invitationStatusstring | nullno—
isInvalidatedbooleanno—
linkedEssenceAccountIdstring (uuid) | nullno—
nominatedAtstring (date-time) | nullno—
respondedAtstring (date-time) | nullno—
shareIndexes(integer (int32))[] | nullno—

RecoveryCustodyPostureResult

PropertyTypeRequiredDescription
hasSurvivingConfigurationbooleanno—
userIdstring (uuid)no—

RecoveryDryRunResponse

PropertyTypeRequiredDescription
concludedAtstring (date-time) | nullno—
expiresAtstring (date-time)no—
guardiansAskedinteger (int32)no—
guardiansRespondedinteger (int32)no—
initiatedAtstring (date-time)no—
noSecretReconstructedbooleanno—
outcomestring | nullno—
rehearsalIdstring (uuid)no—
thresholdRequiredinteger (int32)no—
verdictMeaningstring | nullno—

RecoveryEnrolmentPosture

PropertyTypeRequiredDescription
guardianCountinteger (int32)no—
guardianRecentlyDepartedbooleanno—
lastAttestationAtstring (date-time) | nullno—
thresholdRequiredinteger (int32)no—
userRefstring (uuid)no—

RecoveryEnrolmentPostureLookupRequest

PropertyTypeRequiredDescription
userRefs(string (uuid))[] | nullno—

RecoveryGuardianLinkLookupRequest

PropertyTypeRequiredDescription
guardianRefs(string (uuid))[] | nullno—
userRefs(string (uuid))[] | nullno—

RecoveryInitiationQuorumResponse

PropertyTypeRequiredDescription
expiresAtstring (date-time)no—
guardiansAskedinteger (int32)no—
guardiansConfirmedinteger (int32)no—
idstring (uuid)no—
recoveryAttemptIdstring (uuid) | nullno—
recoveryConfigurationIdstring (uuid)no—
requestedAtstring (date-time)no—
statusstring | nullno—
thresholdMetbooleanno—
thresholdRequiredinteger (int32)no—

RecoveryLifecycleEvent

PropertyTypeRequiredDescription
idstring (uuid)no—
occurredAtstring (date-time)no—
outcomestring | nullno—
typestring | nullno—
userRefstring (uuid)no—

RecoveryLifecycleEventLookupRequest

PropertyTypeRequiredDescription
fromstring (date-time)no—
untilstring (date-time)no—
userRefs(string (uuid))[] | nullno—

RegisterRedistributedRecoveryConfigurationRequest

PropertyTypeRequiredDescription
schemeTypestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

RehearseReconstructionRequest

PropertyTypeRequiredDescription
recoveryAttemptIdstring (uuid)no—
simulatedActorTypestring | nullno—

RehearseReconstructionResponse

PropertyTypeRequiredDescription
noDataReleasedbooleanno—
noUmkUnwrappedbooleanno—
rehearsalSessionIdstring (uuid)no—
rehearsedAtstring (date-time)no—
runTypestring | nullno—
sharesAvailableinteger (int32)no—
sharesRequiredinteger (int32)no—
simulatedActorTypestring | nullno—
wouldReconstructbooleanno—

ResolveRecoveryConfigurationRequest

PropertyTypeRequiredDescription
accountEmailstring | nullno—

RespondToGuardianInvitationRequest

PropertyTypeRequiredDescription
acceptedbooleanno—
guardianIdentitystring | nullno—

RespondToGuardianInvitationResponse

PropertyTypeRequiredDescription
acceptedbooleanno—
configurationIdstring (uuid)no—
guardianIdentitystring | nullno—
sharesAffectedinteger (int32)no—

RsaPublicKeyJwk

PropertyTypeRequiredDescription
algstring | nullno—
estring | nullno—
extbooleanno—
key_opsstring[] | nullno—
ktystring | nullno—
nstring | nullno—

SelfServiceRecoveryLinkRequest

PropertyTypeRequiredDescription
organizationIdstring (uuid)no—
userRefstring (uuid)no—

SelfServiceRecoveryLinkResponse

PropertyTypeRequiredDescription
sentbooleanno—

ShareCollectionStatusResponse

PropertyTypeRequiredDescription
canReconstructbooleanno—
pendingShareIndices(integer (int32))[] | nullno—
recoveryAttemptIdstring (uuid)no—
sharesSubmittedinteger (int32)no—
statusstring | nullno—
submittedShareIndices(integer (int32))[] | nullno—
thresholdRequiredinteger (int32)no—
totalSharesinteger (int32)no—

ShareMetadataDto

PropertyTypeRequiredDescription
attestationDueAtstring (date-time) | nullno—
attestationFailureCausestring | nullno—
attestationLastVerifiedAtstring (date-time) | nullno—
attestationStatusstring | nullno—
contactEmailstring | nullno—
contactPhonestring | nullno—
displayNamestring | nullno—
distributedAtstring (date-time) | nullno—
distributionConfirmationIdstring | nullno—
distributionMethodstring | nullno—
guardianIdentityTypestring | nullno—
idstring (uuid)no—
invitationRespondedAtstring (date-time) | nullno—
invitationStatusstring | nullno—
isAttestationEnrolledbooleanno—
isAwaitingShareGenerationbooleanno—
isDistributedbooleanno—
isInvalidatedbooleanno—
isInvitationAcceptedbooleanno—
isUsablebooleanno—
linkedEssenceAccountIdstring (uuid) | nullno—
recoveryConfigurationIdstring (uuid)no—
shareChecksumstring | nullno—
shareIndexinteger (int32)no—

ShareMetadataInput

PropertyTypeRequiredDescription
contactEmailstring | nullno—
contactPhonestring | nullno—
distributionMethodstring | nullno—
linkedEssenceAccountIdstring (uuid)no—
shareChecksumstring | nullno—
shareIndexinteger (int32)no—

ShareVerificationResponse

PropertyTypeRequiredDescription
failureReasonstring | nullno—
isValidbooleanno—
linkedEssenceAccountIdstring (uuid) | nullno—
shareIndexinteger (int32)no—

SubmitGuardianAttestationRequest

PropertyTypeRequiredDescription
attestationSignaturestring | nullno—

SubmitShareByGuardianTokenRequest

PropertyTypeRequiredDescription
guardianIdentitystring | nullno—
recoveryAttemptIdstring (uuid)no—
shareIndexinteger (int32)no—
submittedByContactIdstring (uuid)no—
wrappedSharestring | nullno—

SubmitShareRequest

PropertyTypeRequiredDescription
recoveryAttemptIdstring (uuid)no—
shareIndexinteger (int32)no—
submittedByContactIdstring (uuid)no—
wrappedSharestring | nullno—

SubmitShareResponse

PropertyTypeRequiredDescription
canReconstructbooleanno—
isValidbooleanno—
recoveryAttemptIdstring (uuid)no—
shareIndexinteger (int32)no—
submittedAtstring (date-time)no—
submittedShareIdstring (uuid)no—
thresholdRequiredinteger (int32)no—
totalSharesSubmittedinteger (int32)no—
validationErrorstring | nullno—

SubmittedShareDto

PropertyTypeRequiredDescription
idstring (uuid)no—
isValidbooleanno—
recoveryAttemptIdstring (uuid)no—
shareIndexinteger (int32)no—
submittedAtstring (date-time)no—
submittedByContactIdstring (uuid)no—
validationErrorstring | nullno—
wrappedSharestring | nullno—

UpdateRecoveryConfigurationRequest

PropertyTypeRequiredDescription
schemeTypestring | nullno—
thresholdinteger (int32)no—
totalSharesinteger (int32)no—

VerifyShareRequest

PropertyTypeRequiredDescription
recoveryConfigurationIdstring (uuid)no—
shareChecksumstring | nullno—
shareIndexinteger (int32)no—

Built with ❤️ for developers · Service status