Accounts and sign-in
Close the account and schedule its deletion
Section titled “Close the account and schedule its deletion”POST /api/v1/auth/account/delete
Closes the account and signs it out. It needs the password. The account and its data are removed when the grace period ends (deleteAfter in the response); until then, the link mailed to the account (when the node can send mail) keeps it. The owner’s account cannot be closed: transfer ownership first.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
password |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
deleteAfter |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/account/delete" \ -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -H "Content-Type: application/json" \ -d '{"password": "..."}'Cancel a scheduled deletion
Section titled “Cancel a scheduled deletion”POST /api/v1/auth/account/keep
Cancels a scheduled deletion, from the link mailed when the account was closed.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/account/keep" \ -H "Content-Type: application/json" \ -d '{"token": "..."}'App password grant (off unless CLOUDOAK_APP_PASSWORD_LOGIN=on)
Section titled “App password grant (off unless CLOUDOAK_APP_PASSWORD_LOGIN=on)”POST /api/v1/auth/app/login
An app signs a user in with email and password and gets a token pair. Off unless the node’s admin turns it on (CLOUDOAK_APP_PASSWORD_LOGIN=on): apps normally sign users in on the node’s own page (/oauth/authorize), so the password never reaches the app.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
app_id |
string | yes | |
code_challenge |
string | no | |
device_label |
string | no | |
email |
string | yes | |
password |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
access_token |
string | yes | |
expires_in |
integer | yes | |
refresh_token |
string | yes | |
token_type |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/app/login" \ -H "Content-Type: application/json" \ -d '{"app_id": "...", "email": "...", "password": "..."}'Revoke an app refresh family
Section titled “Revoke an app refresh family”POST /api/v1/auth/app/logout
Revokes a refresh token’s family: the app is signed out on that device.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
refresh_token |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/app/logout" \ -H "Content-Type: application/json" \ -d '{"refresh_token": "..."}'Rotate an app refresh token
Section titled “Rotate an app refresh token”POST /api/v1/auth/app/refresh
Swaps an app’s refresh token for a new pair. Each refresh token works once; reusing one revokes its whole family.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
refresh_token |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
access_token |
string | yes | |
expires_in |
integer | yes | |
refresh_token |
string | yes | |
token_type |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/app/refresh" \ -H "Content-Type: application/json" \ -d '{"refresh_token": "..."}'Public auth configuration
Section titled “Public auth configuration”GET /api/v1/auth/config
What the sign-in pages need before anyone signs in: the node’s name and edition, its registration policy, whether it can send mail, and its billing mode.
Who may call it: None: anyone may call it.
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
billingMode |
string | yes | |
edition |
string | yes | |
mail |
boolean | yes | |
nodeName |
string | yes | |
registration |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X GET "https://node.example.com/api/v1/auth/config"Ask to change the account’s email address
Section titled “Ask to change the account’s email address”POST /api/v1/auth/email/change
Starts a change of the account’s address. It needs the current password, and mails a confirmation link to the new address; nothing changes until that link is used.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
newEmail |
string | yes | |
password |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/email/change" \ -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -H "Content-Type: application/json" \ -d '{"newEmail": "...", "password": "..."}'Confirm a new email address
Section titled “Confirm a new email address”POST /api/v1/auth/email/change/confirm
Finishes an address change from the link mailed to the new address.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/email/change/confirm" \ -H "Content-Type: application/json" \ -d '{"token": "..."}'Confirm a new account’s address
Section titled “Confirm a new account’s address”POST /api/v1/auth/email/verify
Confirms a new account’s address from the link mailed to it.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/email/verify" \ -H "Content-Type: application/json" \ -d '{"token": "..."}'Send the confirmation link again
Section titled “Send the confirmation link again”POST /api/v1/auth/email/verify/resend
Mails the confirmation link again. It answers the same whether or not the address has an account waiting.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/email/verify/resend" \ -H "Content-Type: application/json" \ -d '{"email": "..."}'Accept an invitation
Section titled “Accept an invitation”POST /api/v1/auth/invitations/accept
Creates the account an admin invited, from the invitation’s token, and signs it in.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | yes | |
password |
string | yes | |
token |
string | yes | |
username |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
csrfToken |
string | yes | |
user |
object | yes | |
user.createdAt |
string | yes | |
user.email |
string | yes | |
user.id |
string | yes | |
user.name |
string | yes | |
user.role |
string | yes | |
user.status |
string | yes | |
user.username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/invitations/accept" \ -H "Content-Type: application/json" \ -d '{"token": "...", "username": "...", "name": "...", "password": "..."}'What an invitation link is for
Section titled “What an invitation link is for”POST /api/v1/auth/invitations/inspect
What an invitation’s token is for (the node, the address, the role, who invited it and when the invitation expires), so the page can show it before the account is created.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
token |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes | |
expiresAt |
string | yes | |
invitedBy |
string | yes | |
node |
string | yes | |
role |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/invitations/inspect" \ -H "Content-Type: application/json" \ -d '{"token": "..."}'Sign in with email and password
Section titled “Sign in with email and password”POST /api/v1/auth/login
Signs in to the console with email and password and sets the session cookie. Every later write in that session sends the CSRF token from the response as X-CSRF-Token. Attempts are rate limited.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes | |
password |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
csrfToken |
string | yes | |
user |
object | yes | |
user.createdAt |
string | yes | |
user.email |
string | yes | |
user.id |
string | yes | |
user.name |
string | yes | |
user.role |
string | yes | |
user.status |
string | yes | |
user.username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/login" \ -H "Content-Type: application/json" \ -d '{"email": "...", "password": "..."}'Sign out this session
Section titled “Sign out this session”POST /api/v1/auth/logout
Ends this console session and clears its cookie.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/logout" \ -b cookies.txt -H "X-CSRF-Token: $CSRF"Current account
Section titled “Current account”GET /api/v1/auth/me
The signed-in account: id, email, username, display name and role.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
csrfToken |
string | yes | |
user |
object | yes | |
user.createdAt |
string | yes | |
user.email |
string | yes | |
user.id |
string | yes | |
user.name |
string | yes | |
user.role |
string | yes | |
user.status |
string | yes | |
user.username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X GET "https://node.example.com/api/v1/auth/me" \ -b cookies.txtUpdate username and display name
Section titled “Update username and display name”PATCH /api/v1/auth/me
Changes the username, the display name, or both. A field left out keeps its value.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
name |
string | no | |
username |
string | no |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
csrfToken |
string | yes | |
user |
object | yes | |
user.createdAt |
string | yes | |
user.email |
string | yes | |
user.id |
string | yes | |
user.name |
string | yes | |
user.role |
string | yes | |
user.status |
string | yes | |
user.username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X PATCH "https://node.example.com/api/v1/auth/me" \ -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -H "Content-Type: application/json" \ -d '{}'Admins the owner can hand the node to
Section titled “Admins the owner can hand the node to”GET /api/v1/auth/owner/candidates
The admins the node’s owner can hand the node to. Only the owner may call it.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
candidates |
array of object | yes | |
candidates[].id |
string | yes | |
candidates[].name |
string | yes | |
candidates[].username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X GET "https://node.example.com/api/v1/auth/owner/candidates" \ -b cookies.txtTransfer ownership of the node to an admin
Section titled “Transfer ownership of the node to an admin”POST /api/v1/auth/owner/transfer
Makes another admin the node’s owner. Only the owner may call it, with their password.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
password |
string | yes | |
userId |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/owner/transfer" \ -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -H "Content-Type: application/json" \ -d '{"userId": "...", "password": "..."}'Confirm a password reset
Section titled “Confirm a password reset”POST /api/v1/auth/password-reset/confirm
Sets a new password from a reset link’s token, which works once. Everything that could act as the account ends: console sessions, API tokens and apps’ sign-ins.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
newPassword |
string | yes | |
token |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/password-reset/confirm" \ -H "Content-Type: application/json" \ -d '{"token": "...", "newPassword": "..."}'Request a password reset
Section titled “Request a password reset”POST /api/v1/auth/password-reset/request
Mails a password-reset link to the address, if an account has it. It answers the same either way, so it does not reveal which addresses have accounts. A node that cannot send mail answers 503: there, an admin resets passwords.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/password-reset/request" \ -H "Content-Type: application/json" \ -d '{"email": "..."}'Change the current password
Section titled “Change the current password”POST /api/v1/auth/password/change
Changes the password. It needs the current one. Everything else that could act as the account ends (other console sessions, API tokens, apps’ sign-ins); this session stays signed in.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
current |
string | yes | |
new |
string | yes |
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/password/change" \ -b cookies.txt -H "X-CSRF-Token: $CSRF" \ -H "Content-Type: application/json" \ -d '{"current": "...", "new": "..."}'Register an account (policy permitting)
Section titled “Register an account (policy permitting)”POST /api/v1/auth/register
Creates an account, when the node’s registration policy allows it: open lets anyone register, allowlist only the addresses an admin listed, and closed nobody. A new account may have to confirm its address before it can sign in.
Who may call it: None: anyone may call it.
Request body (JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
email |
string | yes | |
name |
string | yes | |
password |
string | yes | |
username |
string | yes |
Response (200, JSON):
| Field | Type | Required | Notes |
|---|---|---|---|
csrfToken |
string | yes | |
user |
object | yes | |
user.createdAt |
string | yes | |
user.email |
string | yes | |
user.id |
string | yes | |
user.name |
string | yes | |
user.role |
string | yes | |
user.status |
string | yes | |
user.username |
string | yes |
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X POST "https://node.example.com/api/v1/auth/register" \ -H "Content-Type: application/json" \ -d '{"email": "...", "username": "...", "name": "...", "password": "..."}'Sign out everywhere
Section titled “Sign out everywhere”DELETE /api/v1/auth/sessions
Ends everything that can act as the account: every console session (this one included), every API token, and every app’s sign-in on every device. Apps’ access tokens stop working on their next request.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X DELETE "https://node.example.com/api/v1/auth/sessions" \ -b cookies.txt -H "X-CSRF-Token: $CSRF"Export everything the account owns in one app (JSON lines)
Section titled “Export everything the account owns in one app (JSON lines)”GET /api/v1/me/export/{appId}
Everything the signed-in account owns in one app, as JSON lines: a header, a line for each row, and a line for each file with a download link. It is what a user takes with them, for example before closing their account.
Who may call it: The console session (its cookie, and X-CSRF-Token on writes).
Path parameters: appId.
Response: no body on success.
Errors: 400, 401, 403, 404, 429, as described in errors.
curl -X GET "https://node.example.com/api/v1/me/export/{appId}" \ -b cookies.txtBuilt from spec 2.1.0, SDK 2.0.0 and the node's guide at v0.6.0-alpha.1.