Auth API

building

A short-lived JWT your API verifies locally, so we are not a hop on every request you serve.

Tokens and JWKS

GET/v1/auth/token

Returns a short-lived JWT for the current session. Publishable key and a session cookie.

Request
1curl "$BASE/v1/auth/token" \2  -H "authorization: Bearer $PK" \3  -b "session cookie"
The claims
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.

GET/v1/auth/jwks

The public keys, so your API verifies tokens locally and we are not a network hop on every request you serve.

Request
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

StatusCodeMeans
401—No session on the request
403—Publishable key used from an unregistered origin