Skip to main content
Scopes are space-separated strings you pass in the scope parameter of your authorization request. They control what information Ave includes in the tokens and what actions your app can perform.
scope=openid profile email offline_access
If a scope is not in the list above, or if your app is not configured to request it, the server silently excludes the corresponding claims. Always check the returned scope string in the token response to know exactly what was granted.

Standard scopes

These are available to all OAuth apps without any special configuration.
openid
scope
Required for OIDC. Without this scope, no id_token is returned — just an access token.Adds to id_token:
{
  "iss": "https://aveid.net",,
  "sub": "identity-uuid",
  "aud": "your_client_id",
  "exp": 1712345678,
  "iat": 1712342078,
  "auth_time": 1712342078,
  "azp": "your_client_id",
  "sid": "user-uuid"
}
The sub is the Ave identity UUID. The sid is the permanent user UUID (stable across all identities for the same user).You almost always want this. Without openid, you cannot use Convex auth, validate identity server-side, or get an id_token.
profile
scope
Adds display name, username handle, and avatar URL.Adds to id_token:
{
  "name": "Alice Smith",
  "preferred_username": "alice",
  "picture": "https://avatars.aveid.net/..."
}
Adds to /userinfo response:
{
  "sub": "identity-uuid",
  "name": "Alice Smith",
  "preferred_username": "alice",
  "picture": "https://avatars.aveid.net/..."
}
email
scope
Adds the user’s email address.Adds to id_token:
{
  "email": "[email protected]"
}
Adds to /userinfo response:
{
  "sub": "identity-uuid",
  "email": "[email protected]"
}
Not all Ave identities have a verified email address. If the user has no email on their identity, this claim is absent even if the scope was granted.
offline_access
scope
Issues a refresh token alongside the access token.Adds to token response:
{
  "refresh_token": "rt_a1b2c3d4e5f6..."
}
Without this scope, you get no refresh_token. When the access_token expires, the user must log in again.Use this for long-lived sessions or background sync scenarios. Store the refresh token in an HTTP-only cookie or your server-side session storage — never in localStorage.

Extended scopes

These require explicit app configuration in the developer portal.
user_id
scope
Exposes the permanent user UUID — stable across all identities for the same physical user. Requires allowUserIdScope: true in your app config.Adds to access_token_jwt:
{
  "uid": "user-uuid",
  "sid": "user-uuid"
}
Adds to token response:
{
  "user_id": "user-uuid"
}
user_id is not in the id_token. It is in access_token_jwt as uid and in the top-level token response as user_id. If you need it in Convex, you will need to pass it separately or use a Convex mutation to look it up from the sub.
Only request this when your app has a genuine need for cross-identity user linking. It increases the user consent surface and requires portal configuration.

Scope-to-token mapping

Scopeid_token claims addedaccess_token_jwt claims addedtoken response fields
openidiss, sub, aud, exp, iat, auth_time, azp, sidiss, sub, aud, exp, iat, scope, cid, sid(enables id_token)
profilename, preferred_username, picture
emailemail
offline_accessrefresh_token
user_iduiduser_id

Organization context claims

Organization claims are not enabled by a separate scope. They appear when the authorization request includes a valid organization_id and the selected identity is an active member of that Ave Business organization.
{
  "auth_context": "organization",
  "org_id": "org_...",
  "org_name": "Example Co",
  "org_member_id": "orgmem_...",
  "org_role": "admin",
  "org_scopes": ["read", "sign", "approve"],
  "org_signing_authority": true,
  "org_encryption_mode": "standard",
  "org_key_custody": "ave_standard",
  "auth_method": "enterprise_sso",
  "sso_connection_id": "sso_..."
}
Apps that use Ave organizations as workspaces should require auth_context: "organization" and match org_id against the workspace being accessed. See Business workspaces.

Connector scopes

Connector flows use resource-defined scopes, not OIDC scopes. The target resource defines what scopes it exposes (for example resource.read, resource.write). When a user approves the connector, they grant specific scopes from the resource’s available list. When you perform the token-exchange grant, requestedScope must be a subset of what was granted. Requesting more than granted returns invalid_scope. See Connector app-to-app for details.

Requesting scopes safely

1

Start with the minimum

Begin with openid profile (or just openid if you do not need display names). Add scopes when a specific feature requires them.
2

Check what was actually granted

Read the scope field in the token response. It contains the actual granted scopes, which may differ from what you requested if some were rejected.
const grantedScopes = tokens.scope.split(" ");
const hasEmail = grantedScopes.includes("email");
3

Handle missing claims gracefully

Treat any optional claim (email, name, etc.) as potentially absent. email requires both the email scope and a verified email on the selected identity. Do not throw or break when a claim is missing.
4

Review scope changes

Adding a new scope changes what users see on the consent screen. Have product and legal review any scope additions.

Common mistakes

If your app does not have allowUserIdScope enabled, requesting user_id in the scope has no effect. The uid claim will not appear and the user_id field will not be in the token response.
Email is present only if you requested email scope and the identity has a verified email address. If the user has not linked and verified an email yet, Ave blocks the authorization flow until they do. Always treat the claim as optional in your app anyway.
Refresh token grants cannot add new scopes. The new tokens will have the same scopes as the original grant. To get additional scopes, run a new authorization code flow with the new scope.
sub (identity UUID) is not the same as user_id (user UUID). A user can have multiple identities, each with a different sub. If you store sub as a user identifier and a user creates a second identity, they appear as a different user. Decide upfront whether you identify by identity or by user.
Last modified on May 15, 2026