Getting an Access Token

Use the OAuth 2.0 Client Credentials grant to obtain a Bearer access token for machine-to-machine API calls.

Access tokens are temporary. Your integration must use the expires_in value returned by the token endpoint to determine when to request a new access token.

Before you begin

Paymentology provides the following OAuth configuration during onboarding:

Configuration itemDescription
Token URLThe Auth0 token endpoint for your environment
AudienceThe identifier for the API you are authorised to call
OAuth client_idIdentifies your machine-to-machine application
OAuth client_secretAuthenticates your machine-to-machine application
ScopeRequired only where specified in your onboarding configuration

Environment configuration

Use the values supplied in your onboarding configuration.

ItemUATPROD
Token URLValues are supplied in the onboarding packValues are supplied in the onboarding pack
AudienceValues are supplied in the onboarding packValues are supplied in the onboarding pack

Request an access token

curl --fail-with-body --silent --show-error \
  --request POST "<TOKEN_URL>" \
  --header "Content-Type: application/json" \
  --data '{
    "client_id": "<CLIENT_ID>",
    "client_secret": "<CLIENT_SECRET>",
    "audience": "<AUDIENCE>",
    "grant_type": "client_credentials"
  }'
import os
import requests

response = requests.post(
    os.environ["TOKEN_URL"],
    json={
        "client_id": os.environ["CLIENT_ID"],
        "client_secret": os.environ["CLIENT_SECRET"],
        "audience": os.environ["AUDIENCE"],
        "grant_type": "client_credentials",
    },
    timeout=10,
)
response.raise_for_status()

token_response = response.json()
access_token = token_response["access_token"]
expires_in = token_response["expires_in"]
const response = await fetch(process.env.TOKEN_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    client_id: process.env.CLIENT_ID,
    client_secret: process.env.CLIENT_SECRET,
    audience: process.env.AUDIENCE,
    grant_type: "client_credentials",
  }),
});

if (!response.ok) {
  throw new Error(`Token request failed: ${response.status}`);
}

const { access_token: accessToken, expires_in: expiresIn } =
  await response.json();

A successful response includes:

{
  "access_token": "…",
  "scope": "read:full",
  "expires_in": 3600,
  "token_type": "Bearer"
}

The value of expires_in is expressed in seconds. Do not rely on the example value above; use the value returned in your response.

Use the token

Include the access token in the Authorization header when calling the API:

Authorization: Bearer <access_token>

Refer to the relevant API documentation for other required headers, request fields, and mTLS requirements.

Recommended token handling

  • Cache the access token and reuse it until shortly before it expires.
  • Use expires_in to calculate the expiry time.
  • Request a new access token before expiry, allowing for clock skew and network delay.
  • Access tokens cannot be refreshed; request a new access token when the current access token expires.
  • Where multiple application instances use the same credentials, coordinate token requests to avoid unnecessary concurrent requests.
  • Never log, expose, or store client_secret values or access tokens in source code.
  • Retry access token requests only for transient errors, using backoff and jitter.
  • If an API call returns 401 Unauthorized, obtain a new access token and retry once only when the operation is safe to retry.

Did this page help you?