API ReferenceOAuth 2.1 / OIDC
Token Endpoint
Exchange an authorization code for tokens, refresh an access token, or obtain tokens via client credentials.
Endpoint
POST /oauth2/tokenBase URL: https://api-id.avnology.net
Content-Type: application/x-www-form-urlencoded
The token endpoint supports three grant types:
- Authorization code -- exchange a code for access + refresh + ID tokens
- Refresh token -- obtain a new access token using a refresh token
- Client credentials -- machine-to-machine authentication
Authorization Code Exchange
Request
| Parameter | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | authorization_code |
code | string | Yes | Authorization code from the callback |
redirect_uri | string | Yes | Must match the original request |
client_id | string | Yes | Your client ID |
client_secret | string | Confidential clients | Your client secret |
code_verifier | string | Yes | The PKCE code verifier from the authorization request |
Response (200 OK)
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCJ9.eyJpc3MiOiJodHRwczovL29hdXRoLmlkLmF2bm9sb2d5LmNvbSIsInN1YiI6InVzcl80ZjE4YWNlYy0yNzEyLTRiZTctYTlhZi1iMDYzYjRmNmRlYmEiLCJhdWQiOiJjbGlfYWJjMTIzZGVmNDU2IiwiZXhwIjoxNzEyNTgzMzAwLCJpYXQiOjE3MTI1ODI0MDAsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJvcmdfaWQiOiJvcmdfN2EyYjNjNGQiLCJvcmdfbmFtZSI6IkFjbWUgQ29ycCJ9.signature",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "rt_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL29hdXRoLmlkLmF2bm9sb2d5LmNvbSIsInN1YiI6InVzcl80ZjE4YWNlYy0yNzEyLTRiZTctYTlhZi1iMDYzYjRmNmRlYmEiLCJhdWQiOiJjbGlfYWJjMTIzZGVmNDU2IiwiZXhwIjoxNzEyNTgzMzAwLCJpYXQiOjE3MTI1ODI0MDAsImVtYWlsIjoiamFuZUBhY21lLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiSmFuZSBTbWl0aCJ9.signature",
"scope": "openid profile email"
Refresh Token
Request
curl -X POST https://api-id.avnology.net/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=rt_a1b2c3d4e5f6g7h8..." \
-d "client_id=cli_abc123def456" \
-d "client_secret=cs_secret_value"| Parameter | Type | Required | Description |
|---|---|---|---|
grant_type | string | Yes | refresh_token |
refresh_token | string | Yes | The refresh token |
client_id | string | Yes | Your client ID |
client_secret | string | Confidential clients | Your client secret |
scope | string | No | Request a subset of the original scopes |
Response (200 OK)
{
"access_token": "eyJhbGciOiJSUzI1NiI...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "rt_new_token_value...",
"scope": "openid profile email"
}Refresh tokens are rotated on each use. The old refresh token is invalidated and a new one is returned.
Client Credentials
For machine-to-machine (M2M) authentication without a user:
Request
curl -X POST https://api-id.avnology.net/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=cli_abc123def456" \
-d "client_secret=cs_secret_value" \
-d "scope=admin:users:read admin:orgs:read"Response (200 OK)
{
"access_token": "eyJhbGciOiJSUzI1NiI...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "admin:users:read admin:orgs:read"
}No refresh token is issued for client credentials grants.
Errors
| Error | HTTP | Description |
|---|---|---|
invalid_request | 400 | Missing or invalid parameter |
invalid_client | 401 | Client authentication failed |
invalid_grant | 400 | Code expired, already used, or verifier mismatch |
unauthorized_client | 400 | Client not authorized for this grant type |
unsupported_grant_type | 400 | Grant type not supported |
invalid_scope | 400 | Requested scope is invalid |
{
"error": "invalid_grant",
"error_description": "The authorization code has expired or has already been used"
}Code Examples
JavaScript (fetch)
async function exchangeCode(code, codeVerifier, redirectUri, clientId, clientSecret) {
const response = await fetch('https://api-id.avnology.net/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded'
Python (httpx)
import httpx
def exchange_code(code: str, code_verifier: str, redirect_uri: str, client_id: str, client_secret: str) -> dict:
return httpx.post(
"https://api-id.avnology.net/oauth2/token"
Go (net/http)
func exchangeCode(ctx context.Context, code, codeVerifier, redirectURI, clientID, clientSecret string) (*TokenResponse
Related
- Authorization Endpoint -- start the OAuth flow
- Revoke Token -- revoke a token
- Introspect Token -- check token validity
- SDK:
client.oauth.exchangeCode(),client.oauth.refreshToken()(TypeScript)