Auth API
buildingA short-lived JWT your API verifies locally, so we are not a hop on every request you serve.
Tokens and JWKS
Returns a short-lived JWT for the current session. Publishable key and a session cookie.
1curl "$BASE/v1/auth/token" \2 -H "authorization: Bearer $PK" \3 -b "session cookie"1{2 "sub": "NrzmwycxFVpxrD8RSZqieT4iqpW24W9M",3 "sid": "h0bsPL9wBPaRfvslAcU2q0w8VPeF4wJu",4 "org_id": null,5 "role": null,6 "email": "ada@example.com",7 "email_verified": false,8 "iss": "https://<your-deployment>",9 "exp": 178697748810}Signed with EdDSA/Ed25519, fifteen minute expiry.
The public keys, so your API verifies tokens locally and we are not a network hop on every request you serve.
1curl "$BASE/v1/auth/jwks" -H "authorization: Bearer $PK"The signing keys live in your project's own database, so your tokens are signed with a keypair nobody else holds — a token minted for another project cannot verify against yours.
org_id and role
Both are in the payload from day one, and were null before organizations shipped. This is deliberate: writing your API against these claims now means it keeps working when teams arrive, and retrofitting them after you have built a flat user model is the part that hurts.
org_id is the active organization on the session — one person can belong to
several and switch without their identity changing.
role is read from the membership at the moment the token is minted, not copied
onto the session at sign-in, so demoting an admin takes effect on their next
token rather than their next sign-in.
Expiry is a design decision, not a limitation
Fifteen minutes is short enough that a revoked session stops working quickly and
long enough that a client is not fetching a token per request. Ask for a new one
when it expires; get-session tells you whether the underlying session is still
alive.
Errors
| Status | Code | Means |
|---|---|---|
401 | — | No session on the request |
403 | — | Publishable key used from an unregistered origin |