ManticScore uses Clerk for identity. Rather than sending your Clerk JWT on every request, you exchange it once for a lightweight session token that the API validates in microseconds. Session tokens expire after 30 minutes, so you’ll refresh them periodically. For zero-friction onboarding, the API also supports anonymous sessions — mint a session from a device id, let users try the product, and rebind their work to a Clerk account when they sign in. This page explains the full authentication lifecycle from login to logout.Documentation Index
Fetch the complete documentation index at: https://docs.manticscore.com/llms.txt
Use this file to discover all available pages before exploring further.
How authentication works
Every protected endpoint requires anAuthorization header with a Bearer token:
- Session token — an opaque string returned by
POST /auth/sessionorPOST /auth/anonymous. Validated via an O(1) lookup, making it the fastest path. Use this for all normal requests. - Clerk JWT — an RS256-signed JWT from Clerk, verified against the Clerk JWKS. Used only when exchanging for a session token.
- Authenticated sessions are tied to a Clerk user id (e.g.
user_3AtP...) and mint tokens from a Clerk JWT. - Anonymous sessions are tied to a device id, require no sign-in, and mint tokens from
POST /auth/anonymous. When the user later signs in, callPOST /auth/rebindonce to re-own every anonymous artifact to the authenticated user.
Streaming endpoints (
GET /research/{id}/events, WebSocket /ws, and similar) use the same bearer token. The session TTL is extended automatically when you connect to a stream.Step 1: Get your Clerk JWT
ManticScore uses Clerk as its identity provider. You get a Clerk JWT from the Clerk dashboard or your Clerk client SDK — not from the ManticScore API directly.- Clerk dashboard
- JavaScript SDK
- Python SDK
- Log in to the Clerk dashboard.
- Open your ManticScore application.
- Navigate to Users, select your account, and copy a short-lived JWT from the Sessions panel.
Step 2: Exchange the JWT for a session token
Send your Clerk JWT toPOST /auth/session. The request body is empty — the JWT goes in the Authorization header.
curl
| Field | Type | Description |
|---|---|---|
token | string | Opaque session token — use this on all subsequent requests |
expires_in | integer | Seconds until expiry (always 1800 — 30 minutes) |
Step 3: Make authenticated requests
Include the session token as a Bearer token in every request:curl
python
Anonymous sessions (zero-friction onboarding)
You can skip the Clerk exchange entirely on first launch and let users try the product without signing in. CallPOST /auth/anonymous with a stable device_id and you’ll get back a session token that behaves like any other — attach it on subsequent requests and the API will authorize writes under an anonymous principal.
curl
device_id — repeated calls for the same device reuse the same anonymous principal, so their work is preserved across launches.
Use a stable, per-device identifier. On iOS,
identifierForVendor backed by the Keychain is a good choice. Don’t regenerate a new device_id on every launch or users will see an empty account each time.Rebind on sign-in
When the user signs in with Clerk, callPOST /auth/rebind once with the original device_id and the authenticated session token (or Clerk JWT) in the Authorization header. Every row written under the anonymous principal is re-owned by the Clerk user inside a single database transaction:
curl
- If the device never used an anonymous session, the call is a no-op and returns
{"rebound": false}. - If the same device and user have already been rebound, the call is also a no-op.
- If the device was previously rebound to a different Clerk user, the call returns
409 Conflict.
POST /auth/anonymous and POST /auth/rebind in the API reference.
Recommended: call bootstrap after authenticating
After getting a session token, callGET /auth/bootstrap as your first request. This endpoint returns your full profile, subscription details, and connected secret status in one call — saving you multiple round trips.
curl
Session token TTL and refreshing
Session tokens expire after 30 minutes. Plan to refresh proactively rather than waiting for a
401.POST /auth/session again with your Clerk JWT before the token expires:
curl
python
Logging out
To revoke the current session token, send aDELETE /auth/session request:
curl
401.
Error responses
All auth errors return4xx JSON responses with a detail field.
| Status | detail | Cause |
|---|---|---|
401 | "Missing Bearer token" | Authorization header is absent |
401 | "Token expired" | Session token TTL has elapsed |
401 | "Invalid token: ..." | Token is malformed or unrecognized |
401 | "Invalid authorized party" | JWT azp claim doesn’t match the expected value |
401 | "Rebind requires an authenticated user token; got anonymous session" | POST /auth/rebind was called with an anonymous session token — sign in first, then retry with the authenticated token |
409 | "device <id> already rebound to a different user" | POST /auth/rebind — the device has already been rebound to a different Clerk user |
422 | "device_id required" | POST /auth/anonymous or POST /auth/rebind was called without device_id in the body |
503 | "JWKS not loaded" | Clerk JWKS endpoint is temporarily unreachable |
401 responses by re-authenticating with your Clerk JWT and retrying the original request. A 503 is transient — retry with backoff.
python
Summary
Exchange for a session token
POST /auth/session with your Clerk JWT in the Authorization header. Save the returned token.Refresh before expiry
Session tokens last 30 minutes. Re-authenticate with your Clerk JWT before they expire.