Headless sign-up: creates the unverified account and sends the email
Public (no auth). Verify-first: no credential is issued. The optional workspaceName creates the first tenant in the same step (on the free Spark plan). Rate-limited per IP and per email.
POST
/auth/signupRequest body
requiredapplication/jsonemailstring<email>requiredmatches ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
namestringrequiredmin length 2 · max length 120
workspaceNamestringmin length 2 · max length 80
Responses
202
Account pending verification (or already existing: same shape, no enumeration). The email sent is used to verify AND set a password — it reuses the staff invitation (src/lib/staff-invite.ts). With that, the user can approve an ft login (Device Grant) from their browser.
user_idstringrequiredstatusstringrequiredverification_sent_tostringrequired422
Invalid body (email, name or workspaceName).
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequiredretryablebooleanrequireddetailsany429
Too many attempts from the same IP or the same email.
errorobjectrequiredShow propertiesHide properties
codestringrequiredmessagestringrequiredretryablebooleanrequireddetailsany
