/api/v1/user/Get the authenticated user's profile, API key, and embedded subscription state.
Get the authenticated user's profile, API key, and embedded subscription state. EXEMPT (`cost: 0`). JWT auth required.
Why use this
Common use case
Authenticated 'who am I?' endpoint — returns the full user profile plus embedded Userplan / UserDocumentLimit / UserDeviceLimit relationship rows. EXEMPT (cost: 0). The dashboard SPA calls this on app load to bootstrap user state; server-side automation should NOT — use the api_key directly. Note the response is identical in shape to the user field in the POST /api/v1/auth/login response (both invoke to_dict(include_relations=True)). To update notification preferences (webhook_url, notify_email, notify_browser) use PUT /api/v1/user/; for the live token balance use GET /api/v1/account/balance; for subscription details use GET /api/v1/billing/subscription.
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| user | object | no | Authenticated user profile (matches the `user` field in the /auth/login response). Built by `User.to_dict(include_relations=True)` — includes the three relationship rows (`Userplan`, `UserDocumentLimit`, `UserDeviceLimit`) inline. |
| user.uuid | string | no | Stable user identifier (UUIDv4 string). Foreign-key target in every per-user table; treat as the canonical user PK. |
| user.email | string | no | Lowercased registration email. Unique across `users`. Used as the login identifier. |
| user.usertype | string | no | Role enum value — `user` (default) or `admin`. Use to gate admin-only UI surfaces. Distinct from `billing_admin` (a finer-grained flag for billing-operator dashboard access). |
| user.api_key | string | no | API key for server-to-server billed calls (32-char concatenation of two UUIDs with hyphens removed). Pass as `X-API-Key: <api_key>` header on `/api/v1/sec/*`, `/api/insiders/*`, etc. Distinct from the JWT `token` (issued by /auth/login) — JWT is for browsing the dashboard, API key is for server-to-server calls. |
| user.verify_email | boolean | no | True if the user has clicked the verification email link. Always true here — login is gated by this flag, so the JWT bearer must already be verified. |
| user.has_uat_access | boolean | no | True if the user is allowed onto the UAT environment (separate cohort gate from the production access flag). Use to render UAT-environment banners or to gate UAT-only feature flags. |
| user.billing_admin | boolean | no | Phase 56-02 RBAC flag — true if the user can access the billing-operator dashboard (`/admin/billing/*` routes). Distinct from `usertype === 'admin'` (which grants full admin access). |
| user.credit_balance | number | no | Stripe-paid top-up balance in USD (not in cents). Used by [POST /api/v1/billing/quota](/docs/account/billing-and-subscription/post-billing-quota) for buying additional API quota at 100 requests / $1. NOT the same as the token balance (see [GET /api/v1/account/balance](/docs/account/token-pricing/get-account-balance) for that). |
| user.webhook_url | string | yes | User-configured HTTPS URL for sniper-hit webhook callbacks. Null when the user has not configured one (most users). PUT /api/v1/user/ with `webhook_url` to update. |
| user.notify_email | boolean | no | True if email notifications are enabled. Default true. Toggle via PUT /api/v1/user/. |
| user.notify_browser | boolean | no | True if in-browser push notifications are enabled. Default true. Toggle via PUT /api/v1/user/. |
| user.created_at | string | no | ISO-8601 UTC timestamp the user account was created (set by /auth/register). |
| user.updated_at | string | no | ISO-8601 UTC timestamp the user row was last modified (`onupdate=datetime.utcnow`). Bumped on profile edits, login (last-seen), and admin role changes. |
| user.Userplan | object | yes | Embedded subscription state — `total_limit_api` (monthly request quota), `reach_limit_api` (consumed this cycle), `plan` (`free`/`weekly`/`monthly`/`pro`/`yearly`), `status` (`active`/`canceled`/`past_due`), `current_period_end`. Null in legacy edge cases where the relationship row was never seeded; /auth/register seeds this for new users. |
| user.UserDocumentLimit | object | yes | Embedded document-quota state for the (legacy) RAG document-upload feature — `total_limit_GB` and `reach_limit_GB`. Most users do not consume document quota. |
| user.UserDeviceLimit | object | yes | Embedded device-limit state — `device_limit` (max concurrent JWT sessions, default 2) and `user_login_device` (JSON-serialized array of active session_ids). When a third login lands the oldest session_id is evicted from the array. |
Sample response
- "user":
- "id": 42
- "uuid": "0f14ed05-3a2e-4b76-9c11-1a7c8b3f6de2"
- "email": "user@example.com"
- "usertype": "user"
- "api_key": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
- "verify_email": true
- "is_online": true
- "has_uat_access": false
- "billing_admin": false
- "credit_balance": 12.5
- "notify_email": true
- "notify_browser": true
- "webhook_url": "https://your-app.example.com/webhooks/finradar"
- "created_at": "2026-04-15T10:00:00.000Z"
- "updated_at": "2026-05-02T15:51:00.000Z"
- "Userplan":
- "UserDocumentLimit":
- "UserDeviceLimit":
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 "https://api.finradar.ai/api/v1/user/" \
-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).