/api/v1/auth/registerRegister a new user account.
Register a new user account. EXEMPT (`cost: 0`). INVITE-ONLY during the soft-trial — body must include a valid `invite_token` from POST /api/v1/auth/redeem-invite.
Why use this
Common use case
Soft-trial-gated 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'). Phase 64 added invite-token gating: callers MUST first POST a code to /api/v1/auth/redeem-invite to obtain a short-lived JWT, then pass that JWT here as invite_token. The server re-validates the JWT-encoded code against the invite_codes table on every call — the JWT alone is not trusted. On success: free-tier user created with 2,000 tokens/month, API key generated, verification email sent (mandatory — user cannot log in until verified), welcome email with API key + curl example sent (best-effort — SMTP failure does NOT 500 the response). 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
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| body | required | — | — | User 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 | |
| password | body | required | — | — | User password — minimum 8 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_token | body | required | — | — | Short-lived JWT from POST /api/v1/auth/redeem-invite. 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. Required during the Phase 64 invite-only soft-trial. | eyJhbGciOiJIUzI1NiIs... |
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| message | string | no | Top-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. |
| linkMsg | string | no | Email-flow status message. Always `Please verify the email, I have send verification link.` on a clean 200. If verification email send failed (SMTP error), the endpoint returns 500 instead with a different message and the user is created but cannot log in until they trigger /auth/resend-verification. |
Sample response
- "message": "Register user successful"
- "linkMsg": "Please verify the email, I have send verification link."
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected 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"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).