> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokens and JWKS

> Validate Authentication sessions, rotate refresh tokens safely, and prepare for per-application JWT verification.

<Warning>
  Early access has two distinct contracts. The current hosted runtime returns opaque access tokens and has no public per-application discovery or JWKS contract. JWT access tokens and ID tokens are release-dependent. Do not attempt to decode an opaque token or invent a JWKS URL.
</Warning>

## Current runtime

Set `DIDIT_AUTH_BASE_URL` to the confirmed application runtime URL, including its trailing slash. These calls use **end-user** credentials, not your verification API key or console access token.

| Request | Input | Result |
| - | - | - |
| `POST authorize/` | `redirect_uri`, `state`, `code_challenge`, `code_challenge_method: "S256"` | `transaction`, `expires_in` (600 seconds). |
| `POST token/` | `grant_type: "authorization_code"`, `code`, `code_verifier`, `redirect_uri` | `access_token`, `refresh_token`, `token_type`, `expires_in`, `session_id`. |
| `GET session/` | `Authorization: Bearer <access_token>` | Validated session and identity. |
| `POST token/` | `grant_type: "refresh_token"`, `refresh_token` | A new access token and refresh token. |
| `DELETE session/` | `Authorization: Bearer <access_token>` | `204` after revoking the session. |

An authorization code is single-use and expires after 60 seconds. Check callback `state` before exchanging it, and use the exact redirect URI and original PKCE verifier. Access tokens last at most five minutes; session lifetime and idle policy are separate limits.

```bash theme={null}
curl --fail-with-body "${DIDIT_AUTH_BASE_URL}session/" \
  -H "Authorization: Bearer $DIDIT_ACCESS_TOKEN"
```

The session response includes `sub`, `sid`, `application_id`, `amr`, `mfa_verified`, `email`, `email_verified`, `phone`, `verified_identity`, `expires_at` and `organizations`. `verified_identity` can be null. Do not treat a verified email as a completed identity verification.

```bash theme={null}
curl --fail-with-body "${DIDIT_AUTH_BASE_URL}token/" \
  -H 'Content-Type: application/json' \
  -d "$(jq -n --arg token "$DIDIT_REFRESH_TOKEN" \
    '{grant_type: "refresh_token", refresh_token: $token}')"
```

Serialize refreshes across requests and tabs. Reusing a consumed refresh token revokes the session, so do not blindly retry an uncertain refresh result. Replace both tokens together; if recovery fails, start sign-in again. Do not print either token in logs.

## JWT and JWKS release contract

<Note>
  The following describes the planned issuer contract. Use it only after your application's release provides discovery, keys and the SDK verifier. It is not an installation or endpoint reference for the current runtime.
</Note>

Each application will have its own issuer and signing keys; sandbox and live are different applications. Discovery supplies the issuer's `jwks_uri`. Access tokens will use ES256, last five minutes and be separate from ID tokens. Refresh tokens remain opaque and rotating.

| Claim | Intended meaning |
| - | - |
| `iss`, `aud` | Issuer and intended audience; both must match your trusted application configuration. |
| `sub`, `sid` | Identity and session within that application. |
| `vendor_data` | Stable person reference shared with verification and monitoring. |
| `amr` | Authentication methods used. |
| `org` | Organization context, including `id` and `role`, when present. |
| `verified` | Verification context when available; enforce your own required assurance. |
| `act` | Agent actor context when an agent is acting for a person. |

Your server must verify the signature, allowed algorithm, issuer, audience and time claims before trusting any claim. Obtain discovery from a configured issuer, never from an unverified token. Cache keys by issuer and key ID; allow the published rotation overlap, refresh on an unknown key ID, and reject if no trusted key verifies the token.

Offline signature verification cannot detect an immediately revoked session. Use `GET session/` when you need a current revocation check. Do not use an ID token as an API access token, and do not authorize an agent beyond its grant scopes.

## Store credentials by purpose

* Keep verification API keys and console management tokens on your server.
* Keep browser access tokens in memory where possible. Use secure, HttpOnly cookies for server sessions; protect cookie-authenticated mutations against CSRF.
* Store mobile refresh tokens in platform-protected storage. Clear local state after logout and treat revocation failures as failures.
* A publishable key identifies the application for the future SDK; it is not a server secret or proof of an end user's identity.

Continue with the [JavaScript quickstart](/authentication/quickstarts/javascript) or [Next.js quickstart](/authentication/quickstarts/nextjs).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.