Docs
  • 0.0.1latest

The HTTP API

Every route the server serves, who may call it, and how a refusal looks: one table per area, read from the server's route table.

The web application and anything else speak to the server over one JSON API under /api. This page lists every route in the server's route table, 67 of them, and the pages the server serves beside them.

Status. Release 0.0.1. The HTTP surface may change in a later release.

Calling it

A session comes from the sign-in steps: POST /api/sign-in with the email and password answers a challenge, and POST /api/sign-in/code with that challenge and an authenticator code answers a session. Send it as authorization: Bearer <session>. Bodies are JSON. A field the route does not know is refused, except in the two passkey bodies and the issuer-link return.

Records, keys and files cross the API sealed. The server checks who may do what and that a revision, a share or a wrap is shaped right; it cannot check what is inside, because it cannot open it.

Refusals

Every refusal is a body with two fields, error_code and message, and nothing else beside it.

StatusWhen
400a body or a path the route cannot accept, a password too weak to set among them
401no session, or one the server does not know
403a session whose standing is too low for the route
404something the caller does not reach: another company's anything, a record not shared with them, a request that does not exist
409a conflict with what is there now: a revision or a share list that moved since it was read, a target the record is already shared with
429too many requests in the current window; try again shortly
503the store did not answer, so nothing was decided; try again

Another company's admin who names your company is answered exactly as if it did not exist. Every route but the two that name no account (GET /api/sign-in/methods and POST /api/sign-in/passkey/begin) is called in the test suite unsigned, with an unknown session, as a lower standing and as another company, and each answers with the refusal its row expects.

"Who" below is the lowest standing that may call the route: an admin may do what a member may, and an owner what an admin may.

Account and companies

MethodPathWhoWhat it does
GET/api/companiessigned inthe companies the caller belongs to; every company for the platform admin
POST/api/companiesplatform admincreate a company and name its owner; answers the owner's enrolment token
POST/api/companies/{company}/resumeplatform adminresume a company
POST/api/companies/{company}/suspendplatform adminsuspend a company
GET/api/mesigned inthe caller's account and companies

Signing in and joining

MethodPathWhoWhat it does
POST/api/enrolment/beginanyone, with a tokenopen an enrolment
POST/api/enrolment/completeanyone, with a tokenset the sign-in password and the authenticator
POST/api/me/identities/oidcsigned inbegin linking an identity at the issuer
POST/api/me/identities/oidc/returnsigned infinish linking it
POST/api/me/passkeyssigned inregister a passkey
POST/api/me/passkeys/beginsigned ina passkey registration challenge
DELETE/api/sessionsigned insign out
POST/api/sign-inanyonethe password step; answers a challenge
POST/api/sign-in/codeanyone, with a challengethe authenticator step; answers a session
GET/api/sign-in/methodsanyonewhich ways in this server offers
GET/api/sign-in/oidcanyonebegin sign-in at the OpenID Connect issuer
GET/api/sign-in/oidc/returnanyone, with the flow's statefinish sign-in at the issuer
POST/api/sign-in/passkeyanyone, with a passkeysign in with a passkey
POST/api/sign-in/passkey/beginanyonea sign-in challenge that names no account

Members and the trail

MethodPathWhoWhat it does
GET/api/companies/{company}/auditadminthe trail, newest first
GET/api/companies/{company}/audit/verifyadmincheck the chain over the company's events
GET/api/companies/{company}/membersmemberthe members, their roles and states
POST/api/companies/{company}/membersadminadd a member with an email, a name and a role
DELETE/api/companies/{company}/members/{account}adminremove a member
PATCH/api/companies/{company}/members/{account}adminchange a member's role or state; only an owner makes or unmakes an owner
POST/api/companies/{company}/members/{account}/enrolmentadminissue a member's single-use enrolment token

Departments and teams

MethodPathWhoWhat it does
GET/api/companies/{company}/groupsmemberdepartments and teams
POST/api/companies/{company}/groupsadminmake a department or a team, with an optional parent
DELETE/api/companies/{company}/groups/{group}admindelete a group that holds no other group; its members leave it
PATCH/api/companies/{company}/groups/{group}adminrename a group
GET/api/companies/{company}/groups/{group}/keymembera group's public key and the caller's own wrap of it
PUT/api/companies/{company}/groups/{group}/keyadminkey a group: its public key and the members' wraps
GET/api/companies/{company}/groups/{group}/key/pendingadminthe members still waiting for a wrap
POST/api/companies/{company}/groups/{group}/key/wrapsadminadd wraps for waiting members
GET/api/companies/{company}/groups/{group}/membersmembera group's members
POST/api/companies/{company}/groups/{group}/membersadminadd a member to a group
DELETE/api/companies/{company}/groups/{group}/members/{account}admintake a member out of a group

Records, shares and files

MethodPathWhoWhat it does
GET/api/companies/{company}/record-typesmemberthe company's record types
POST/api/companies/{company}/record-typesadmindefine a record type and the roles that may use it
GET/api/companies/{company}/recordsmemberthe records the caller can read
POST/api/companies/{company}/recordsmembercreate a record
DELETE/api/companies/{company}/records/{record}author or admindelete a record, every revision, share and file, with a reason
GET/api/companies/{company}/records/{record}author or readerthe latest sealed revision and the caller's wrap
PUT/api/companies/{company}/records/{record}author or editorwrite a revision over the one it was read at
POST/api/companies/{company}/records/{record}/filesauthor or editorbegin a file
GET/api/companies/{company}/records/{record}/files/{file}author or readerread a complete file by offset and limit
PUT/api/companies/{company}/records/{record}/files/{file}author or editorwrite the next part, up to 4 MiB, at offset
GET/api/companies/{company}/records/{record}/sharesauthor or editorthe record's shares and its author's key
POST/api/companies/{company}/records/{record}/sharesauthor or editorshare with a member or a group, carrying the wrapped record key
DELETE/api/companies/{company}/records/{record}/shares/{target}author or editortake a share back

Keys and vouching

MethodPathWhoWhat it does
GET/api/companies/{company}/keysmemberthe company's public keys
GET/api/companies/{company}/keys/mememberthe caller's key set
PUT/api/companies/{company}/keys/mememberkeep the caller's key set
GET/api/companies/{company}/statementsmemberthe vouching chain
POST/api/companies/{company}/statementsadminappend a signed statement

Recovery

MethodPathWhoWhat it does
GET/api/companies/{company}/keys/me/escrowmemberwhich recovery key the caller escrowed to
PUT/api/companies/{company}/keys/me/escrowmemberescrow the caller's keys to the recovery key
POST/api/companies/{company}/keys/me/rewrapmemberwrap the recovered keys under a new unlock password
GET/api/companies/{company}/keys/{account}/escrowownera member's escrow; the read is shown to that member
GET/api/companies/{company}/notices/mememberwho reached the caller's keys
GET/api/companies/{company}/recovery-keymemberthe recovery key's public half
POST/api/companies/{company}/recovery-keyownerkeep the company's recovery key
GET/api/companies/{company}/recovery-key/mineownerthe caller's own wrap of the recovery key
GET/api/companies/{company}/recovery-requestsownerthe open requests
POST/api/companies/{company}/recovery-requestsmemberask for recovery with a one-time public key
POST/api/companies/{company}/recovery-requests/{request}/handoffownerhand a member's keys to their one-time key
POST/api/companies/{company}/recovery-requests/{request}/redeemthe member who askedredeem once, within 72 hours

Pages

GET /, /app.js, /app.css, /favicon.svg and /vault-crypto.wasm serve the web application: the same committed bytes to anyone, holding no data. They are compiled into the binary.