---
updatedAt: 2026-06-17T21:34:16.000Z
---

Fetch the complete documentation index at: https://docs.clover.com/dev/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Generate OAuth expiring (access and refresh) token

Prerequisites and steps for generating an `access_token` and `refresh_token` pair using the v2/OAuth flow

<div class="container-top">
  
  <div class="container-reg">
    <div class="pill-reg">
      <div class="label-reg">North America</div>
    </div>
  </div>
  
   <div class="container-reg">
    <div class="pill-reg">
      <div class="label-reg">Europe</div>
    </div>
  </div>
  
  <div class="container-reg">
    <div class="pill-reg">
      <div class="label-reg">Latin America</div>
    </div>
  </div>
  
  <div class="container-reg">
    <div class="pill-reg">
      <div class="label-reg">Asia Pacific</div>
    </div>
  </div>
</div>

[block:html]
{
  "html": "<!--DS-5402 - New standalone topic that explains the high-level steps to generate\n expiring token and links to the three topics - 1. generate expiring token for high trust apps \n2. generate expiring tokens for low trust apps with PKCE 3. generate a new refresh token -->\n<!--DS-7355-Updated region icon and other info to indicate that\nv2/OAuth flow is available in all regions. -->"
}
[/block]

All REST API endpoints require an OAuth-generated `access_token` with specific permissions. Use the v2/OAuth flow to create an expiring authentication token, which includes an `access_token` and a `refresh_token` pair.

# Prerequisites

1. [Create a global developer account](https://docs.clover.com/docs/gdp-create-global-developer-account).
2. [Manage test merchant accounts and information](https://docs.clover.com/docs/gdp-manage-test-merchants-accounts).
3. [Create your app](https://docs.clover.com/docs/gdp-create-new-app) in the sandbox environment.
4. Configure [settings](https://docs.clover.com/dev/docs/gdp-manage-app-settings) and [permissions](https://docs.clover.com/dev/docs/gdp-set-app-permissions) that your app requires to access Clover merchant data.
5. Set the Alternate Launch Path—Required when the app OAuth is initiated from the left navigation menu on the Merchant Dashboard or directly from the Clover App Market. See [Set app link (URL) and CORS domain](https://docs.clover.com/dev/docs/using-cors).

[block:image]
{
  "images": [
    {
      "image": [
        "https://files.readme.io/075fedc5205803a0744aeb809213c879dc1b1420bed9cb17834d876651443d4b-NewOAuthFlowSettings.png",
        "",
        "App Settings on the Developer Dashboard: Edit REST Configuration page"
      ],
      "align": "center",
      "sizing": "80% ",
      "border": true,
      "caption": "App Settings on the Developer Dashboard: Edit REST Configuration page"
    }
  ]
}
[/block]

# Steps

The Clover OAuth flow starts when the merchant selects your app directly from the <a href="https://www.clover.com/appmarket/" target="_blank">Clover App Market</a> or from the left navigation on the Merchant Dashboard (More Tools > Clover App Market). Clover redirects the merchant to your app with the <<glossary:merchantId>> included in the <<glossary:Redirect URI>> as a query parameter. From there, your app must call the `/oauth/v2/authorize` endpoint to initiate the v2/OAuth flow and get an `access_token` and `refresh_token` pair.

If a merchant accesses the app from your website instead of installing or connecting to it from the Clover App Market, your app needs to redirect to the `/oauth/v2/authorize` endpoint.

To generate an expiring access and refresh token pair:

1. Log in to the [Global Developer Dashboard](https://www.clover.com/global-developer-home).
2. Navigate to the Merchant Dashboard for your test merchant.
3. From the left navigation menu, click **More**, and then select your app on the Clover App Market page.
4. Click **Connect** to install your app for the test merchant.

   From here:

   1. For merchant authorization, Clover redirects the merchant to the location specified in the Alternate Launch Path field, and the app calls `/oauth/v2/authorize` with the authorization code `code` as a query param to initiate OAuth.
      ```Text OAuth callback format
      `https://www.example.com/oauth_callback?code={AUTHORIZATION_CODE}&merchant_id={MERCHANT_ID}`
      ```

   2. For token exchange, your app makes a POST request with the`client_id`, `client_secret`, and `code` to `/oauth/v2/token`. The response provides an `access_token` and `refresh_token` pair that displays on the OAuth Process Results page of your app.

[block:image]{"images":[{"image":["https://files.readme.io/09caaf6279fac7604ce580b5f01b41327eb5d0362118a6dba093a808ece51ed3-Access-Refresh-Token.png","","Sample: Access and Refresh token pair"],"align":"center","sizing":"100% ","border":true,"caption":"Sample: Access and Refresh token pair"}]}[/block]

***

# Request and Response example

## Expiring OAuth token for high-trust app

```curl Request
curl --request POST \
--url 'https://apisandbox.dev.clover.com/oauth/v2/token' \
--header 'content-type: application/json' \
--data '{
    "client_id": "{APP_ID}",
    "client_secret": "{APP_SECRET}",
    "code": "{AUTHORIZATION_CODE}"
}'

```
```json Response
{
    "access_token": "{ACCESS_TOKEN}",
    "access_token_expiration": 1677875430,
    "refresh_token": "{REFRESH_TOKEN}",
    "refresh_token_expiration": 1709497830
}
```

## Expiring OAuth token for low-trust app

```curl Request
curl --request POST \
--url 'https://apisandbox.dev.clover.com/oauth/v2/token' \
--header 'content-type: application/json' \
--data '{
    "client_id": "{APP_ID}",
    "code": "{AUTHORIZATION_CODE}",
    "code_verifier": "{CODE_VERIFIER}"
}'
```
```json Response
{
"access_token": "{ACCESS_TOKEN}",  
"access_token_expiration": 1677875430,  
"refresh_token": "{REFRESH_TOKEN}",  
 "refresh_token_expiration": 1709497830  
}
```

For more information, see:

* [High-trust apps—Auth code flow](https://docs.clover.com/dev/docs/high-trust-app-auth-flow)
* [Low-trust apps—Auth code flow with PKCE](https://docs.clover.com/dev/docs/oauth-flow-for-low-trust-apps-pkce)

***

# Generate a new OAuth expiring token with a refresh token

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 generate a new 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 the refreshing of access tokens to allow merchants continuous access to the app.

For information, see [Use refresh token to generate new expiring token](https://docs.clover.com/dev/docs/refresh-access-tokens).

***

# 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.

[block:parameters]
{
  "data": {
    "h-0": "Request path",
    "h-1": "Sandbox URL",
    "h-2": "Production URL  \nNorth America",
    "h-3": "Production URL  \nEurope",
    "h-4": "Production URL  \nLatin America",
    "0-0": "/oauth/v2/authorize",
    "0-1": "sandbox.dev.clover.com",
    "0-2": "www\\.clover\\.com",
    "0-3": "www\\.eu\\.clover\\.com",
    "0-4": "www\\.la\\.clover\\.com",
    "1-0": "/oauth/v2/token",
    "1-1": "apisandbox.dev.clover.com",
    "1-2": "api.clover.com",
    "1-3": "api.eu.clover.com",
    "1-4": "api.la.clover.com",
    "2-0": "/oauth/v2/refresh",
    "2-1": "apisandbox.dev.clover.com",
    "2-2": "api.clover.com",
    "2-3": "api.eu.clover.com",
    "2-4": "api.la.clover.com",
    "3-0": "/oauth/token/migrate_v2",
    "3-1": "apisandbox.dev.clover.com",
    "3-2": "api.clover.com",
    "3-3": "api.eu.clover.com",
    "3-4": "api.la.clover.com"
  },
  "cols": 5,
  "rows": 4,
  "align": [
    "left",
    "left",
    "left",
    "left",
    "left"
  ]
}
[/block]

***

# Related topics

* <a href="https://docs.clover.com/dev/docs/use-oauth" target="_blank">Authenticate with v2/OAuth flow</a>
* <a href="https://medium.com/clover-platform-blog/expiring-oauth-tokens-securing-clover-merchant-data-16243b9c00cc" target="_blank">Blog: Expiring OAuth Tokens: Securing Clover Merchant Data</a>
* <a href="https://medium.com/clover-platform-blog/understanding-clover-auth-tokens-and-ecommerce-keys-4e048827afa2" target="_blank">Blog: Fiddling Through Digital Keys: Clover Auth Tokens and Ecommerce Keys</a>

<HTMLBlock>{`
<style>
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Video Table (vt) */

div.vt {
  width: 100%;
  overflow: auto;
}

table.vt,
td.vt {
  border: 1px solid #000;
}

#first {
  width: 40%;
}

#second {
  width: 60%;
}

tr.table-head th.table-head {
  background-color: #280;
  margin-block-start: 1em;
  color: #fff;
  margin-top: 0;
  font-size: 1.4em;
  font-weight: 500;
  overflow-wrap: normal;
  word-break: normal;
}

td.table-head {
  margin-block-start: 1em;
  color: #fff;
  padding: 10px;
  margin-top: 0;
  font-size: 1.4em;
  font-weight: 500;
  overflow-wrap: normal;
  word-break: normal;
}

tr.table-content {
  vertical-align: top;
}

td.table-content {
  vertical-align: top !important;
  margin-block-start: 1em;
}

p.table-title {
  color: #fff;
  padding: 10px;
  margin-top: 0;
  font-size: 1.4em;
  font-weight: 500;
  overflow-wrap: normal;
  word-break: normal;
}

p.table-content {
  padding-left: 4%;
  padding-right: 4%;
  overflow-wrap: normal;
  vertical-align: top;
  margin-block-start: 1em;
}

ul.table-content {
  margin-block-start: 1em;
}

/* iframe sizes */

#myiframe100p {
  width: 100%;
  min-height: 315px;
}

#myiframe90p {
  width: 90%;
  height: 100%;
}

#myiframe75p {
  width: 75%;
  height: 75%;
}

#myiframe60p {
  width: 60%;
  height: 60%;
}

#myiframe50p {
  width: 50%;
  height: 50%;
}
</style>
`}</HTMLBlock>

<br />