With your client credentials, your application will make a direct request to the OAuth authorization server's Token endpoint to exchange them for an Access Token.
URL
Prod
Audience : https://ibexhub.ibexmercado.com
OAUTH2_DOMAIN : https://auth.hub.poweredbyibex.io
Sandbox
Audience : https://api-sandbox.poweredbyibex.io
OAUTH2_DOMAIN : https://auth.hub.sandbox.poweredbyibex.io
Making the Token Request
Your service client must send an HTTP POST request to the Auth0 token endpoint with the following specifications:
| Parameter | Value | Description |
|---|---|---|
| Method | POST | HTTP method for the request |
| URL | <OAUTH2_DOMAIN>/oauth/token | Replace AUTH0_DOMAIN with your actual Auth0 domain see above |
| Content-Type | application/x-www-form-urlencoded | Standard encoding for form data |
Request Parameters
Include these parameters in the request body:
| Parameter | Required | Description |
|---|---|---|
grant_type | Yes | Must be set to client_credentials |
client_id | Yes | Your application's client identifier |
client_secret | Yes | Your application's client secret |
audience | Yes | The unique identifier of the target API. See above audiences |
cURL Example
curl --request POST \
--url '<OAUTH2_DOMAIN>/oauth/token' \
--header 'content-type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=YOUR_CLIENT_ID \
--data client_secret=YOUR_CLIENT_SECRET \
--data audience=AUDIENCEJavaScript Example
const options = {
method: 'POST',
headers: {'content-type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
audience: 'AUDIENCE'
})
};
fetch('OAUTH2_DOMAIN/oauth/token', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));Successful Response
When the request is successful, you'll receive a JSON response containing the access token:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjRmNDQ4...",
"token_type": "Bearer",
"expires_in": 86400,
"scope": "read:users write:users"
}Response Fields
| Field | Type | Description |
|---|---|---|
access_token | String | The JWT access token |
token_type | String | Always "Bearer" for this flow |
expires_in | Number | Token lifetime in seconds |
scope | String | Granted scopes (space-separated) |
Error Response
If the request fails, you'll receive an error response:
{
"error": "invalid_client",
"error_description": "Invalid client credentials"
}Token Lifetime
Access tokens expire 1 hour after they're issued. Once expired, requests made with that token will be rejected — request a new one before continuing.
Reuse Your Token
Cache your access token and reuse it for its full lifetime instead of requesting a new one on every call. Avoid creating more than 2 tokens per hour per client — repeated, unnecessary re-authentication may be throttled.
Store client credentials securely using environment variables or secret management systems. Always use HTTPS for token requests. Implement proper token caching and renewal strategies. Monitor token expiration times to avoid service interruptions. When creating the client, whitelist the public IP addresses that will access it.
Invalid credentials: Double-check your client ID and secret. Wrong audience: Verify the API identifier matches your configuration. Scope issues: Ensure requested scopes are allowed for your client. Rate limiting: Implement appropriate retry logic with exponential backoff. If IP whitelisting isn't working, verify your IP address. In some cases, requests may be sent from your IPv6 address. Our IP whitelisting supports both IPv4 and IPv6.

