The user's own account
Let a signed-in user change their name and password, confirm or change their email address, and delete their account.
These routes act on the caller's own account, taken from the session, never from the request body. Every user holds them by default, through the Manage my own account and Delete my own account capabilities in the seeded Org Member Baseline.
| Method | Path | Does |
|---|---|---|
GET | /{appUid}/auth/me | Who the session belongs to, checked against the live session |
PATCH | /{appUid}/auth/me | Change the name: { "fname", "lname" } |
POST | /{appUid}/auth/password | Change the password: { "currentPassword", "newPassword" } |
POST | /{appUid}/auth/verify-email/request | Send the "confirm your email" link again: { "redirectTo"? } |
POST | /{appUid}/auth/verify-email/confirm | Confirm the address: { "token" }. No session needed. |
POST | /{appUid}/auth/reverify | Prove it is still you; answers a single-use receipt |
POST | /{appUid}/auth/reverify/email-code | Email a code to prove it with |
POST | /{appUid}/auth/email | Ask to move the account to a new address: { "newEmail", "reverifyToken", "redirectTo"? } |
POST | /{appUid}/auth/email/confirm | Finish the move: { "token" }. No session needed. |
DELETE | /{appUid}/auth/me | Delete the account: { "reverifyToken" } |
The client SDK wraps each of them.
Who is signed in
GET /{appUid}/auth/me answers the account and the session's active organization:
{
"user": {
"uid": "0199a3c2-5b1e-7c4d-9f2a-3e8b6d1c0a47",
"email": "dana@example.com",
"fname": "Dana",
"lname": "Reyes",
"emailVerified": true
},
"activeOrgUid": "0199a3c2-5b1d-74e0-8c55-1f0e2a9b7d31",
"org": { "uid": "0199a3c2-5b1d-74e0-8c55-1f0e2a9b7d31", "name": "Dana Reyes" }
}This is the call a server makes to learn who is asking: see Server-side sign-in.
Name
PATCH /{appUid}/auth/me takes fname, lname or both, and nothing else. A string sets the field
and null or an empty string clears it. It answers the same shape as GET /auth/me.
Password
POST /{appUid}/auth/password with { "currentPassword", "newPassword" } changes the password.
The new one follows the sign-up rule: at least 8 characters with an uppercase letter, a lowercase
letter, a number and a special character. It answers { "changed": true, "signedOutSessions": 2 }.
- Every other session ends, and every browser remembered for two-factor is forgotten. The session that made the change stays signed in.
- The account's address is sent a "your password was changed" email.
- A wrong current password is
403 PASSWORD_INCORRECT. - An account with no password yet (one that signs in with Google, GitHub or a sign-in link) is
409 PASSWORD_NOT_SET. It sets one with the password reset email, which proves the address.
Confirming the email address
A password sign-up has not proven its address, so sign-up sends a "confirm your email" link. Pass
verifyRedirectTo to sign-up to have the link open your own page, on one of your app's
allowed domains. The link carries a token (and the
appUid) in its query string. Your page sends it back:
POST /{appUid}/auth/verify-email/confirm
{ "token": "<token from the link>" }It answers { "verified": true }, and needs no session: the link proves the mailbox.
POST /{appUid}/auth/verify-email/request sends the link again, to a signed-in user, and answers
{ "sent": true, "verified": false } (or { "sent": false, "verified": true } when the address is
already confirmed). Without a redirectTo, a link goes to the public address the deployment is
configured with.
GET /auth/me says whether the address is confirmed (emailVerified). Signing in with a sign-in
link, an email code, Google or GitHub proves the address too.
Until the address is confirmed, the account cannot send invitations
or create organizations; both answer 403 EMAIL_NOT_VERIFIED.
Requiring a confirmed address
When your app requires a confirmed address (see App settings), sign-up opens no session. It answers:
{ "verificationRequired": true, "email": "dana@example.com" }and a password sign-in is refused with 403 EMAIL_NOT_VERIFIED until the link is followed. Show a
"check your email" screen, and send the user to sign in once the confirm call succeeds.
Proving it is still you
A signed-in session is not enough for the two changes that would hurt most in the wrong hands: moving the account to a new address, and deleting it. First the user proves it is them again, with exactly one of:
| Body | Proof |
|---|---|
{ "password" } | The account's password |
{ "mfaCode", "mfaKind"? } | A code from an authenticator app or a texted code (mfaKind: totp or sms) |
{ "requestId", "code" } | The 6-digit code emailed by POST /auth/reverify/email-code, which answers the requestId |
POST /{appUid}/auth/reverify answers a receipt:
{ "reverifyToken": "<receipt>", "expiresInSeconds": 600 }The receipt lasts ten minutes, works for one change, and only from the session that earned it. A
proof that fails, and a change sent without a valid receipt, both answer 403 REVERIFY_REQUIRED
with details.methods, the proofs this account can give (password, totp, sms, email), so
your app can show the right prompt.
Changing the email address
POST /{appUid}/auth/email with the new address and a receipt:
# 1. Prove it is you
curl -X POST "$AUTHORIC_URL/$APP_UID/auth/reverify" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "password": "Str0ng!Passphrase" }'
# 2. Ask for the move, with the receipt
curl -X POST "$AUTHORIC_URL/$APP_UID/auth/email" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"newEmail": "dana.reyes@example.com",
"reverifyToken": "<receipt>",
"redirectTo": "https://yourapp.com/confirm-email"
}'
# 3. On https://yourapp.com/confirm-email, with the link's token
curl -X POST "$AUTHORIC_URL/$APP_UID/auth/email/confirm" \
-H "Content-Type: application/json" \
-d '{ "token": "<token from the link>" }'- The ask answers
{ "sent": true }. A link goes to the new address, and a notice to the current one. - The answer is the same whether or not the new address already has an account. When it does, that address's own mailbox is told instead, and no link is sent.
- The confirm call needs no session, and answers
{ "changed": true, "email": "<new address>" }. The account moves to the new address, which counts as confirmed, and its email code and sign-in link methods move with it. Every session except the one that asked ends, and every remembered browser is forgotten. - Asking for the address the account already has is
400 EMAIL_UNCHANGED. If the new address gets an account of its own before the link is followed, the confirm is409 EMAIL_IN_USE.
Deleting the account
DELETE /{appUid}/auth/me with a receipt in the body:
DELETE /{appUid}/auth/me
{ "reverifyToken": "<receipt>" }It answers { "deleted": true, "orgsDeleted": 1 }, and:
- erases the account's personal details: name, email address and password;
- removes every way in: sign-in methods, two-factor factors and recovery codes, remembered browsers and every session;
- ends its memberships and roles, and withdraws pending invitations to it;
- deletes each organization the user was the only member of (
orgsDeletedcounts them). Their rows are kept, for you, the app's owner, to keep or remove; - sends a notice to the address, which is then free to sign up again.
It is refused, and nothing changes, when:
| Code | Status | When |
|---|---|---|
ACCOUNT_LAST_OWNER | 409 | The user is the last owner or administrator of an organization that has other members. details.orgs names them. Give another member the owner role, or remove the members, first. |
ACCOUNT_HAS_SUBSCRIPTION | 409 | The user has a subscription that is still billing. Cancel it first. |
ACCOUNT_DELETE_DISABLED | 403 | Your app does not let users delete their own account. |
REVERIFY_REQUIRED | 403 | No receipt, or one that is spent, expired or another session's. |
App settings
In the console, open the app, then App settings › Sign-in. Under Accounts:
| Setting | Default | What it does |
|---|---|---|
| Require a confirmed email to sign in | Off | A password sign-up cannot sign in until its address is confirmed. |
| Users can delete their own account | On | Turned off, DELETE /auth/me answers ACCOUNT_DELETE_DISABLED. |
| Users can create more organizations | Off | Lets a user create organizations beyond their own, up to a number per user you choose (10 by default). |
Errors to branch on
| Code | Status | Meaning |
|---|---|---|
PASSWORD_INCORRECT | 403 | The current password is wrong. |
PASSWORD_NOT_SET | 409 | The account has no password; use the reset email. |
EMAIL_NOT_VERIFIED | 403 | The address is not confirmed yet. |
REVERIFY_REQUIRED | 403 | Prove it is you first; details.methods lists how. |
EMAIL_UNCHANGED | 400 | The new address is the current one. |
EMAIL_IN_USE | 409 | The new address got an account before the change finished. |
LINK_TOKEN_INVALID | 404 | A link that is invalid, expired, used or revoked. |
REDIRECT_NOT_ALLOWED | 400 | redirectTo or verifyRedirectTo is not on one of your app's allowed domains. |
ACCOUNT_LAST_OWNER, ACCOUNT_HAS_SUBSCRIPTION, ACCOUNT_DELETE_DISABLED | 409, 403 | See Deleting the account. |