Mark a table as auth_table: true to get built-in email/password auth.
# Sign up POST /p/{id}/auth/signup { "email": "user@example.com", "password": "secret123" } # -> { token, refresh_token, user } # Log in POST /p/{id}/auth/login { "email": "user@example.com", "password": "secret123" } # Refresh token POST /p/{id}/auth/refresh { "refresh_token": "..." } # Get current user GET /p/{id}/auth/me Authorization: Bearer {token} # Logout POST /p/{id}/auth/logout Authorization: Bearer {token}
Pass the JWT in subsequent requests:
Authorization: Bearer eyJhbGci...
# Change password (requires Bearer token) POST /p/{id}/auth/change-password { "current_password": "old", "new_password": "new123456" } # Forgot password (sends reset email) POST /p/{id}/auth/forgot-password { "email": "user@example.com", "redirect_url": "https://myapp.com/reset" } # Reset password (with token from email) POST /p/{id}/auth/reset-password { "token": "...", "new_password": "new123456" }
forgot-password always returns 200 (never reveals whether the email exists). The redirect_url is your app's reset page — the token is appended as ?token=....
Important: redirect_url must use an origin from the project's allowed_redirect_origins allow-list. Configure it once with the admin key — otherwise forgot-password returns 400 VALIDATION_REDIRECT_URL:
PUT /p/{id}/v1/redirect-origins
X-Admin-Key: sk_...
{ "allowed_redirect_origins": ["https://myapp.com", "https://staging.myapp.com"] }
Changing or resetting a password invalidates all of that user's outstanding access tokens (they're bound to a per-user password version that bumps on every change). Refresh tokens are unaffected.
POST /p/{id}/v1/rotate-keys # rotate sk_ or pk_ (admin key required) POST /p/{id}/v1/rotate-jwt-secret # invalidates ALL outstanding end-user JWTs
Add "verify_email": true to the auth table. Users receive a verification email on signup.
GET /p/{id}/auth/verify?token=... POST /p/{id}/auth/resend-verification Authorization: Bearer {token}
If your auth table has custom columns, pass them in the signup body:
POST /p/{id}/auth/signup
{
"email": "user@example.com",
"password": "secret123",
"display_name": "Alice",
"role": "user"
}