---
schema_version: "1"
id: 3b8262b54d73a274e212035e85e7ab99eb5eec476054fde11d1b8e592f3c2cc1
title: OAuth 2.0 Refresh Token Flow for Renewed Sessions
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_oauth_refresh_token_flow.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_refresh_token_flow.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 572be44d5d13f8957a2e19db8ea01fe16bde9ca5bd67f0d63c44245910ed017e
description: The OAuth 2.0 refresh token flow renews access tokens issued by the OAuth 2.0 web server flow or the OAuth 2.0 user-agent flow.
products:
  - Security
  - Cross Cloud
release: "264"
---
# OAuth 2.0 Refresh Token Flow for Renewed Sessions

The OAuth 2.0 refresh token flow renews access tokens issued by the OAuth 2.0 web server flow or the OAuth 2.0 user-agent flow.

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition"><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: both Salesforce Classic (<a href="https://help.salesforce.com/s/articleView?id=xcloud.overview_edition_lex_only.htm&amp;type=5&amp;language=en_US" target="_blank">not available in all orgs</a>) and Lightning Experience</td></tr><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>All</strong> Editions</td></tr></tbody></table>

After a client—via a connected app—receives an access token, it can use a refresh token to get a new session when its current session expires. The connected app’s session timeout value determines when an access token is no longer valid and when to apply for a new one using a refresh token.

For better security, enable refresh token rotation on your connected app or external client app when you configure its OAuth settings. With this setting enabled, the connected app issues a new refresh token along with the access token each time the flow is invoked. The previous refresh token is automatically invalidated. Refresh token rotation ensures that each refresh token is used only one time per user, so that refresh tokens can’t be used to get new access tokens. If someone tries to use a refresh token that’s been rotated out, Salesforce invalidates the current refresh token and any associated access tokens. To get a new refresh token, the client must complete a new flow.

The refresh token flow involves these steps.

1. The connected app uses the existing refresh token to [request a new access token](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_refresh_token_flow.htm&release=264.0.0&type=5).
2. After verifying the request, Salesforce [grants a new access token](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_refresh_token_flow.htm&release=264.0.0&type=5) to the client.

## Request an Updated Access Token

A connected app can use the refresh token to get a new access token by sending one of these refresh token POST requests to the Salesforce token endpoint.

The connected app can send the `client_id` and `client_secret` in the body of the refresh token POST request, as shown here.

```
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com/ 
grant_type=refresh_token&
client_id=3MVG9lKcPoNINVBIPJjdw1J9LLM82HnFVVX19KY1uA5mu0QqEWhqKpoW3svG3XHrXDiCQjK1mdgAvhCscA9GE&client_secret=1955279925675241571&
refresh_token=your token here 
```

Instead of sending client credentials as parameters in the body of the refresh token POST request, you can use the HTTP Basic authentication scheme. This scheme’s format requires the `client_id` and `client_secret` in the authorization header of the post as follows:

`Authorization: Basic64Encode(client_id:secret)`

The `client_id` and `client_secret` are separated with a colon (`:`). For more information, see the [OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749).

This example shows a refresh token POST request that uses the HTTP Basic authentication scheme rather than sending client credentials in the POST request’s body.

```
POST /services/oauth2/token HTTP/1.1
Host: login.salesforce.com
Authorization:  Basic 
client_id=3MVG9lKcPoNINVBIPJjdw1J9LLM82HnFVVX19KY1uA5mu0QqEWhqKpoW3svG3XHrXDiCQjK1mdgAvhCscA9GE&
client_secret=1955279925675241571
grant_type=refresh_token&
refresh_token=your token here 
```

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_note.png)

Note If the `client_id` and `client_secret` are sent in the POST’s body, the authorization header is ignored.

Avoid sending simultaneous requests that contain the same refresh token. If your client sends identical requests at the same time, some of the requests fail intermittently and the Status column in the Login History displays Failed: Token request is already being processed. Instead of continually sending requests for new access tokens, cache and reuse tokens instead. If you do send simultaneous requests with the same refresh token, which isn’t recommended, develop a way to retry the requests when this error occurs.

With either refresh token POST request format, include these parameters.

![Important](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_important.png)

Important When developing OAuth integrations, always pass sensitive information in the body of a POST request or in a request header. Don't use GET parameters in the URL query string to pass sensitive information. Sensitive information includes but isn't limited to usernames, passwords, OAuth tokens, client secrets, and any personally identifiable information. For more information on security best practices, see [Storing Sensitive Data](https://developer.salesforce.com/docs/atlas.en-us.secure_coding_guide.meta/secure_coding_guide/secure_coding_storing_sensitive_data.htm) in the Secure Coding Guide.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d91021e182">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d91021e185">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>client_id</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">The consumer key of the connected app. To access the consumer
              key, from the App Manager, find the connected app and select
              <strong class="uicontrol">View</strong> from the dropdown. Then click
              <strong class="uicontrol">Manage Consumer Details</strong>. You're sometimes
              prompted to verify your identity before you can view the consumer
              key.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>client_secret</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">The consumer secret of the connected app. To access the consumer
              secret, from the App Manager, find the connected app and select
              <strong class="uicontrol">View</strong> from the dropdown. Then click
              <strong class="uicontrol">Manage Consumer Details</strong>. You're sometimes
              prompted to verify your identity before you can view the consumer
              secret.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>grant_type</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">The OAuth 2.0 grant type that the connected app requests. The
              value must be <code>refresh_token</code> for
              this flow.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>refresh_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">Token obtained from the web server, user-agent, or hybrid app
              token flow. This value is a secret. Take appropriate measures to
              protect it. This parameter is returned only if your connected app is
              set up with a <code>refresh_token</code>
              scope.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>client_assertion</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">Instead of passing a <code>client_secret</code>, you can provide a <code>client_assertion</code> and <code>client_assertion_type</code>. If a <code>client_secret</code> parameter isn’t
              provided, Salesforce checks for the <code>client_assertion</code> and <code>client_assertion_type</code>. See <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&amp;type=5&amp;language=en_US" target="_blank">Use
                <code>client_assertion</code>
                Instead of <code>client_secret</code></a>. </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>client_assertion_type</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">
              <p>Provide this value when using the <code>client_assertion</code> parameter.</p>
              <p style="margin-bottom:0;">The value of <code>client_assertion_type</code> must be
                <code>urn:ietf:params:oauth:client-assertion-type:jwt-bearer</code>.
              </p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e182 ">
              <code>format</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e185 ">
              <p>If not included in the request’s header, you can specify the
                expected return format. The <code>format</code> parameter takes precedence over the request’s
                header. These formats are supported.</p>
              <ul>
                <li><code>urlencoded</code></li>
                <li><code>json</code> (default)</li>
                <li><code>xml</code></li>
              </ul>
            </td>

          </tr>
        </tbody>
      </table>

## Salesforce Grants a New Access Token

After verifying the request, Salesforce sends a response with a new access token to the connected app.

Here’s an example JSON response from Salesforce.

```
{ 
"id":"https://login.salesforce.com/id/00Dx0000000BV7z/005x00000012Q9P",
"issued_at":"1278448384422",
"instance_url":"https://yourInstance.salesforce.com/",
"signature":"SSSbLO/gBhmmyNUvN18ODBDFYHzakxOMgqYtu+hDPsc=",
"access_token":"00Dx0000000BV7z!AR8AQP0jITN80ESEsj5EbaZTFG0RNBaT1cyWk7TrqoDjoNIWQ2ME_sTZzBjfmOE6zMHq6y8PIW4eWze9JksNEkWUl.Cju7m4",
"token_type":"Bearer",
"scope":"id api refresh_token"
}
```

And here’s an example XML response.

```
<Oauth>
   <access_token>00Dx0000000BV7z!AR8AQP0jITN80ESEsj5EbaZTFG0RNB
       aT1cyWk7TrqoDjoNIWQ2ME_sTZzBjfmOE6zMHq6y8PIW4eWze9JksNEkWUl.Cju7m4 
   </access_token>
   <token_type>Bearer
   </token_type>
   <scope>id api refresh_token
   </scope>
   <instance_url>https://yourInstance.salesforce.com/</instance_url>
   <id>https://login.salesforce.com/id/00Dx0000000BV7z/005x00000012Q9P</id>
   <issued_at>1278448101416</issued_at>
   <signature>CMJ4l+CCaPQiKjoOEwEig9H4wqhpuLSk4J2urAe+fVg=</signature>
</Oauth>
```

This example shows a URL-encoded response.

```
access_token=00Dx0000000BV7z%21AR8AQP0jITN80ESEsj5EbaZTFG0RNBaT1cyWk7TrqoDjoNIWQ2
ME_sTZzBjfmOE6zMHq6y8PIW4eWze9JksNEkWUl.Cju7m4
&token_type=Bearer&scope=id%20api%20refresh_token
&instance_url=https%3A%2F%2FyourInstance.salesforce.com
&id=https://login.salesforce.com%2Fid%2F00Dx0000000BV7z%2F005x00000012Q9P
&issued_at=1278448101416
&signature=CMJ4l%2BCCaPQiKjoOEwEig9H4wqhpuLSk4J2urAe%2BfVg%3D
```

If refresh token rotation is enabled for the connected app or external client app, the response includes a new refresh token. Here's an example JSON response if refresh token rotation is enabled.

```
{ 
"access_token":"00Dx0000000BV7z!AR8AQP0jITN80ESEsj5EbaZTFG0RNBaT1cyWk7T...",
"refresh_token":"CjAwRHgwMDAwMDAwQlY3eiFBUjhBUVAwaklUTjgwRVNFc2o1RWJhWl...",
"signature":"SSSbLO/gBhmmyNUvN18ODBDFYHzakxOMgqYtu+hDPsc=",
"scope":"id api refresh_token",
"instance_url":"https://yourInstance.salesforce.com/",
"id":"https://login.salesforce.com/id/00Dx0000000BV7z/005x00000012Q9P"
"token_type":"Bearer",
"issued_at":"1278448384422",
}
```

The following parameters can be included in the body of the response.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d91021e407">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d91021e410">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>access_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">OAuth token that a connected app uses to request access to a
              protected resource on behalf of the client application. Additional
              permissions in the form of scopes can accompany the access
              token.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>refresh_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">A new refresh token. Use the refresh token to get a new access
              token the next time you invoke the refresh token flow. This
              parameter is included only if you enable refresh token rotation for
              your connected app or external client app.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>token_type</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">A <code>Bearer</code> token type, which
              is used for all responses that include an access token.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>token_format</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">
              <p>If your connected app or external client app is enabled to issue
                JSON Web Token (JWT)-based access tokens, your response includes
                this parameter to indicate the format of the access token. The value
                is <code>jwt</code>.</p>
              <p style="margin-bottom:0;">This parameter isn't
                included if your app issues opaque access tokens.</p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>instance_url</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">A URL indicating the instance of the user’s org. For example:
              <code>https://<var>yourInstance</var>.salesforce.com/</code>.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>id</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">An identity URL that can be used to identify the user and to
              query for more information about the user. See <a href="https://help.salesforce.com/articleView?id=remoteaccess_using_openid.htm&amp;language=en_US" target="_blank">Identity
                URLs</a>.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>issued_at</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">Time stamp of when the signature was created in
              milliseconds.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>signature</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">Base64-encoded HMAC-SHA256 signature signed with the <code>client_secret</code>. The signature can
              include the concatenated ID and <code>issued_at value</code>, which you can use to verify that the
              identity URL hasn’t changed since the server sent it.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>sfdc_site_url</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">If the user is a member of an Experience Cloud site, the site URL
              is provided.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e407 ">
              <code>sfdc_site_id</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d91021e410 ">If the user is a member of an Experience Cloud site, the user’s
              site ID is provided.</td>

          </tr>
        </tbody>
      </table>

#### See Also

- [OAuth 2.0 Authorization Errors](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_flow_errors.htm&release=264.0.0&type=5 "Errors can occur during OAuth authorization. For example, a user denies access to the connected app or request parameters are incorrect. When errors occur, the authorizing server sends an error to the callback URL with an error code.")