Hosts and purposes
Identity model
When a user signs in with Ave, they sign in as a specific identity — not just a user account. The same person can have multiple identities.Token types
A successful token exchange returns up to four tokens, each with a different purpose:access_token — opaque bearer token
access_token — opaque bearer token
An opaque string accepted by Ave’s own API endpoints (mainly
/api/oauth/userinfo). Not a JWT — you cannot decode it. It expires after 1 hour.access_token_jwt — signed JWT for Ave APIs
access_token_jwt — signed JWT for Ave APIs
A signed JWT with Verify using the
aud: https://aveid.net. Use this when calling Ave API endpoints that accept JWTs. Do not use it as the login token for your app API; use id_token or your own app session for that.jwks_uri from your issuer’s OIDC discovery document ({issuer}/.well-known/openid-configuration). For Ave, this is https://aveid.net/.well-known/jwks.json.id_token — OIDC identity token
id_token — OIDC identity token
A signed JWT with
aud set to your clientId. Use this to establish a user session in your app, or with OIDC-aware services like Convex. Only returned when openid scope is granted.refresh_token — long-lived session token
refresh_token — long-lived session token
An opaque token you can exchange for a fresh set of access/ID tokens without re-authenticating the user. Only returned when
offline_access scope is granted. Rotated on every use — store the new one immediately.id_token and access_token_jwt are both JWTs but have different audiences. The id_token audience is your clientId. The access_token_jwt audience is https://aveid.net. This matters for any library that validates JWT audience.Scopes
Scopes are space-separated strings requested during authorization. They control which claims appear in tokens and whether Ave delivers encryption keys.openid, profile, email, and offline_access are allowlisted per app in the developer portal. Requesting one outside the allowlist returns invalid_scope. user_id and the encryption scopes are requested per sign-in and always require user consent. See Scopes and claims.Token endpoint field casing
The Ave token endpoint (POST /api/oauth/token) accepts OAuth-standard snake_case body fields and their camelCase equivalents.
grantType, clientId, redirectUri, and codeVerifier as JSON. Form-encoded bodies, which most OAuth libraries send, work too.