Auth API

building

What is fixed by convention, what you still decide per project, and how to change it.

Settings

Most of how auth behaves is decided for you, on purpose.

The rule is convention over configuration: if there is an answer we would defend in a security review, that is the answer, and it is not a switch. A knob whose only correct position is the default is a way for somebody to get it wrong.

What is left is what we cannot guess — facts about your product and your customers' systems, which have no sensible default because they are not opinions.

Fixed for every project

BehaviourWhat it isWhy it is not yours to set
Account creationA six-digit code, emailedAn account that exists before the address is proved can be created for somebody, with a password they never chose. See sign up
Email verificationAlways requiredThe account was made by proving the address, so there is nothing to relax
Password lengthAt least 12 charactersLength is the only password rule that survives contact with evidence. No character classes, no rotation
PasswordOptionalCodes are a complete way in; a password is a second one
Code lifetime10 minutes, 3 attemptsLong enough to find the mail, short enough to be useless later
Session7 days, refreshed daily
Access tokens15 minutes, EdDSA, per-project keysSee tokens

If you need one of these to be different, tell us what you are building — that is a conversation about the convention, not a setting we forgot to expose.

GET/v1/auth/settings

Secret key.

Request
1curl "$BASE/v1/auth/settings" -H "authorization: Bearer $SK"
Response
1{2  "disableSignUp": false,3  "invitationUrl": null,4  "ssoOrigins": [],5  "scimRoleMap": {}6}
SettingDefaultWhat it does
disableSignUpfalseStop new account creation; existing users still sign in
invitationUrlunsetWhere invitations land in your app
ssoOrigins[]Hosts trusted for SSO discovery
scimRoleMap{}Directory groups that grant roles
PATCH/v1/auth/settings

Changes only what you send, so one setting can move without restating the rest.

Request
1curl -X PATCH "$BASE/v1/auth/settings" \2  -H "authorization: Bearer $SK" \3  -H "content-type: application/json" \4  -d '{"disableSignUp":true}'

Changes take effect on the next request, not after a cache expires.

A misspelled setting is refused, not ignored — a setting that reads as saved and does nothing is worse than an error:

json
{ "error": "Unknown setting: disableSignUps. Known settings are disableSignUp, invitationUrl, ssoOrigins, scimRoleMap." }

A setting that used to exist gets a straight answer rather than "unknown", so you are told what happened rather than left thinking you made a typo:

json
{ "error": "Email verification is always required and is no longer configurable." }

disableSignUp is not a suspension

Sign-in, sessions and tokens keep working; only account creation stops — for an app that provisions its users elsewhere, or one you are closing to new signups. It covers both doors: a code for an unknown address will not create an account either.

Errors

StatusCodeMeans
400—Unknown setting name, quoted back to you
400—A retired setting, with what replaced it
401—Missing key, or a publishable key