Skip to main content
POST
/
api
/
oauth
/
token
Token Endpoint
curl --request POST \
  --url https://api.example.com/api/oauth/token \
  --header 'Content-Type: application/json' \
  --data '
{
  "grantType": "<string>",
  "code": "<string>",
  "redirectUri": "<string>",
  "clientId": "<string>",
  "clientSecret": "<string>",
  "codeVerifier": "<string>",
  "refreshToken": "<string>",
  "subjectToken": "<string>",
  "requestedResource": "<string>",
  "requestedScope": "<string>",
  "actor": {}
}
'
{
  "access_token": "<string>",
  "access_token_jwt": "<string>",
  "token_type": "<string>",
  "expires_in": 123,
  "scope": "<string>",
  "id_token": "<string>",
  "refresh_token": "<string>",
  "user": {
    "id": "<string>",
    "handle": "<string>",
    "displayName": "<string>",
    "email": "<string>",
    "avatarUrl": "<string>"
  },
  "user_id": "<string>",
  "encrypted_app_key": "<string>",
  "audience": "<string>",
  "target_resource": "<string>",
  "communication_mode": "<string>",
  "error": "<string>",
  "error_description": "<string>"
}
The token endpoint supports three grant types for obtaining access tokens:
  • authorization_code - Exchange an authorization code for tokens
  • refresh_token - Refresh an expired access token
  • urn:ietf:params:oauth:grant-type:token-exchange - Exchange a token for delegated access

Authorization Code Grant

Exchange an authorization code for access tokens. Supports both PKCE (public clients) and client secret authentication (confidential clients).

Request Body

grantType
string
required
Must be authorization_code
code
string
required
The authorization code received from the authorization endpoint
redirectUri
string
required
The redirect URI used in the authorization request. Must match exactly.
clientId
string
required
Your OAuth application’s client ID
clientSecret
string
Your OAuth application’s client secret (for confidential clients)
codeVerifier
string
PKCE code verifier (for public clients using PKCE)

Response

access_token
string
Opaque access token for API requests
access_token_jwt
string
JWT access token containing claims
token_type
string
Always Bearer
expires_in
number
Token lifetime in seconds (default: 3600)
scope
string
Granted scopes (space-separated)
id_token
string
OpenID Connect ID token (if openid scope was granted)
refresh_token
string
Refresh token (if offline_access scope was granted)
user
object
User identity information
user_id
string
Ave user ID (if user_id scope was granted and allowed)
encrypted_app_key
string
Encrypted app key for E2EE applications

Example with PKCE (Public Client)

import { exchangeCode } from '@ave-id/sdk';

const tokens = await exchangeCode(
  {
    clientId: 'your_client_id',
    redirectUri: 'https://yourapp.com/callback',
  },
  {
    code: authorizationCode,
    codeVerifier: codeVerifier,
  }
);

Example with Client Secret (Confidential Client)

import { exchangeCodeServer } from '@ave-id/sdk/server';

const tokens = await exchangeCodeServer(
  {
    clientId: 'your_client_id',
    clientSecret: 'your_client_secret',
    redirectUri: 'https://yourapp.com/callback',
  },
  {
    code: authorizationCode,
  }
);

Refresh Token Grant

Refresh an expired access token using a refresh token. Implements token rotation for security.

Request Body

grantType
string
required
Must be refresh_token
refreshToken
string
required
The refresh token received from a previous token response
clientId
string
required
Your OAuth application’s client ID
clientSecret
string
Your OAuth application’s client secret (for confidential clients)

Response

Returns the same structure as the authorization code grant, including a new rotated refresh token.
access_token
string
New opaque access token
access_token_jwt
string
New JWT access token
id_token
string
New ID token
refresh_token
string
New refresh token (the old one is revoked)
expires_in
number
Token lifetime in seconds
user_id
string
Ave user ID (if user_id scope was granted)

Example

import { refreshToken } from '@ave-id/sdk';

const tokens = await refreshToken(
  {
    clientId: 'your_client_id',
    redirectUri: 'https://yourapp.com/callback',
  },
  {
    refreshToken: currentRefreshToken,
  }
);
Token Rotation: Each refresh invalidates the old refresh token and returns a new one. If a revoked token is reused, all tokens for that app are revoked as a security measure.

Token Exchange Grant

Exchange an access token for a delegated token to access another app’s resources. This enables connector flows where one app accesses another app’s API on behalf of a user.

Request Body

grantType
string
required
Must be urn:ietf:params:oauth:grant-type:token-exchange
subjectToken
string
required
The access token or access token JWT from the source app
requestedResource
string
required
Resource key of the target resource to access
requestedScope
string
required
Space-separated scopes being requested for the target resource
clientId
string
required
Your OAuth application’s client ID
clientSecret
string
Your OAuth application’s client secret
actor
object
Optional actor information to include in the delegated token

Response

access_token
string
Delegated access token (JWT) for the target resource
token_type
string
Always Bearer
expires_in
number
Token lifetime in seconds (default: 600)
scope
string
Granted scopes for the target resource
audience
string
Audience claim for the target resource
target_resource
string
Resource key of the target resource
communication_mode
string
Communication mode: user_present or background

Example

import { exchangeDelegatedToken } from '@ave-id/sdk';

const delegatedToken = await exchangeDelegatedToken(
  {
    clientId: 'your_client_id',
    redirectUri: 'https://yourapp.com/callback',
  },
  {
    subjectToken: accessTokenJwt,
    requestedResource: 'target-app-resource',
    requestedScope: 'read write',
    actor: { service: 'integration-service' },
  }
);
Delegation Grant Required: The user must have previously authorized delegation between your app and the target resource. See the Connector Flow guide for more information.

Error Responses

All grant types return standard OAuth 2.0 error responses:
error
string
Error code:
  • invalid_client - Client authentication failed
  • invalid_grant - Authorization code or refresh token is invalid/expired
  • invalid_request - Missing or invalid parameters
  • invalid_scope - Requested scope is not allowed
  • invalid_target - Requested resource not found
  • access_denied - No delegation grant exists
error_description
string
Human-readable error description

Example Error

{
  "error": "invalid_grant",
  "error_description": "Authorization code expired"
}

Build docs developers (and LLMs) love