Sync server API
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
The HTTP API of the Sternway sync server, version 1.0.0: 93 routes under /api/v1. The apps use it; you need it only to script your own server (for example the audit export) or to check what the apps send. Every request and answer body is JSON unless a route says otherwise, and every vault item’s contents travel encrypted: the fields below that hold item data, keys or log chunks are ciphertext the server cannot read.
Conventions
Section titled “Conventions”- Session token. Routes that need one take
Authorization: Bearer <token>, the token the sign-in routes answer with. - Errors. A refused request answers with an HTTP error status and a body
{ "code", "message", "details"? }. The codes are listed in Error codes. - Limits. The server allows 300 requests a minute per signed-in account, and the same per client address for everything else; see Run the sync server.
- Health.
GET /healthzanswers the same asGET /api/v1/healthz, for container health checks.
WebSocket routes
Section titled “WebSocket routes”These are WebSocket upgrades, not JSON calls, so they are not in the OpenAPI document. Each is opened with a single-use ticket from POST /api/v1/ws/ticket in its ticket query parameter.
| Route | Id | What |
|---|---|---|
/api/v1/ws |
ws.connect |
Changes as they happen, and team presence. |
/api/v1/relay/:sessionId |
ws.relay |
A shared terminal session, end-to-end encrypted between its participants. |
Health
Section titled “Health”GET /api/v1/healthz
Section titled “GET /api/v1/healthz”health.get · needs nothing
Answer 200:
| Field | Type | Always there |
|---|---|---|
ok |
true |
yes |
version |
string | yes |
Signing in
Section titled “Signing in”POST /api/v1/auth/prelogin
Section titled “POST /api/v1/auth/prelogin”auth.prelogin · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
POST /api/v1/auth/signup
Section titled “POST /api/v1/auth/signup”auth.signup · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
userId |
uuid | yes |
email |
yes | |
name |
string, 1–256 chars | yes |
authKey |
base64url | yes |
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
wrappedUserKeys |
base64url | yes |
personalVault |
object | yes |
personalVault.id |
uuid | yes |
personalVault.encName |
base64url | yes |
personalVault.wrappedKey |
base64url | yes |
device |
object | yes |
device.id |
uuid | yes |
device.name |
string, 1–256 chars | yes |
device.platform |
string, 1–64 chars | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
user |
object | yes |
user.id |
uuid | yes |
user.email |
yes | |
user.name |
string, 1–256 chars | yes |
user.totpEnabled |
boolean | yes |
user.handle |
any | yes |
user.createdAt |
integer ≥ 0 | yes |
user.emailVerified |
boolean | |
user.canVerifyEmail |
boolean |
POST /api/v1/auth/login
Section titled “POST /api/v1/auth/login”auth.login · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes | |
authKey |
base64url | yes |
device |
object | yes |
device.id |
uuid | yes |
device.name |
string, 1–256 chars | yes |
device.platform |
string, 1–64 chars | yes |
totp |
string | |
recoveryCode |
string | |
passkeyTicket |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
user |
object | yes |
user.id |
uuid | yes |
user.email |
yes | |
user.name |
string, 1–256 chars | yes |
user.totpEnabled |
boolean | yes |
user.handle |
any | yes |
user.createdAt |
integer ≥ 0 | yes |
user.emailVerified |
boolean | |
user.canVerifyEmail |
boolean | |
wrappedUserKeys |
base64url | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
POST /api/v1/auth/logout
Section titled “POST /api/v1/auth/logout”auth.logout · needs a session token (Authorization: Bearer <token>)
Request body:
object
Answer 200:
object
POST /api/v1/auth/recover/start
Section titled “POST /api/v1/auth/recover/start”auth.recover.start · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes | |
recoveryAuthKey |
base64url | yes |
totp |
string | |
recoveryCode |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
userId |
uuid | yes |
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
wrappedKek |
base64url | yes |
wrappedUserKeys |
base64url | yes |
personalVaultKeys |
array of object | yes |
personalVaultKeys[].vaultId |
uuid | yes |
personalVaultKeys[].keyVersion |
integer ≥ 0 | yes |
personalVaultKeys[].wrapped |
base64url | yes |
POST /api/v1/auth/recover/complete
Section titled “POST /api/v1/auth/recover/complete”auth.recover.complete · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes | |
recoveryAuthKey |
base64url | yes |
totp |
string | |
recoveryCode |
string | |
ssoTicket |
string | |
newAuthKey |
base64url | yes |
newKdf |
object | yes |
newKdf.alg |
"argon2id13" |
yes |
newKdf.salt |
base64url | yes |
newKdf.opslimit |
integer 1–16 | yes |
newKdf.memlimit |
integer 8388608–1073741824 | yes |
newWrappedUserKeys |
base64url | yes |
personalVaultKeys |
array of object | yes |
personalVaultKeys[].vaultId |
uuid | yes |
personalVaultKeys[].keyVersion |
integer ≥ 0 | yes |
personalVaultKeys[].wrapped |
base64url | yes |
wrappedKek |
base64url | yes |
device |
object | yes |
device.id |
uuid | yes |
device.name |
string, 1–256 chars | yes |
device.platform |
string, 1–64 chars | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
user |
object | yes |
user.id |
uuid | yes |
user.email |
yes | |
user.name |
string, 1–256 chars | yes |
user.totpEnabled |
boolean | yes |
user.handle |
any | yes |
user.createdAt |
integer ≥ 0 | yes |
user.emailVerified |
boolean | |
user.canVerifyEmail |
boolean |
GET /api/v1/auth/sso/config
Section titled “GET /api/v1/auth/sso/config”auth.sso.config · needs nothing
Answer 200:
| Field | Type | Always there |
|---|---|---|
mode |
one of off, hybrid, enforced |
yes |
issuer |
any | yes |
publicClientId |
any | yes |
POST /api/v1/auth/sso/start
Section titled “POST /api/v1/auth/sso/start”auth.sso.start · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
redirectUri |
string, 1–2048 chars | yes |
clientBindingHash |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
authorizationUrl |
string | yes |
state |
string | yes |
nonce |
string | yes |
expiresAt |
integer ≥ 0 | yes |
POST /api/v1/auth/sso/exchange
Section titled “POST /api/v1/auth/sso/exchange”auth.sso.exchange · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
state |
string | yes |
code |
string | yes |
flowSecret |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
ssoTicket |
string | yes |
expiresAt |
integer ≥ 0 | yes |
email |
yes | |
name |
string | yes |
accountExists |
boolean | yes |
kdf |
object or null | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
POST /api/v1/auth/sso/login
Section titled “POST /api/v1/auth/sso/login”auth.sso.login · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
ssoTicket |
string | yes |
authKey |
base64url | yes |
device |
object | yes |
device.id |
uuid | yes |
device.name |
string, 1–256 chars | yes |
device.platform |
string, 1–64 chars | yes |
totp |
string | |
recoveryCode |
string | |
passkeyTicket |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
user |
object | yes |
user.id |
uuid | yes |
user.email |
yes | |
user.name |
string, 1–256 chars | yes |
user.totpEnabled |
boolean | yes |
user.handle |
any | yes |
user.createdAt |
integer ≥ 0 | yes |
user.emailVerified |
boolean | |
user.canVerifyEmail |
boolean | |
wrappedUserKeys |
base64url | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
POST /api/v1/auth/sso/signup
Section titled “POST /api/v1/auth/sso/signup”auth.sso.signup · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
userId |
uuid | yes |
email |
yes | |
name |
string, 1–256 chars | yes |
authKey |
base64url | yes |
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
wrappedUserKeys |
base64url | yes |
personalVault |
object | yes |
personalVault.id |
uuid | yes |
personalVault.encName |
base64url | yes |
personalVault.wrappedKey |
base64url | yes |
device |
object | yes |
device.id |
uuid | yes |
device.name |
string, 1–256 chars | yes |
device.platform |
string, 1–64 chars | yes |
ssoTicket |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
user |
object | yes |
user.id |
uuid | yes |
user.email |
yes | |
user.name |
string, 1–256 chars | yes |
user.totpEnabled |
boolean | yes |
user.handle |
any | yes |
user.createdAt |
integer ≥ 0 | yes |
user.emailVerified |
boolean | |
user.canVerifyEmail |
boolean |
POST /api/v1/auth/saml/start
Section titled “POST /api/v1/auth/saml/start”auth.saml.start · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
organization |
string, 2–48 chars | yes |
redirectUri |
string, 1–2048 chars | yes |
clientBindingHash |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
authorizationUrl |
string | yes |
teamName |
string | yes |
state |
string | yes |
expiresAt |
integer ≥ 0 | yes |
POST /api/v1/auth/saml/exchange
Section titled “POST /api/v1/auth/saml/exchange”auth.saml.exchange · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
state |
string | yes |
code |
string | yes |
flowSecret |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
ssoTicket |
string | yes |
expiresAt |
integer ≥ 0 | yes |
email |
yes | |
name |
string | yes |
accountExists |
boolean | yes |
kdf |
object or null | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
POST /api/v1/auth/passkey/start
Section titled “POST /api/v1/auth/passkey/start”auth.passkey.start · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
redirectUri |
string, 1–2048 chars | yes |
clientBindingHash |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
ceremonyUrl |
string | yes |
state |
string | yes |
expiresAt |
integer ≥ 0 | yes |
POST /api/v1/auth/passkey/exchange
Section titled “POST /api/v1/auth/passkey/exchange”auth.passkey.exchange · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
state |
string | yes |
code |
string | yes |
flowSecret |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
passkeyTicket |
string | yes |
expiresAt |
integer ≥ 0 | yes |
email |
yes | |
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
GET /api/v1/auth/session
Section titled “GET /api/v1/auth/session”auth.session.get · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
factor |
one of password, totp, recovery, passkey, sso, saml or null |
yes |
scope |
one of full, licence |
yes |
stepUpUntil |
integer ≥ 0 or null | yes |
POST /api/v1/auth/step-up
Section titled “POST /api/v1/auth/step-up”auth.stepUp · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | |
totp |
string | |
recoveryCode |
string | |
passkeyTicket |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
until |
integer ≥ 0 | yes |
POST /api/v1/auth/licence/login
Section titled “POST /api/v1/auth/licence/login”auth.licence.login · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes | |
authKey |
base64url | yes |
totp |
string | |
recoveryCode |
string | |
passkeyTicket |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
userId |
uuid | yes |
email |
yes | |
scope |
"licence" |
yes |
idleTimeoutMs |
integer | yes |
Account
Section titled “Account”GET /api/v1/account
Section titled “GET /api/v1/account”account.get · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
email |
yes | |
name |
string, 1–256 chars | yes |
totpEnabled |
boolean | yes |
handle |
any | yes |
createdAt |
integer ≥ 0 | yes |
emailVerified |
boolean | |
canVerifyEmail |
boolean |
PATCH /api/v1/account
Section titled “PATCH /api/v1/account”account.patch · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
name |
string, 1–256 chars | |
email |
||
handle |
string | |
authKey |
base64url |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
email |
yes | |
name |
string, 1–256 chars | yes |
totpEnabled |
boolean | yes |
handle |
any | yes |
createdAt |
integer ≥ 0 | yes |
emailVerified |
boolean | |
canVerifyEmail |
boolean |
DELETE /api/v1/account
Section titled “DELETE /api/v1/account”account.delete · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
restorableUntil |
integer ≥ 0 | yes |
POST /api/v1/account/email/verify/start
Section titled “POST /api/v1/account/email/verify/start”account.email.verify.start · needs a session token (Authorization: Bearer <token>)
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
expiresAt |
integer ≥ 0 | yes |
POST /api/v1/account/email/verify
Section titled “POST /api/v1/account/email/verify”account.email.verify · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
code |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
email |
yes | |
name |
string, 1–256 chars | yes |
totpEnabled |
boolean | yes |
handle |
any | yes |
createdAt |
integer ≥ 0 | yes |
emailVerified |
boolean | |
canVerifyEmail |
boolean |
POST /api/v1/account/password
Section titled “POST /api/v1/account/password”account.password · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | yes |
newAuthKey |
base64url | yes |
newKdf |
object | yes |
newKdf.alg |
"argon2id13" |
yes |
newKdf.salt |
base64url | yes |
newKdf.opslimit |
integer 1–16 | yes |
newKdf.memlimit |
integer 8388608–1073741824 | yes |
newWrappedUserKeys |
base64url | yes |
personalVaultKeys |
array of object | yes |
personalVaultKeys[].vaultId |
uuid | yes |
personalVaultKeys[].keyVersion |
integer ≥ 0 | yes |
personalVaultKeys[].wrapped |
base64url | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
POST /api/v1/account/reset
Section titled “POST /api/v1/account/reset”account.reset · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
confirm |
"DELETE" |
yes |
currentAuthKey |
base64url | yes |
userId |
uuid | yes |
authKey |
base64url | yes |
kdf |
object | yes |
kdf.alg |
"argon2id13" |
yes |
kdf.salt |
base64url | yes |
kdf.opslimit |
integer 1–16 | yes |
kdf.memlimit |
integer 8388608–1073741824 | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
wrappedUserKeys |
base64url | yes |
personalVault |
object | yes |
personalVault.id |
uuid | yes |
personalVault.encName |
base64url | yes |
personalVault.wrappedKey |
base64url | yes |
Answer 200:
object
POST /api/v1/account/2fa/setup
Section titled “POST /api/v1/account/2fa/setup”account.twoFactor.setup · needs a session token (Authorization: Bearer <token>)
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
secret |
string | yes |
otpauthUrl |
string | yes |
POST /api/v1/account/2fa/enable
Section titled “POST /api/v1/account/2fa/enable”account.twoFactor.enable · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
code |
string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
recoveryCodes |
array of string (≤ 10) | yes |
POST /api/v1/account/2fa/disable
Section titled “POST /api/v1/account/2fa/disable”account.twoFactor.disable · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
code |
string | yes |
Answer 200:
object
POST /api/v1/account/restore
Section titled “POST /api/v1/account/restore”account.restore · needs nothing
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes | |
authKey |
base64url | yes |
Answer 200:
object
GET /api/v1/account/recovery
Section titled “GET /api/v1/account/recovery”account.recovery.get · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
enabled |
boolean | yes |
createdAt |
integer ≥ 0 or null | yes |
PUT /api/v1/account/recovery
Section titled “PUT /api/v1/account/recovery”account.recovery.put · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | yes |
recoveryAuthKey |
base64url | yes |
wrappedKek |
base64url | yes |
Answer 200:
object
DELETE /api/v1/account/recovery
Section titled “DELETE /api/v1/account/recovery”account.recovery.delete · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | yes |
Answer 200:
object
GET /api/v1/account/passkeys
Section titled “GET /api/v1/account/passkeys”account.passkeys.list · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
passkeys |
array of object | yes |
passkeys[].id |
string | yes |
passkeys[].name |
string, 1–64 chars | yes |
passkeys[].createdAt |
integer ≥ 0 | yes |
passkeys[].lastUsedAt |
integer ≥ 0 or null | yes |
passkeys[].synced |
boolean | yes |
passkeys[].backedUp |
boolean | yes |
passkeys[].addedHere |
boolean | yes |
POST /api/v1/account/passkeys/register/start
Section titled “POST /api/v1/account/passkeys/register/start”account.passkeys.register.start · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
redirectUri |
string, 1–2048 chars | yes |
clientBindingHash |
string | yes |
authKey |
base64url | yes |
totp |
string | |
recoveryCode |
string |
Answer 200:
| Field | Type | Always there |
|---|---|---|
ceremonyUrl |
string | yes |
state |
string | yes |
expiresAt |
integer ≥ 0 | yes |
POST /api/v1/account/passkeys/register/finish
Section titled “POST /api/v1/account/passkeys/register/finish”account.passkeys.register.finish · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
state |
string | yes |
code |
string | yes |
flowSecret |
string | yes |
name |
string, 1–64 chars | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
string | yes |
name |
string, 1–64 chars | yes |
createdAt |
integer ≥ 0 | yes |
lastUsedAt |
integer ≥ 0 or null | yes |
synced |
boolean | yes |
backedUp |
boolean | yes |
addedHere |
boolean | yes |
PATCH /api/v1/account/passkeys/{id}
Section titled “PATCH /api/v1/account/passkeys/{id}”account.passkeys.rename · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | string, 1–1024 chars | yes |
Request body:
| Field | Type | Required |
|---|---|---|
name |
string, 1–64 chars | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
string | yes |
name |
string, 1–64 chars | yes |
createdAt |
integer ≥ 0 | yes |
lastUsedAt |
integer ≥ 0 or null | yes |
synced |
boolean | yes |
backedUp |
boolean | yes |
addedHere |
boolean | yes |
DELETE /api/v1/account/passkeys/{id}
Section titled “DELETE /api/v1/account/passkeys/{id}”account.passkeys.delete · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | string, 1–1024 chars | yes |
Request body:
| Field | Type | Required |
|---|---|---|
authKey |
base64url | yes |
totp |
string | |
recoveryCode |
string |
Answer 200:
object
Devices and the key directory
Section titled “Devices and the key directory”GET /api/v1/devices
Section titled “GET /api/v1/devices”devices.list · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string | yes |
platform |
string | yes |
lastSeenAt |
integer ≥ 0 | yes |
current |
boolean | yes |
appVersion |
any |
DELETE /api/v1/devices/{id}
Section titled “DELETE /api/v1/devices/{id}”devices.revoke · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
object
PUT /api/v1/devices/current/ssh-keys
Section titled “PUT /api/v1/devices/current/ssh-keys”devices.currentSshKeys.put · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
publicKeys |
array of string | yes |
authKey |
base64url |
Answer 200:
object
GET /api/v1/k/{handle}
Section titled “GET /api/v1/k/{handle}”devices.handleKeys.get · needs nothing
| Parameter | In | Type | Required |
|---|---|---|---|
handle |
path | string, 3–32 chars | yes |
Answer 200:
string
GET /api/v1/users/{id}/keys
Section titled “GET /api/v1/users/{id}/keys”users.keys.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
userId |
uuid | yes |
boxPk |
base64url | yes |
signPk |
base64url | yes |
Vaults
Section titled “Vaults”GET /api/v1/vaults
Section titled “GET /api/v1/vaults”vaults.list · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
kind |
one of personal, team |
yes |
teamId |
uuid or null | yes |
encName |
base64url | yes |
keyVersion |
integer ≥ 0 | yes |
permission |
one of owner, edit, view |
yes |
loggingEnabled |
boolean | yes |
rotationRequired |
boolean | yes |
recordSessions |
boolean | |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
POST /api/v1/vaults
Section titled “POST /api/v1/vaults”vaults.create · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
id |
uuid | yes |
teamId |
uuid | yes |
encName |
base64url | yes |
keys |
array of object | yes |
keys[].userId |
uuid | yes |
keys[].keyVersion |
1 |
yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
kind |
one of personal, team |
yes |
teamId |
uuid or null | yes |
encName |
base64url | yes |
keyVersion |
integer ≥ 0 | yes |
permission |
one of owner, edit, view |
yes |
loggingEnabled |
boolean | yes |
rotationRequired |
boolean | yes |
recordSessions |
boolean | |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
PATCH /api/v1/vaults/{id}
Section titled “PATCH /api/v1/vaults/{id}”vaults.update · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
encName |
base64url | |
loggingEnabled |
boolean |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
kind |
one of personal, team |
yes |
teamId |
uuid or null | yes |
encName |
base64url | yes |
keyVersion |
integer ≥ 0 | yes |
permission |
one of owner, edit, view |
yes |
loggingEnabled |
boolean | yes |
rotationRequired |
boolean | yes |
recordSessions |
boolean | |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
DELETE /api/v1/vaults/{id}
Section titled “DELETE /api/v1/vaults/{id}”vaults.delete · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
purgeAfter |
integer ≥ 0 |
GET /api/v1/vaults/{id}/members
Section titled “GET /api/v1/vaults/{id}/members”vaults.members.list · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
userId |
uuid | yes |
email |
yes | |
name |
string | yes |
permission |
one of edit, view |
yes |
expiresAt |
integer ≥ -9007199254740991 or null |
PUT /api/v1/vaults/{id}/members/{userId}
Section titled “PUT /api/v1/vaults/{id}/members/{userId}”vaults.members.grant · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
userId |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
permission |
one of edit, view |
yes |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null | |
expiresAt |
integer ≤ 4102444800000 |
Answer 200:
object
DELETE /api/v1/vaults/{id}/members/{userId}
Section titled “DELETE /api/v1/vaults/{id}/members/{userId}”vaults.members.revoke · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
userId |
path | uuid | yes |
Answer 200:
object
POST /api/v1/vaults/{id}/restore
Section titled “POST /api/v1/vaults/{id}/restore”vaults.restore · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
kind |
one of personal, team |
yes |
teamId |
uuid or null | yes |
encName |
base64url | yes |
keyVersion |
integer ≥ 0 | yes |
permission |
one of owner, edit, view |
yes |
loggingEnabled |
boolean | yes |
rotationRequired |
boolean | yes |
recordSessions |
boolean | |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
POST /api/v1/vaults/{id}/rotate
Section titled “POST /api/v1/vaults/{id}/rotate”vaults.rotate · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
newKeyVersion |
integer | yes |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null | |
keys[].userId |
uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
kind |
one of personal, team |
yes |
teamId |
uuid or null | yes |
encName |
base64url | yes |
keyVersion |
integer ≥ 0 | yes |
permission |
one of owner, edit, view |
yes |
loggingEnabled |
boolean | yes |
rotationRequired |
boolean | yes |
recordSessions |
boolean | |
keys |
array of object | yes |
keys[].keyVersion |
integer ≥ 0 | yes |
keys[].wrapped |
base64url | yes |
keys[].senderUserId |
uuid or null | |
keys[].signature |
base64url or null |
POST /api/v1/sync/push
Section titled “POST /api/v1/sync/push”sync.push · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
idempotencyKey |
uuid | yes |
changes |
array of object (≤ 500) | yes |
changes[].id |
uuid | yes |
changes[].vaultId |
uuid | yes |
changes[].type |
one of 16 values | yes |
changes[].baseRevision |
decimal string | yes |
changes[].keyVersion |
integer ≥ 0 | yes |
changes[].deleted |
boolean | yes |
changes[].data |
base64url, ≤ 349526 chars or null | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
results |
array of object | yes |
results[].id |
uuid | yes |
results[].status |
one of ok, conflict |
yes |
results[].revision |
decimal string | yes |
results[].server |
object | |
results[].server.id |
uuid | yes |
results[].server.vaultId |
uuid | yes |
results[].server.type |
one of 17 values or string | yes |
results[].server.revision |
decimal string | yes |
results[].server.keyVersion |
integer ≥ 0 | yes |
results[].server.deleted |
boolean | yes |
results[].server.data |
base64url or null | yes |
results[].server.updatedAt |
integer ≥ 0 | yes |
POST /api/v1/sync/pull
Section titled “POST /api/v1/sync/pull”sync.pull · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
cursors |
object (any keys) | yes |
limit |
integer ≤ 1000 |
Answer 200:
| Field | Type | Always there |
|---|---|---|
items |
array of object | yes |
items[].id |
uuid | yes |
items[].vaultId |
uuid | yes |
items[].type |
one of 17 values or string | yes |
items[].revision |
decimal string | yes |
items[].keyVersion |
integer ≥ 0 | yes |
items[].deleted |
boolean | yes |
items[].data |
base64url or null | yes |
items[].updatedAt |
integer ≥ 0 | yes |
cursors |
object (any keys) | yes |
hasMore |
boolean | yes |
Session logs
Section titled “Session logs”PUT /api/v1/vaults/{id}/logs/{logId}/chunks/{idx}
Section titled “PUT /api/v1/vaults/{id}/logs/{logId}/chunks/{idx}”logs.chunks.put · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
logId |
path | uuid | yes |
idx |
path | integer ≥ 0 | yes |
Request body:
| Field | Type | Required |
|---|---|---|
keyVersion |
integer ≥ 0 | yes |
data |
base64url | yes |
Answer 200:
object
GET /api/v1/vaults/{id}/logs/{logId}/chunks/{idx}
Section titled “GET /api/v1/vaults/{id}/logs/{logId}/chunks/{idx}”logs.chunks.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
logId |
path | uuid | yes |
idx |
path | integer ≥ 0 | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
keyVersion |
integer ≥ 0 | yes |
data |
base64url | yes |
DELETE /api/v1/vaults/{id}/logs/{logId}
Section titled “DELETE /api/v1/vaults/{id}/logs/{logId}”logs.delete · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
logId |
path | uuid | yes |
Answer 200:
object
POST /api/v1/teams
Section titled “POST /api/v1/teams”teams.create · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
name |
string, 1–256 chars | yes |
vault |
object | yes |
vault.id |
uuid | yes |
vault.encName |
base64url | yes |
vault.keys |
array of object | yes |
vault.keys[].userId |
uuid | yes |
vault.keys[].keyVersion |
1 |
yes |
vault.keys[].wrapped |
base64url | yes |
vault.keys[].senderUserId |
uuid or null | |
vault.keys[].signature |
base64url or null |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
GET /api/v1/teams
Section titled “GET /api/v1/teams”teams.list · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
GET /api/v1/teams/{id}
Section titled “GET /api/v1/teams/{id}”teams.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
PATCH /api/v1/teams/{id}
Section titled “PATCH /api/v1/teams/{id}”teams.update · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
name |
string, 1–256 chars | |
require2fa |
boolean | |
recordSessions |
boolean |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
DELETE /api/v1/teams/{id}
Section titled “DELETE /api/v1/teams/{id}”teams.delete · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
name |
string, 1–256 chars | yes |
Answer 200:
object
GET /api/v1/teams/deleted
Section titled “GET /api/v1/teams/deleted”teams.deleted · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
teams |
array of object | yes |
teams[].id |
uuid | yes |
teams[].name |
string | yes |
teams[].deletedAt |
integer ≥ 0 | yes |
teams[].byYou |
boolean | yes |
POST /api/v1/teams/{id}/invites
Section titled “POST /api/v1/teams/{id}/invites”teams.invites.create · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
email |
yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
token |
string | yes |
link |
string | yes |
expiresAt |
integer ≥ 0 | yes |
DELETE /api/v1/teams/{id}/members/{userId}
Section titled “DELETE /api/v1/teams/{id}/members/{userId}”teams.members.remove · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
userId |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
mode |
one of convert, delete |
yes |
Answer 200:
object
POST /api/v1/teams/{id}/transfer
Section titled “POST /api/v1/teams/{id}/transfer”teams.transfer · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
toUserId |
uuid | yes |
leaveAfterTransfer |
boolean |
Answer 200:
object
DELETE /api/v1/teams/{id}/transfer
Section titled “DELETE /api/v1/teams/{id}/transfer”teams.transfer.cancel · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
POST /api/v1/teams/{id}/transfer/decline
Section titled “POST /api/v1/teams/{id}/transfer/decline”teams.transfer.decline · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
object
POST /api/v1/teams/{id}/transfer/accept
Section titled “POST /api/v1/teams/{id}/transfer/accept”teams.transfer.accept · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
GET /api/v1/teams/{id}/statements
Section titled “GET /api/v1/teams/{id}/statements”teams.statements.list · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
after |
query | integer ≥ 0 | |
pageBytes |
query | integer 1024–1048576 | |
patches |
query | boolean | |
full |
query | boolean | |
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
statements |
array of object | yes |
statements[].epoch |
integer | yes |
statements[].signerId |
uuid | yes |
statements[].body |
base64url, ≤ 699051 chars | |
statements[].patch |
base64url, ≤ 699115 chars | |
statements[].signature |
base64url, ≤ 256 chars | yes |
anchor |
object | |
anchor.epoch |
integer | yes |
anchor.signerId |
uuid | yes |
anchor.body |
base64url, ≤ 699051 chars | yes |
anchor.signature |
base64url, ≤ 256 chars | yes |
more |
boolean |
POST /api/v1/teams/{id}/statements
Section titled “POST /api/v1/teams/{id}/statements”teams.statements.post · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
epoch |
integer | yes |
signerId |
uuid | yes |
body |
base64url, ≤ 699051 chars | yes |
signature |
base64url, ≤ 256 chars | yes |
Answer 200:
object
GET /api/v1/teams/{id}/keys
Section titled “GET /api/v1/teams/{id}/keys”teams.keys.list · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
after |
query | uuid | |
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
keys |
array of object (≤ 200) | yes |
keys[].userId |
uuid | yes |
keys[].boxPk |
base64url | yes |
keys[].signPk |
base64url | yes |
more |
boolean | yes |
GET /api/v1/teams/{id}/audit
Section titled “GET /api/v1/teams/{id}/audit”teams.audit.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
before |
query | string | |
limit |
query | integer ≤ 500 | |
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
events |
array of object | yes |
events[].id |
string | yes |
events[].teamId |
uuid or null | yes |
events[].userId |
uuid or null | yes |
events[].actorId |
uuid | yes |
events[].type |
string | yes |
events[].meta |
any | yes |
events[].at |
integer ≥ 0 | yes |
GET /api/v1/teams/{id}/audit/export
Section titled “GET /api/v1/teams/{id}/audit/export”teams.audit.export · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
format |
query | one of csv, ndjson |
|
from |
query | integer 0–8640000000000000 | |
to |
query | integer 0–8640000000000000 | |
types |
query | string, ≤ 2000 chars | |
id |
path | uuid | yes |
Answer 200:
string
GET /api/v1/teams/{id}/digest
Section titled “GET /api/v1/teams/{id}/digest”teams.digest.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
frequency |
one of off, daily, weekly |
yes |
lastSentAt |
integer ≥ 0 or null | yes |
PUT /api/v1/teams/{id}/digest
Section titled “PUT /api/v1/teams/{id}/digest”teams.digest.put · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
frequency |
one of off, daily, weekly |
yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
frequency |
one of off, daily, weekly |
yes |
lastSentAt |
integer ≥ 0 or null | yes |
GET /api/v1/teams/{id}/saml
Section titled “GET /api/v1/teams/{id}/saml”teams.saml.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
serviceProvider |
object | yes |
serviceProvider.entityId |
string | yes |
serviceProvider.acsUrl |
string | yes |
serviceProvider.metadataUrl |
string | yes |
config |
object or null | yes |
config.organization |
string, 2–48 chars | yes |
config.idpEntityId |
string | yes |
config.idpSsoUrl |
string | yes |
config.idpCerts |
array of string (≤ 2) | yes |
config.metadataUrl |
any | yes |
config.emailAttribute |
string, 1–512 chars or null | yes |
config.nameAttribute |
string, 1–512 chars or null | yes |
config.requireSso |
boolean | yes |
config.certFingerprints |
array of string | yes |
config.updatedAt |
integer ≥ 0 | yes |
PUT /api/v1/teams/{id}/saml
Section titled “PUT /api/v1/teams/{id}/saml”teams.saml.put · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
organization |
string, 2–48 chars | yes |
metadataXml |
string, 1–524288 chars | |
metadataUrl |
uri, ≤ 2048 chars or null | |
idpEntityId |
string, 1–1024 chars | |
idpSsoUrl |
uri, ≤ 2048 chars | |
idpCerts |
array of string, 1–16384 chars (≤ 2) | |
emailAttribute |
string, 1–512 chars or null | |
nameAttribute |
string, 1–512 chars or null | |
requireSso |
boolean | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
serviceProvider |
object | yes |
serviceProvider.entityId |
string | yes |
serviceProvider.acsUrl |
string | yes |
serviceProvider.metadataUrl |
string | yes |
config |
object or null | yes |
config.organization |
string, 2–48 chars | yes |
config.idpEntityId |
string | yes |
config.idpSsoUrl |
string | yes |
config.idpCerts |
array of string (≤ 2) | yes |
config.metadataUrl |
any | yes |
config.emailAttribute |
string, 1–512 chars or null | yes |
config.nameAttribute |
string, 1–512 chars or null | yes |
config.requireSso |
boolean | yes |
config.certFingerprints |
array of string | yes |
config.updatedAt |
integer ≥ 0 | yes |
DELETE /api/v1/teams/{id}/saml
Section titled “DELETE /api/v1/teams/{id}/saml”teams.saml.delete · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
serviceProvider |
object | yes |
serviceProvider.entityId |
string | yes |
serviceProvider.acsUrl |
string | yes |
serviceProvider.metadataUrl |
string | yes |
config |
object or null | yes |
config.organization |
string, 2–48 chars | yes |
config.idpEntityId |
string | yes |
config.idpSsoUrl |
string | yes |
config.idpCerts |
array of string (≤ 2) | yes |
config.metadataUrl |
any | yes |
config.emailAttribute |
string, 1–512 chars or null | yes |
config.nameAttribute |
string, 1–512 chars or null | yes |
config.requireSso |
boolean | yes |
config.certFingerprints |
array of string | yes |
config.updatedAt |
integer ≥ 0 | yes |
GET /api/v1/teams/{id}/chain
Section titled “GET /api/v1/teams/{id}/chain”teams.chain.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
statementVersion |
integer ≥ 0 | yes |
latestEpoch |
integer ≥ 0 | yes |
anchorEpoch |
integer ≥ 0 | yes |
bodyBytes |
integer ≥ 0 | yes |
signingCap |
integer ≥ 0 | yes |
reserveBytes |
integer ≥ 0 | yes |
decoderCap |
integer ≥ 0 | yes |
tail |
object | yes |
tail.statements |
integer ≥ 0 | yes |
tail.patchBytes |
integer ≥ 0 | yes |
tail.rebuiltBytes |
integer ≥ 0 | yes |
tail.maxStatements |
integer ≥ 0 | yes |
tail.maxPatchBytes |
integer ≥ 0 | yes |
tail.maxRebuiltBytes |
integer ≥ 0 | yes |
band |
object | yes |
band.statements |
integer ≥ 0 | yes |
band.patchBytes |
integer ≥ 0 | yes |
band.rebuiltBytes |
integer ≥ 0 | yes |
band.maxStatements |
integer ≥ 0 | yes |
band.maxPatchBytes |
integer ≥ 0 | yes |
band.maxRebuiltBytes |
integer ≥ 0 | yes |
shareApplies |
boolean | yes |
signers |
array of object | yes |
signers[].userId |
uuid | yes |
signers[].tailStatements |
integer ≥ 0 | yes |
signers[].bandStatements |
integer ≥ 0 | yes |
signers[].grownBytes |
integer ≥ -9007199254740991 | yes |
today |
array of object | yes |
today[].userId |
uuid | yes |
today[].tombstones |
integer ≥ 0 | yes |
today[].vaultCreations |
integer ≥ 0 | yes |
today[].vaultDeletions |
integer ≥ 0 | yes |
ownerPriorityUntil |
integer ≥ 0 or null | yes |
server |
object | yes |
server.knownAuthz |
array of integer | yes |
server.knownCatalogues |
array of integer | yes |
server.knownAppVersion |
string, ≤ 64 chars | yes |
server.delegatedSigning |
boolean | yes |
POST /api/v1/teams/{id}/proposals
Section titled “POST /api/v1/teams/{id}/proposals”teams.proposals.post · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
body |
base64url, ≤ 43691 chars | yes |
signature |
base64url, ≤ 256 chars | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
proposalId |
string | yes |
GET /api/v1/teams/{id}/proposals
Section titled “GET /api/v1/teams/{id}/proposals”teams.proposals.list · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
proposals |
array of object | yes |
proposals[].body |
base64url, ≤ 43691 chars | yes |
proposals[].signature |
base64url, ≤ 256 chars | yes |
proposals[].proposalId |
string | yes |
proposals[].proposer |
uuid | yes |
proposals[].receivedAt |
integer ≥ 0 | yes |
POST /api/v1/teams/{id}/proposals/{proposalId}/resolve
Section titled “POST /api/v1/teams/{id}/proposals/{proposalId}/resolve”teams.proposals.resolve · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
proposalId |
path | string | yes |
Request body:
| Field | Type | Required |
|---|---|---|
outcome |
one of accepted, declined |
yes |
epoch |
integer |
Answer 200:
object
POST /api/v1/teams/{id}/attestations
Section titled “POST /api/v1/teams/{id}/attestations”teams.attestations.post · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
body |
base64url, ≤ 5462 chars | yes |
signature |
base64url, ≤ 256 chars | yes |
Answer 200:
object
GET /api/v1/teams/{id}/attestations
Section titled “GET /api/v1/teams/{id}/attestations”teams.attestations.list · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
attestations |
array of object | yes |
attestations[].userId |
uuid | yes |
attestations[].deviceId |
string, 1–128 chars | yes |
attestations[].body |
base64url, ≤ 5462 chars | yes |
attestations[].signature |
base64url, ≤ 256 chars | yes |
attestations[].receivedAt |
integer ≥ 0 | yes |
GET /api/v1/teams/{id}/report-data
Section titled “GET /api/v1/teams/{id}/report-data”teams.reportData.get · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
generatedAt |
integer ≥ 0 | yes |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].totpEnabled |
boolean | yes |
members[].passkeys |
integer ≥ 0 | yes |
members[].signInFactor |
one of password, totp, recovery, passkey, sso, saml or null |
yes |
devices |
array of object | yes |
devices[].userId |
uuid | yes |
devices[].deviceId |
uuid | yes |
devices[].name |
string | yes |
devices[].platform |
string | yes |
devices[].appVersion |
any | yes |
devices[].lastSeenAt |
integer ≥ 0 | yes |
access |
array of object | yes |
access[].vaultId |
uuid | yes |
access[].userId |
uuid | yes |
access[].permission |
one of edit, view |
yes |
access[].expiresAt |
integer ≥ 0 or null | yes |
statements |
array of object | yes |
statements[].epoch |
integer | yes |
statements[].signerId |
uuid | yes |
statements[].receivedAt |
integer ≥ 0 | yes |
statements[].bytes |
integer ≥ 0 | yes |
audit |
array of object | yes |
audit[].type |
string, ≤ 64 chars | yes |
audit[].count |
integer ≥ 0 | yes |
audit[].lastAt |
integer ≥ 0 | yes |
auditSince |
integer ≥ 0 | yes |
historyPrunedBefore |
integer ≥ 0 or null | yes |
POST /api/v1/teams/{id}/reports/exported
Section titled “POST /api/v1/teams/{id}/reports/exported”teams.reports.exported · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Request body:
| Field | Type | Required |
|---|---|---|
report |
string, 1–64 chars | yes |
format |
one of csv, pdf |
yes |
Answer 200:
object
GET /api/v1/teams/{id}/vaults/deleted
Section titled “GET /api/v1/teams/{id}/vaults/deleted”teams.vaults.deleted · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
id |
path | uuid | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
vaults |
array of object | yes |
vaults[].vaultId |
uuid | yes |
vaults[].encName |
base64url | yes |
vaults[].keyVersion |
integer ≥ 0 | yes |
vaults[].deletedBy |
uuid | yes |
vaults[].deletedAt |
integer ≥ 0 | yes |
vaults[].purgeAfter |
integer ≥ 0 | yes |
Invites
Section titled “Invites”POST /api/v1/invites/{token}/accept
Section titled “POST /api/v1/invites/{token}/accept”invites.accept · needs a session token (Authorization: Bearer <token>)
| Parameter | In | Type | Required |
|---|---|---|---|
token |
path | string | yes |
Answer 200:
| Field | Type | Always there |
|---|---|---|
id |
uuid | yes |
name |
string, 1–256 chars | yes |
ownerId |
uuid | yes |
pendingOwnerId |
uuid or null | yes |
pendingOwnerLeaves |
boolean | |
require2fa |
boolean | yes |
recordSessions |
boolean | |
members |
array of object | yes |
members[].userId |
uuid | yes |
members[].email |
yes | |
members[].name |
string | yes |
members[].role |
one of owner, member |
yes |
members[].totpEnabled |
boolean | yes |
members[].handle |
any | |
members[].emailVerified |
boolean | |
statementVersion |
integer ≥ 0 | |
plan |
one of free, pro, team, business, enterprise |
|
entitlements |
array of string, ≤ 128 chars |
POST /api/v1/ai/complete
Section titled “POST /api/v1/ai/complete”ai.complete · needs a session token (Authorization: Bearer <token>)
Request body:
| Field | Type | Required |
|---|---|---|
kind |
one of command, snippet, ask |
yes |
prompt |
string, 1–8192 chars | yes |
context |
string, ≤ 8192 chars | |
os |
string, ≤ 64 chars | |
shell |
string, ≤ 64 chars |
Answer 200:
| Field | Type | Always there |
|---|---|---|
text |
string | yes |
truncated |
boolean |
Licence
Section titled “Licence”GET /api/v1/licence
Section titled “GET /api/v1/licence”licence.get · needs a session token (Authorization: Bearer <token>)
Answer 200:
| Field | Type | Always there |
|---|---|---|
mode |
one of hosted, selfHosted |
yes |
state |
one of none, valid, expiring, grace, expired, invalid |
yes |
problem |
one of expiry, origin, notYetValid, signature or null |
yes |
licenceId |
string, ≤ 128 chars or null | yes |
customerUserId |
string, ≤ 128 chars or null | yes |
tier |
string, ≤ 64 chars or null | yes |
addOns |
array of string, ≤ 128 chars | yes |
seats |
integer or null | yes |
seatsUsed |
integer ≥ 0 | yes |
overageSince |
integer ≥ 0 or null | yes |
notBefore |
integer ≥ 0 or null | yes |
expiresAt |
integer ≥ 0 or null | yes |
graceUntil |
integer ≥ 0 or null | yes |
origins |
array of string, ≤ 300 chars | yes |
publicUrl |
string, ≤ 2048 chars or null | yes |
entitlements |
array of string, ≤ 128 chars | yes |
checkedAt |
integer ≥ 0 | yes |
Licence portal
Section titled “Licence portal”POST /api/v1/portal/ticket
Section titled “POST /api/v1/portal/ticket”portal.ticket · needs a session token (Authorization: Bearer <token>)
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
ticket |
string, 1–4096 chars | yes |
portalUrl |
uri | yes |
expiresAt |
integer ≥ 0 | yes |
Realtime
Section titled “Realtime”POST /api/v1/ws/ticket
Section titled “POST /api/v1/ws/ticket”ws.ticket · needs a session token (Authorization: Bearer <token>)
Request body:
object
Answer 200:
| Field | Type | Always there |
|---|---|---|
ticket |
string | yes |
expiresAt |
integer ≥ -9007199254740991 | yes |
© 2026 IRONPINE LABS LLC
ALL RIGHTS RESERVED.