POST /v2/authorizations/applyToken
The applyToken endpoint is used to obtain access tokens. It supports two use cases:
- Authorization Code Exchange: Exchange an
authCode for an accessToken
- Token Refresh: Use a
refreshToken to obtain a new accessToken
Use Cases
Authorization Code Flow
After a user completes authorization (e.g., signs an agreement), you receive an authCode. Exchange it for tokens:
User signs agreement → You receive authCode → Call applyToken → Receive accessToken
Token Refresh Flow
When an accessToken expires, use the refreshToken to get a new one without requiring user interaction:
accessToken expires → Call applyToken with refreshToken → Receive new accessToken
Request Parameters
The type of token grant being requested.Possible values:
AUTHORIZATION_CODE - Exchange an auth code for tokens
REFRESH_TOKEN - Refresh an expired access token
The authorization code received after user authorization.Required when: grantType is AUTHORIZATION_CODE
The refresh token from a previous token response.Required when: grantType is REFRESH_TOKEN
Your client reference identifier.
Extended information for wallet and merchant configuration.
Response Parameters
Standard result object with resultCode, resultStatus, resultMessage
Access token for accessing user resources within the authorized scope.
Access token expiration time in ISO 8601 format.
Token for obtaining new access tokens when the current one expires.
Refresh token expiration time. After this, the user must re-authorize.
Resource owner identifier (user ID, app ID, or merchant ID).
Extended information response field.
Example: Authorization Code Exchange
Request:
{
"referenceClientId": "305XST2CSG0N4P0xxxx",
"grantType": "AUTHORIZATION_CODE",
"authCode": "2810111301lGZcM9CjlF91WH00039190xxxx",
"extendInfo": "{\"customerBelongsTo\":\"siteNameExample\"}"
}
Response:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"accessToken": "281010033AB2F588D14B43238637264FCA5AAF35xxxx",
"accessTokenExpiryTime": "2024-06-06T12:12:12+01:00",
"refreshToken": "2810100334F62CBC577F468AAC87CFC6C9107811xxxx",
"refreshTokenExpiryTime": "2024-06-08T12:12:12+01:00",
"customerId": "1000001119398804xxxx"
}
Example: Token Refresh
Request:
{
"referenceClientId": "305XST2CSG0N4P0xxxx",
"grantType": "REFRESH_TOKEN",
"refreshToken": "2810100334F62CBC577F468AAC87CFC6C9107811xxxx"
}
Response:
{
"result": {
"resultCode": "SUCCESS",
"resultStatus": "S",
"resultMessage": "success"
},
"accessToken": "NEW_ACCESS_TOKEN_HERE",
"accessTokenExpiryTime": "2024-06-07T12:12:12+01:00",
"refreshToken": "NEW_REFRESH_TOKEN_HERE",
"refreshTokenExpiryTime": "2024-06-09T12:12:12+01:00",
"customerId": "1000001119398804xxxx"
}
Result Codes
| resultStatus | resultCode | Description | Action |
|---|
S | SUCCESS | Token issued successfully | Store tokens securely |
F | PROCESS_FAIL | Processing failed | Retry the request |
F | PARAM_ILLEGAL | Invalid parameters | Check request parameters |
F | INVALID_CODE | Auth code is invalid | Request new authorization |
F | EXPIRED_CODE | Auth code has expired | Request new authorization |
F | USED_CODE | Auth code already used | Use existing tokens or re-authorize |
F | INVALID_REFRESH_TOKEN | Refresh token is invalid | Request new authorization |
F | EXPIRED_REFRESH_TOKEN | Refresh token has expired | Request new authorization |
F | AUTH_CLIENT_UNSUPPORTED_GRANT_TYPE | Grant type not supported | Check grantType value |
F | INVALID_AUTH_CLIENT | Auth client invalid | Verify configuration |
U | UNKNOWN_EXCEPTION | Unknown error occurred | Retry with backoff |
U | REQUEST_TRAFFIC_EXCEED_LIMIT | Rate limit exceeded | Implement rate limiting |
Implementation Example
class TokenManager {
async exchangeAuthCode(authCode, referenceClientId) {
const response = await rebellAPI.call('/v2/authorizations/applyToken', {
grantType: 'AUTHORIZATION_CODE',
authCode,
referenceClientId
});
if (response.result.resultStatus === 'S') {
await this.storeTokens(referenceClientId, {
accessToken: response.accessToken,
accessTokenExpiry: new Date(response.accessTokenExpiryTime),
refreshToken: response.refreshToken,
refreshTokenExpiry: new Date(response.refreshTokenExpiryTime),
customerId: response.customerId
});
return response;
}
throw new Error(`Token exchange failed: ${response.result.resultCode}`);
}
async refreshAccessToken(referenceClientId) {
const stored = await this.getStoredTokens(referenceClientId);
if (!stored.refreshToken) {
throw new Error('No refresh token available');
}
if (new Date() > stored.refreshTokenExpiry) {
throw new Error('Refresh token expired, re-authorization required');
}
const response = await rebellAPI.call('/v2/authorizations/applyToken', {
grantType: 'REFRESH_TOKEN',
refreshToken: stored.refreshToken,
referenceClientId
});
if (response.result.resultStatus === 'S') {
await this.storeTokens(referenceClientId, {
accessToken: response.accessToken,
accessTokenExpiry: new Date(response.accessTokenExpiryTime),
refreshToken: response.refreshToken,
refreshTokenExpiry: new Date(response.refreshTokenExpiryTime),
customerId: response.customerId
});
return response.accessToken;
}
throw new Error(`Token refresh failed: ${response.result.resultCode}`);
}
async getValidAccessToken(referenceClientId) {
const stored = await this.getStoredTokens(referenceClientId);
// Check if access token is still valid (with 5 min buffer)
const bufferTime = 5 * 60 * 1000;
if (new Date() < new Date(stored.accessTokenExpiry.getTime() - bufferTime)) {
return stored.accessToken;
}
// Refresh the token
return this.refreshAccessToken(referenceClientId);
}
}
Best Practices
When a refresh token expires, the user must go through the full authorization flow again. Plan your token refresh strategy to avoid disrupting user experience.