Use refresh token to generate new expiring token
Overview
In the v2/OAuth flow, an expiring authentication token consisting of an access_token and refresh_token pair is generated. The access_token is short-lived, while the refresh_token lasts longer but also expires eventually.
To maintain authorization, your app must refresh the token pair before the current one expires. To do so, send a POST request to the /oauth/v2/refresh endpoint with the existing refresh_token and client_id to generate a new access_token and refresh_token pair. Your app needs to handle refreshing of access tokens to ensure merchants have continuous access to the app.
If the current refresh_token is lost, a high-trust app can restore authentication by using the immediately preceding refresh_token that was used to generate the current token. This previous token acts as a recovery token and can be exchanged for a new access_token and refresh_token pair through the /oauth/v2/recovery endpoint.
Key features of expiring tokens
Key features of access and refresh tokens are:
- Limitations on the number of refresh tokens—Clover limits the number of active refresh tokens an app can have for each merchant. If an app exceeds the limit, prior tokens become invalid.
- Limitations on refresh token usage—Refresh token is for single use and becomes invalid immediately after a new
access_tokenandrefresh_tokenpair is generated using the/oauth/v2/refreshendpoint. - Dynamic expiration dates and length—You should not hard-code access and refresh token expirations or lengths, but handle them dynamically in your app:
- Token expiration date is based on the time the token is generated; hence, tokens created over a period of time have different expiration dates. The format of the expiration dates is Unix timestamp.
- Token length is not fixed.
- Recovery token support for refresh cycles—If the current
refresh_tokenis lost, a high-trust app can use the immediately precedingrefresh_tokento restore authentication. The recovery token ensures a secure, linear recovery path.
Generate new access and refresh token pair
Prerequisites
You need an access_token and refresh_token pair along with the client_id for which you initiated the OAuth flow. For information, see Generate OAuth expiring (access and refresh) token.
- Install the app and receive authorization information from the
/oauth/v2/authorizeendpoint. - Send a POST request to the
/oauth/v2/tokenendpoint with the following parameters:client_id,client_secret, andcode.
The response body displays the access_token and refresh_token pair, along with their expiration date, in Unix timestamp format.
Steps
- Send a POST request to the
/oauth/v2/refreshendpoint. - Include the
client_IDandrefresh_tokenfrom your app's initial token request to the/oauth/v2/tokenendpoint to generate an expiring token. See Prerequisite.
Request and Response example—Generate new access and refresh tokens
curl --request POST \
--url 'https://apisandbox.dev.clover.com/oauth/v2/refresh' \
--header 'content-type: application/json' \
--data '{
"client_id": "{APP_ID}",
"refresh_token": "{REFRESH_TOKEN}"
}'{
"access_token": "{NEW_ACCESS_TOKEN}",
"access_token_expiration": 1709498373,
"refresh_token": "{NEW_REFRESH_TOKEN}",
"refresh_token_expiration": 1741034373
}The response body displays the new access_token and refresh_token pair, along with their expiration date, in Unix timestamp format.
Reauthenticate with a recovery token
In the OAuth expiring token flow, a refresh_token becomes invalid once it is used to generate a new access_token and refresh_token pair. In some cases, this new token may be lost before it is used, causing the app to enter an unauthenticated state. Triggering a reauthentication flow can be challenging for backend-driven, high-trust apps, as it typically requires user interaction.
In such scenarios, the token recovery flow allows reauthentication for high-trust apps. If the current refresh_token is lost, a high-trust app can use the immediately preceding refresh token as a recovery token to restore authentication. This recovery token is exchanged for a new access_token and refresh_token pair through the /oauth/v2/recovery endpoint, ensuring continuity across refresh cycles without requiring user reauthentication. The client_secret is required to validate the app’s identity.
Validity
A recovery token associated with a currentrefresh_tokenremains valid for up to 2 weeks or until therefresh_tokenis successfully used.
Once the refresh_token is used, it is no longer considered lost, and the associated recovery token becomes invalid. After the 2-week period from when the current refresh_token was generated, the only way to reauthenticate the app is by completing the OAuth flow again.
How it works
Recovery tokens enable high-trust apps to regenerate a refresh token if the current one is lost before it can be used.
- When your app uses a refresh token
Token Ato obtain a new refresh tokenToken Bthrough the/oauth/v2/refreshendpoint,Token Abecomes the recovery token forToken B. - If
Token Bis lost before your app is able to persist it, you can reuseToken Awith the/oauth/v2/recoveryendpoint to generate a new refresh tokenToken C. - In this case,
Token Aremains the recovery token forToken C, andToken Bbecomes invalid.
This chaining continues until a refresh token is successfully used. At any given time, only one recovery token is active. This ensures a linear recovery path and prevents branching. A recovery token remains valid until either:
- A new refresh token is successfully used by the client, or
- Two weeks have passed since the current access and refresh token pair was generated.
Prerequisites
- Install a high-trust app and obtain the
client_secret. - Generate an initial
access_tokenandrefresh_tokenpair to start the refresh flow.
Note: At this stage, the recovery flow is not available because there is no previously issued token to act as a recovery token for the current refresh token. If the current refresh token is lost, the app must initiate the complete OAuth flow to reauthenticate the user.
Steps
- To refresh the token, send a POST request to the
/oauth/v2/refreshendpoint using the current refresh token.
- If the
refresh_tokenis valid, the system issues a new access and refresh token pair. The previousrefresh_tokennow becomes the recovery token for this new refresh token. - If the
refresh_tokenis invalid but matches a known recovery token, the server responds with HTTP status code 401. In this case, proceed to Step 2. If a recovery token exists for the providedrefresh_token, the response includes a headerX-Clover-Recovery-Available: true.
- Send a POST request to the
oauth/v2/recoveryendpoint. - In the request body, include the
client_id,client_secret, and the immediately precedingrefresh_token(now used as therecovery_token).
If the recovery token is valid, the auth server issues a new access and refresh token pair.
curl --request POST \
--url 'https://apisandbox.dev.clover.com/oauth/v2/recovery' \
--header 'content-type: application/json' \
--data '{
"client_id": "APP_ID",
"client_secret": "APP_SECRET",
"recovery_token": "PREVIOUS_REFRESH_TOKEN"
}{
"access_token": "{NEW_ACCESS_TOKEN}",
"access_token_expiration": 1729813869,
"refresh_token": "{NEW_REFRESH_TOKEN}",
"refresh_token_expiration": 1761349869
}Error handling
| Status code | Description | Resolution |
|---|---|---|
| 401 Unauthorized | Failed to validate the recovery token. |
|
| 400 Bad Request | Malformed request or missing parameters. | Check that the request body includes the client_id, client_secret, and previous refresh_token in a valid JSON format. |
Bypass refresh token creation in the OAuth flow
Clover limits the number of active refresh tokens that an app can have for each merchant. In some scenarios, a refresh token is not needed, for example, in:
- Frontend apps that use OAuth to authenticate users to their own apps often don’t need a refresh token.
- Apps that only need the access token to verify that the user successfully authenticated with Clover and then use that token to get details from the API.
In such cases, generating a refresh token may unnecessarily cause the app to reach the limit. Use the no_refresh_token setting on the OAuth Authorize endpoint to bypass the refresh token creation.
To bypass generating a refresh token for your app:
- Install the app and receive authorization information from the
/oauth/v2/authorizeendpoint. - Send a POST request to the
/oauth/v2/tokenendpoint with the following parameters:client_id,client_secret, andcode. - Set the
no_refresh_tokenparameter to true.
Request and Response example—No refresh token
curl --request POST \
--url 'https://apisandbox.dev.clover.com/oauth/v2/token' \
--header 'content-type: application/json' \
--data '{
"code": "{AUTHORIZATION_CODE}",
"client_id": "{APP_ID}",
"client_secret": "{APP_SECRET}"
}'{
"access_token": "{ACCESS_TOKEN}",
"access_token_expiration": 1709498373,
}The response returns only an access token, along with the expiration date, in Unix timestamp format.
Sandbox and production environment URLs
Clover sandbox and production environments use different URLs. The following table lists which URL to use for OAuth requests in each environment.
| Request path | Sandbox URL | Production URL North America | Production URL Europe | Production URL Latin America |
|---|---|---|---|---|
| /oauth/v2/authorize | sandbox.dev.clover.com | www.clover.com | www.eu.clover.com | www.la.clover.com |
| /oauth/v2/token | apisandbox.dev.clover.com | api.clover.com | api.eu.clover.com | api.la.clover.com |
| /oauth/v2/refresh | apisandbox.dev.clover.com | api.clover.com | api.eu.clover.com | api.la.clover.com |
| /oauth/v2/recovery | apisandbox.dev.clover.com | api.clover.com | api.eu.clover.com | api.la.clover.com |
| /oauth/token/migrate_v2 | apisandbox.dev.clover.com | api.clover.com | api.eu.clover.com | api.la.clover.com |
Updated 7 days ago
