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
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.
Example error response:
401 responses by re-authenticating with your Clerk JWT and retrying the original request. A 503 is transient — retry with backoff.
python
Summary
1
Get a Clerk JWT
Retrieve your JWT from the Clerk dashboard or your Clerk client SDK.
2
Exchange for a session token
POST /auth/session with your Clerk JWT in the Authorization header. Save the returned token.3
Call bootstrap
GET /auth/bootstrap to load your profile and verify the token works end-to-end.4
Make requests
Pass
Authorization: Bearer <session_token> on every subsequent API call.5
Refresh before expiry
Session tokens last 30 minutes. Re-authenticate with your Clerk JWT before they expire.
6
Logout when done
DELETE /auth/session to revoke the token immediately.