Skip to content
/api/v1/auth/register

Register a new user account.

Register a new user account. EXEMPT (`cost: 0`). Open signup — no invite required by default; `invite_token` is only checked when invite-only mode is enabled server-side.

Why use this

Create a new user account. EXEMPT (`cost: 0`) — auth endpoints never debit tokens. Registration is open by default (`INVITE_ONLY_MODE` unset or `false`): no invite is required. If an operator sets `INVITE_ONLY_MODE=true`, the body MUST include a short-lived `invite_token` JWT issued by `/api/v1/auth/redeem-invite`; the server re-validates the token against the `invite_codes` table on every register call (never trusts the JWT alone) whenever this mode is on. On success the user is created with the FREE tier (2,000 tokens/month), an API key is generated for the login-gated dashboard, a verification email is sent, and a separate welcome email links to the API-key dashboard and API documentation. The raw API key is never emailed. Verification delivery is required for a clean 200 response; welcome-email delivery is best-effort and does not cancel account creation. The user CANNOT log in until they click the verification link — `/auth/login` returns 400 if `verify_email=false`.

Common use case

Frontend signup form: user enters email + password → POST here → backend creates the account, sends verification email, returns success message. User clicks verification link → email is verified → user can log in. If the deployment has invite-only mode enabled, the form additionally collects a redeemed invite token (see /auth/redeem-invite) and includes it as `invite_token`.

Open user registration. EXEMPT (cost: 0) — auth endpoints carry cost: 0 and never debit the token ledger (consistent with the locked Phase 56 decision: 'session cookies do NOT debit tokens — clean separation between browsing the site and calling the API'). Signup is public by default — no invite token is required. Invite-token gating is available but off by default: an operator can set INVITE_ONLY_MODE=true to require callers to first POST a code to /api/v1/auth/redeem-invite to obtain a short-lived JWT, then pass that JWT here as invite_token; when enabled, the server re-validates the JWT-encoded code against the invite_codes table on every call (the JWT alone is not trusted). On success: a free-tier user is created with 2,000 tokens/month, an API key is generated for the login-gated dashboard, the required verification email is sent, and a best-effort welcome email links to the API-key dashboard and API documentation. The raw API key is never emailed. Customer-facing mail uses the FinRadar sender identity; operational alerts remain a separate internal mail path. After verification the user can call POST /api/v1/auth/login to obtain a JWT. Forgotten-password flow lives at POST /api/v1/auth/forgetpassword.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
emailbodyrequiredUser email address. Lowercased server-side. Must be unique across the `users` table — re-registration with an existing email returns 400 with `Email already exists`. Used as the canonical login identifier and the destination for the verification email.user@example.com
passwordbodyrequiredUser password — minimum 6 characters (validated by `@validate_register`). Hashed via bcrypt server-side; never stored in plaintext, never returned in any response. Use a strong password manager-generated value in production; the example shown above is a redaction placeholder.<redacted>
invite_tokenbodyoptionalShort-lived JWT from POST /api/v1/auth/redeem-invite. Only honored (and required) when the deployment has invite-only mode enabled (`INVITE_ONLY_MODE=true`); ignored otherwise since signup is open by default. When required, encodes the underlying `invite_codes.code` value — the server re-validates against the `invite_codes` table to confirm the code is still REDEEMABLE (not used, not expired, not revoked) before creating the account.eyJhbGciOiJIUzI1NiIs...

Response schema

FieldTypeNullableDescription
messagestringnoTop-level result message. `Register user successful` on success (200). On error: `Email already exists` (400), `Invalid or expired invite token` (400), `Invite code is used and cannot be used` (410), or the underlying exception message (400). UI should toast on success and gate-form on error.
linkMsgstringnoEmail-flow status message. Always `We sent you a verification link. Open it within 24 hours to activate your FinRadar account.` on a clean 200. If verification delivery fails, the account remains created but the endpoint returns 500 with `Your account exists, but we could not send the verification email. Please use Resend Verification.`; provider diagnostics are logged server-side and are not exposed in the response.

Sample response

·
  • "message": "Register user successful"
  • "linkMsg": "We sent you a verification link. Open it within 24 hours to activate your FinRadar account."
}

Errors

StatusLabelDescription
200OKRequest succeeded.
400Bad RequestInvalid query, body, or path parameter.
401UnauthorizedMissing or invalid Authorization header / api_Token.
402Payment RequiredInsufficient token balance for this call. Top up
429Too Many RequestsRate limit exceeded for your tier (see /pricing for tier limits). Tier limits
500Server ErrorUnexpected server-side failure. Retry with backoff; report if persistent.

Code samples

curl -X POST "https://api.finradar.ai/api/v1/auth/register" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "user@example.com",
  "password": "<redacted>",
  "invite_token": "eyJhbGciOiJIUzI1NiIs..."
}'

Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).