API reference ✅
The complete endpoint catalogue available today. This page is a
human-readable companion to the machine-readable contract — the
authoritative, drift-tested source is
docs/contracts/openapi.json (regenerated on every
API change and enforced by tests). Import that file into Postman / Swagger / your
codegen.
- Base URL:
{base}(e.g.https://<node-domain>/id). Ask your operator. - Contract version:
0.7.0. - Auth: noted per endpoint. The panel endpoints take a
Bearersession token; consent/token/identity contract endpoints are server-to-server in the trusted channel; federation endpoints are the browser handshake. - Errors: standard HTTP.
422= validation (e.g. unknown scope/category),403= not authorized (no matching grant / trust-partner required),404= unknown DID/consent,401= bad/missing session.
Identity (L1) ✅
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/identity/register |
Register a P-256 public key → derive DID, return DID document |
POST |
/v1/identity/register/begin |
WebAuthn registration: creation options |
POST |
/v1/identity/register/finish |
Verify attestation → DID + session |
POST |
/v1/identity/auth/begin |
WebAuthn sign-in: request options |
POST |
/v1/identity/auth/finish |
Verify assertion → session |
GET |
/v1/identity/resolve/{did} |
Resolve a DID document |
GET |
/u/{user_id}/did.json |
Standard did:web resolution path |
POST |
/v1/identity/rotate |
Trust-partner-approved key rotation (header X-Trust-Partner-Token; fail-secure) |
POST |
/v1/identity/session/verify |
Resolve a session token → {active, did, expires_at} |
POST |
/v1/identity/session/logout |
Revoke a session token |
Register example:
POST {base}/v1/identity/register
{ "public_key_jwk": { "kty": "EC", "crv": "P-256", "x": "…", "y": "…" } }
→ { "did": "did:web:…", "created": true, "did_document": { … } }
DID derivation: did:web:<domain>:u:<first-16-hex-of-RFC7638-thumbprint>.
Registration is idempotent by key (created:false if already known).
Recovery (L1) ✅
Email-magic-link recovery (beta trust anchor). Primarily an end-user / web-surface flow; listed for completeness.
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/recovery/email |
Enroll a recovery email (session-auth) → verify link |
POST |
/v1/recovery/email/verify |
Confirm the email from the link |
POST |
/v1/recovery/email/status |
Masked email + verified flag (session-auth) |
POST |
/v1/recovery/begin |
Start recovery from an email → recovery link |
POST |
/v1/recovery/finish |
New passkey + recovery token → rotate key, new session |
Consent (L2) ✅
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/consent/grant |
Create a grant → {consent_id, receipt} |
POST |
/v1/consent/revoke |
Revoke a grant → kills tokens, ledgers it |
GET |
/v1/consent/grants/{did} |
All grants for a DID (receipts) |
GET |
/v1/consent/ledger/{did} |
Full hash-chained ledger {chain_valid, entries[]} |
POST |
/v1/access/record |
Record a data access (resource-host audit) |
See Scopes & consent for field-level detail and the
receipt shape. Scopes: cgm, daily, labs, body_composition, recovery,
activity.
Authorization / tokens (L3) ✅
| Method | Path | Purpose |
|---|---|---|
POST |
/v1/token |
Issue a data-access token (RPT) against a matching grant |
POST |
/v1/token/introspect |
Validate a token → claims or {active:false}. token_type:"access" carries resource_owner + scope; token_type:"user" carries subject_did |
GET |
/v1/revocation/{user_id} |
Public revocation registry for a subject |
Consent panel (LC-TASK 4) ✅ — Bearer session token
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/panel/summary |
Identity + active grants |
GET |
/v1/panel/feed |
Reverse-chron ledger feed; ?category=&limit=&before= |
POST |
/v1/panel/grant |
Grant as the session user (no subject_did) |
POST |
/v1/panel/revoke |
Revoke (ownership-checked) |
See Embedding the consent panel.
Federation — "Sign in with LifeCare.ID" ✅
Browser-redirect + form handshake on the LifeCare.ID origin. Not in the JSON contract (it's a redirect/form surface), but stable and documented in Authentication.
| Method | Path | Purpose |
|---|---|---|
GET |
/authorize |
OAuth authorization request (code + PKCE S256) |
POST |
/token |
Confidential-client code exchange → {did, access_token} |
GET |
/, /signin, /recover, /verify-email |
LifeCare.ID web surface pages |
POST |
/session, /session/establish |
Set the session cookie on the LifeCare.ID origin |
POST |
/session/logout, GET /logout |
End a session (RP-initiated logout honors registered origins) |
Service
| Method | Path | Purpose |
|---|---|---|
GET |
/healthz |
Liveness probe → {status:"ok", service:"lifecareid"} |
Conventions
- Timestamps are ISO 8601 UTC, second precision.
- DIDs are
did:web:<domain>:u:<id>;{user_id}in paths is the trailing<id>. - Token prefixes:
lcs_= session / user token (introspects withsubject_did— proves the caller is the user),lc_= data-access token (RPT; introspects withresource_owner, never a subject). - Zero-PHI: every field of every request/response carries only identity, scope, consent, or token metadata — never a health value.