---
schema_version: "1"
id: 51e9c28f2ad56701dec72da3cd62e2e7d30d1402b479af33220d042f7b0c5d16
title: OAuth 2.0 Web Server Flow for Web App Integration
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_oauth_web_server_flow.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 97cb81ed097d74171d45864cde872c08e8e2089cfa2ae5e65dac57c173f3dcb8
description: To integrate an external web app with the Salesforce API, use the OAuth 2.0 web server flow, which implements the OAuth 2.0 authorization code grant type. With this flow, the server hosting the web app must be able to protect the external client app’s identity, defined by the client ID and client secret.
products:
  - Security
  - Cross Cloud
release: "264"
---
# OAuth 2.0 Web Server Flow for Web App Integration

To integrate an external web app with the Salesforce API, use the OAuth 2.0 web server flow, which implements the [OAuth 2.0 authorization code grant type](https://tools.ietf.org/html/rfc6749#section-4.1). With this flow, the server hosting the web app must be able to protect the external client app’s identity, defined by the client ID and client secret.

### 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: all editions</td></tr></tbody></table>

We recommend that you use the web server flow with Proof Key for Code for Exchange (PKCE, pronounced pixy) in place of the user-agent flow or the username-password flow for special scenarios. Use the `code_challenge` and `code_verifier` parameters to implement PKCE with the web server flow. For more information on PKCE, see the [Internet Engineering Task Force (IETF.)](https://datatracker.ietf.org/doc/rfc7636/) We also recommend that you block all external client apps from using the user-agent flow or the username-password flow. For steps, see [Block Authorization Flows to Improve Security](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_disable_username_password_flow.htm&release=264.0.0&type=5 "The OAuth 2.0 user-agent and username-password flows are considered insecure and aren’t recommended. For better security, we strongly recommend that you block these flows in Salesforce to prevent developers from using them to build new integrations. If your org is created in Summer ‘23 or later, the username-password flow is blocked by default. You can enable the username-password flow if needed. If you have existing integrations that use the user-agent or username-password flow, update them to a more secure OAuth 2.0 flow. You can also block the Authorization Code and Credentials Flow, which is used to securely configure a headless login process. And you can block certain flows that don’t use the PKCE extension.").

Here’s an example use case for implementing the web server flow. You recently developed a web service that allows secure access to customer order status. The order status data is securely stored in your Salesforce CRM platform. To authorize Help Desk users to view a customer’s order status, you develop an Order Status app and configure it as an external client app with the web server flow.

- A Help Desk user clicks the Order Status web app.
- The external client app posts an authorization code request to the Salesforce authorization endpoint.
- The user is redirected to the Salesforce login page. After a successful login, the user is asked to approve the app’s access to order status data.
- After the user approves the Order Status app to access the data, Salesforce sends a callback to the Order Status app with an authorization code.
- The Order Status app passes the authorization code to the Salesforce token endpoint, requesting an access token.
- Salesforce validates the authorization code and sends back an access token that includes associated permissions in the form of scopes.
- The Order Status app sends a request back to Salesforce to access the order status data. The request includes the access token with associated scopes.
- Salesforce validates the access token and associated scopes.
- The Order Status app can access the protected data, and the customer’s order status is displayed in the app.
    
    ![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 access token becomes invalid, the external client app can use a refresh token to get a new access token.

Let’s take a closer look at each step of this authorization flow.

- [Request an Authorization Code](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5)
- [User Authenticates and Authorizes Access](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5)
- [Salesforce Grants Authorization Code](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5)
- [Request an Access Token](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5)
- [Salesforce Grants an Access Token](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_web_server_flow.htm&release=264.0.0&type=5)

## Request an Authorization Code

To initiate the OAuth 2.0 web server flow, the external web service—via the external client app—posts an authorization code request using the authorization code grant type to the Salesforce authorization endpoint. With an authorization code, the external client app can prove that it’s been authorized as a safe visitor to the site and that it has permission to request an access token.

The authorization code is in the form of an HTTP redirect.

```
https://MyDomainName.my.salesforce.com/services/oauth2/authorize?
client_id=3MVG9IHf89I1t8hrvswazsWedXWY0i1qK20PSFaInvUgLFB6vrcb9bbWFTSIHpO8G2jxBLJA6uZGyPFC5Aejq&
redirect_uri=https://www.mycustomerorderstatus.com/oauth2/callback&
response_type=code
```

Include these parameters in an authorization code request.

 
| Parameter | Description |
| --- | --- |
| `Request Header` | The Salesforce OAuth 2.0 authorization endpoint. External client apps send OAuth authorization requests to this endpoint. |
| `client_id` | The consumer key of the external client app. To access the consumer key, from the App Manager, find the external client app, and select **View** from the dropdown. Then click **Manage Consumer Details**. You’re sometimes prompted to verify your identity before you can view the consumer key. |
| `redirect_uri` | The URL where users are redirected after a successful authentication. The redirect URI must match one of the values in the external client app’s Callback URL field. Otherwise, the approval fails. You can find the redirect URI on the external client app’s OAuth Settings page. This value must be URL encoded. |
| `response_type` | The OAuth 2.0 grant type that the external client app requests. The value for this flow must be `code` to indicate that the external client app is requesting an authorization code. |

You can also include these parameters in an authorization code request.

<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="d25751e272">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d25751e275">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e272 ">
              <code>scope</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Permissions that define the type of protected resources an external client app
                can access. You assign scopes to an external client app when you build it, and
                they’re included with the OAuth tokens during the authorization flow. </p>
              <p style="margin-bottom:0;">If you
                don’t include this parameter, all scopes assigned to the external client app are
                requested. The scopes passed in this parameter must be a subset of the registered
                scopes. For valid parameters, see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&amp;release=264.0.0&amp;type=5" title="OAuth tokens authorize access to protected resources. Connected apps receive tokens on behalf of a client after authorization. Scopes further define the type of protected resources that the connected app can access. You assign scopes to a connected app when you build it, and they’re included with the OAuth tokens during the authorization flow.">OAuth Tokens and Scopes</a>.</p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">The developer name of a single sign-on (SSO) identity provider configured with
              a My Domain login URL or Experience Cloud site URL. You can use this parameter to
              create an SSO experience that feels like your app is integrated with the SSO
              provider. For example, you can use this parameter to offer SSO in a Headless
              Identity implementation. For more information, see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_native_sso.htm&amp;release=264.0.0&amp;type=5" title="With an optional parameter in the OAuth 2.0 web server flow and user-agent flow, you can build a single sign-on (SSO) experience that feels like your third-party app is integrated with an external identity provider. With this process, you link an OAuth flow to an SSO flow while maintaining control of the experience within your app. This parameter is supported for Experience Cloud sites, so you can use this capability to add SSO to a Headless Identity implementation. This parameter is also supported for My Domain.">Create a Native Single Sign-On Experience in Your App</a>.</td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">Any state that the external web service requests to be sent to the callback
              URL. This value must be URL encoded.</td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>A boolean value to determine whether the user is prompted for login and
                approval. The default value is <code>false</code>. If you
                set this parameter to <code>true</code>, one of these
                scenarios happens.</p>
              <ul>
                <li>If the user is logged in and has previously approved the client’s access,
                  Salesforce skips the approval step.</li>
                <li>If the user isn’t logged in or hasn’t previously approved the client’s access,
                  Salesforce immediately terminates with the <code>immediate_unsuccessful</code> error code.</li>
              </ul>
              <p style="margin-bottom:0;">The <code>immediate</code> option isn’t available
                for Experience Cloud sites.</p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Specifies the SHA256 hash value of the <code>code_verifier</code> value in the token request. Set this parameter to help
                prevent authorization code interception attacks. The value must be base64url-encoded
                as defined in <a href="https://tools.ietf.org/html/rfc4648#section-5" target="_blank"><samp class="filepath">https://tools.ietf.org/html/rfc4648#section-5</samp></a>.
              </p>
              <p>This parameter is required if a <code>code_verifier</code> is specified in the token request.</p>
              <ul>
                <li>If the <code>code_challenge</code> value is provided
                  in the authorization request and a <code>code_verifier</code> value is provided in the token request, Salesforce
                  compares the <code>code_challenge</code> to the <code>code_verifier</code>. If the <code>code_challenge</code> is invalid or doesn’t match, the login fails with the
                  <code>invalid_request</code> error code.
                </li>
                <li>If the <code>code_challenge</code> value is provided
                  in the authorization request, but a <code>code_verifier</code> value isn’t provided in the token request, the login
                  fails with the <code>invalid_grant</code> error
                  code.</li>
              </ul>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Changes the display type of the login and authorization pages. Salesforce
                supports these values.</p>
              <ul>
                <li><code>page</code>—Full-page authorization
                  screen (default).</li>
                <li><code>popup</code>—Compact dialog optimized for
                  modern web browser popups.</li>
                <li><code>touch</code>—Mobile-optimized dialog
                  designed for modern mobile devices, such as Android and iPhone.</li>
                <li><code>mobile</code>—Mobile-optimized dialog
                  designed for less capable devices, such as the BlackBerry operating system
                  5.</li>
              </ul>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Provides a valid username value to prepopulate the login page with the
                username, such as <code>login_hint=username@company.com</code>. If a user already has an active session
                in the browser, the <code>login_hint</code> parameter does
                nothing, and the active user session continues.</p>
              <p style="margin-bottom:0;">To pass the <code>login_hint</code> parameter for Experience Cloud sites,
                also pass the <code>prompt=login</code> parameter.
                Together, these parameters redirect the user to the login page with the correct
                login hint.</p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <span>Use with the <code>openid</code> scope to request a
                user ID token. The user ID token is returned in the response. This parameter is
                optional, but it helps to detect replay attacks.</span>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Specifies how the authorization server prompts the user for reauthentication
                and reapproval. Salesforce supports these values.</p>
              <ul>
                <li><code>login</code>—The authorization server
                  must prompt the user for reauthentication, forcing the user to log in
                  again.</li>
                <li><code>consent</code>—The authorization server
                  must prompt the user for reapproval before returning information to the
                  client.</li>
                <li><code>select_account</code>—If presented, take
                  one of these actions.<ul>
                    <li>If zero or one hint is available and the user is logged in, show the
                      approval page without prompting for login.</li>
                    <li>If zero or one hint is available and the user isn’t logged in, prompt for
                      login.</li>
                    <li>If more than one hint is available, show the account chooser.</li>
                  </ul>
                </li>
              </ul>
              <p style="margin-bottom:0;">You can pass <code>login</code> and <code>consent</code> values, separated by a space, to require
                the user to log in and reauthenticate. For example: <code>?prompt=login%20consent</code></p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e272 "><code>Uvid-Hint</code> header</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>Optionally, to connect this flow to the headless guest flow, you can include a
                <code>Uvid-Hint</code> header with a JWT-based access token containing a UVID
                value, which is a Version 4 universally unique identifier (UUID) that your app
                generates and manages. To get an access token with a UVID, you must enable your
                external client app to issue JWT-based access tokens and implement the headless
                guest flow on your app.
              </p>
              <p style="margin-bottom:0;">If you implement the guest user flow on your app, you can
                optionally use this header to pass in a JSON Web Token (JWT)-based access token
                containing a unique visitor ID (UVID) tied to a guest user’s identity. By passing
                the UVID into a named user flow, you can carry contextual information from a guest
                user session, like the user’s cookie preferences, into a named user
                session.</p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e272 "><code>uvid_hint</code> body parameter</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e275 ">
              <p>A plain <code>UVID</code> value, which is a Version 4 UUID that your app
                generates and manages. To get a <code>UVID</code>, you must enable your external
                client app to issue JWT-based access tokens and implement the headless guest flow on
                your app. You can optionally use this parameter to pass in a UVID value tied to a
                guest user’s identity, carrying contextual information from a guest user session
                into a named user session.</p>
              <p style="margin-bottom:0;">Instead of passing the UVID in the request body, you
                can also pass it in a JWT-based token with a UVID via the
                <code>UVID-Hint</code> header.
              </p>
            </td>

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

## User Authenticates and Authorizes Access

Before Salesforce provides authorization codes to external client apps, the authenticating users are asked to log in to Salesforce.

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

After a successful login, Salesforce redirects users to the approval page to grant access to the app.

![Approval page to grant access to the external client app](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/identity/images/remoteaccess_authflow_authorize.png)

If users previously approved access, it isn’t necessary to approve access again.

## Salesforce Grants Authorization Code

After users approve access to an external client app, Salesforce redirects users to the callback URL, where they can view the callback with an authorization code.

```
https://www.mycustomerorderstatus.com/oauth2/callback?
code=aPrx4sgoM2Nd1zWeFVlOWveD0HhYmiDiLmlLnXEBgX01tpVOQMWVSUuafFPHu3kCSjzk4CUTZg==
```

- The first part of the callback is the external client app’s callback URL: `https://www.mycustomerorderstatus.com/oauth2/callback`.
- The second part is the authorization code that the external client app uses to get an access token: `code=aPrx4sgoM2Nd1zWeFVlOWveD0HhYmiDiLmlLnXEBgX01tpVOQMWVSUuafFPHu3kCSjzk4CUTZg==`. The authorization code expires after 15 minutes.

If the `state` parameter is included in the original query string, the specified state is passed into the approval step.

## Request an Access Token

To request an access token, the external client app passes the authorization code to the Salesforce token endpoint as an HTTP POST.

```
POST /services/oauth2/token HTTP/1.1
Host: mycompany.my.salesforce.com
Content-length: 307
Content-type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=aPrxhgZ2MIpkSy0aOdn07LjKFvsFOis6RGcWXz7p8JQCjcqfed5NQLe7sxWwMY_JQFuLwHRaRA==&
client_id=3MVG9IHf89I1t8hrvswazsWedXWY0iqK20PSFaInvUgLFB6vrcb9bbWFTSIHpO8G2jxBLJA6uZGyPFC5Aejq&
client_secret=*******************&
redirect_uri=https://www.mycustomerorderstatus.com/oauth2/callback
```

The POST in the example contains 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="d25751e689">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d25751e692">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e689 ">
              <code>Request Header</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">
              <p>The request header can contain these parameters.</p>
              <ul>
                <li>The Salesforce OAuth 2.0 endpoint. External client apps send OAuth token requests to this
                  endpoint.</li>
                <li>The URL of the hosting service.</li>
                <li>The length of the request’s content.</li>
                <li>The requested format of the returned response. These formats are supported.<ul>
                    <li><code>Accept: application/json</code></li>
                    <li><code>Accept: application/xml</code></li>
                    <li><code>Accept:
                          application/x-www-form-urlencoded</code></li>
                  </ul>
                </li>
              </ul>
              <p>The request header also supports these parameters.</p>
              <ul>
                <li>The <code>*/*</code> wildcard is accepted and returns
                  JSON.</li>
                <li>A list of values, which is checked left to right. For example: <code>application/xml,application/json,application/html,*/*</code> returns
                  XML.</li>
              </ul>
              <p style="margin-bottom:0;">The <code>format</code> parameter takes precedence
                over the access request header.</p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">The type of validation that the external client app can provide to prove it’s a
              safe visitor. For the web server flow, the value must be
              <code>authorization_code</code>.
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">A temporary authorization code received from the authorization server. The
              external client app uses this code in exchange for an access token. This type of
              OAuth 2.0 flow is a secure way to pass the access token back to the
              application.</td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">The consumer key of the external client app. To access the consumer key, from
              the App Manager, find the external client 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="d25751e689 ">
              <code>client_secret</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">
              <p>
                <span>The consumer secret of the external client app. To access the consumer secret,
                  from the App Manager, find the external client 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.</span>
              </p>
              <p style="margin-bottom:0;">This parameter is required unless the external client app doesn’t have
                <strong class="uicontrol">Require Secret for Web Server Flow</strong> enabled. If a
                <code>client_secret</code> isn’t required, and the external client app sends
                it in the authorization request, Salesforce attempts to validate it anyway.
              </p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e692 ">The URL where users are redirected after a successful authentication. The
              redirect URI must match one of the values in the external client app’s Callback URL
              field. Otherwise, the approval fails. You can find the redirect URI on the external
              client app’s OAuth Settings page or from the external client app’s definition. This
              value must be URL encoded.</td>

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

You can also include these parameters.

<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="d25751e852">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d25751e855">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e852 ">
              <code>client_assertion</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e855 ">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;release=264.0.0&amp;type=5">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="d25751e852 ">
              <code>client_assertion_type</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e855 ">
              <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="d25751e852 ">
              <code>code_verifier</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e855 ">
              <p>
                <span id="remoteaccess_oauth_web_server_flow__code_verifier_parameter_description"><a name="remoteaccess_oauth_web_server_flow__code_verifier_parameter_description"><!-- --></a>Required only if a
                  <samp class="parmname">code_challenge</samp> parameter was specified in the authorization
                  request. Specifies 128 bytes of random data with high entropy to make guessing the
                  <code>code</code> value difficult. Set this parameter to
                  help prevent authorization code interception attacks. The value must be
                  base64url-encoded as defined in <a href="https://tools.ietf.org/html/rfc4648#section-5" target="_blank"><samp class="filepath">https://tools.ietf.org/html/rfc4648#section-5</samp></a>.</span>
              </p>
              <ul>
                <li>If the <samp class="parmname">code_verifier</samp> value is provided in the token
                  request and a <samp class="parmname">code_challenge</samp> value is in the authorization
                  request, Salesforce compares the <samp class="parmname">code_verifier</samp> to the
                  <samp class="parmname">code_challenge</samp>. If the <samp class="parmname">code_verifier</samp>
                  is invalid or doesn’t match, the login fails with the <code>invalid_grant</code> error code.
                </li>

                <li>If the <samp class="parmname">code_verifier</samp> value is provided in the token
                  request, but a <samp class="parmname">code_challenge</samp> value isn’t provided in the
                  authorization request, the login fails with the <code>invalid_grant</code> error code.</li>

              </ul>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e855 ">
              <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>

Use `client_assertion` instead of `client_secret`.

If you provide a `client_assertion` instead of a `client_secret`, the value of `client_assertion` must include these parameters.

- `iss`—The `client_id` from the external client app definition.
- `sub`—The `client_id` from the external client app definition.
- `aud`—The token servlet URL: https://hostname/services/oauth2/token.
- `exp`—The expiration time of the assertion within 5 minutes, expressed as the number of seconds from 1970-01-01T0:0:0Z measured in UTC.

The `client_assertion` must also be signed with the private key associated with the OAuth consumer’s uploaded certificate. Only the RS256 algorithm is supported. For the `private_key_jwt` client authentication method, see the [OpenID Connect specifications](http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication).

HTTP Basic Authentication Scheme

Instead of sending client credentials as parameters in the body of the POST, Salesforce supports 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) document.

This example shows an access 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: mycompany.my.salesforce.com
Authorization: Basic client_id=3MVG9IHf89I1t8hrvswazsWedXWY0iqK20PSFaInvUgLFB6vrcb9bbWFTSIHpO8G2jxBLJA6uZGyPFC5Aejq&
client_secret=*******************&

grant_type=authorization_code&code=aPrxsmIEeqM9PiQroGEWx1UiMQd95_5JUZ
VEhsOFhS8EVvbfYBBJli2W5fn3zbo.8hojaNW_1g%3D%3D&
redirect_uri=https%3A%2F%2Fwww.mysite.com%2Fcode_callback.jsp
```

![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.

## Salesforce Grants an Access Token

After Salesforce validates the external client app’s credentials, it returns a response with the access token. In this example, the response is in a JSON format.

```
{
"access_token": "00DB0000000TfcR!AQQAQFhoK8vTMg_rKA.esrJ2bCs.OOIjJgl.9Cx6O7KqjZmHMLOyVb.U61BU9tm4xRusf7d3fD1P9oefzqS6i9sJMPWj48IK",
"signature": "d/SxeYBxH0GSVko0HMgcUxuZy0PA2cDDz1u7g7JtDHw=",
"scope": "web openid",
"id_token": "eyJraWQiOiIyMjAiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiSVBRNkJOTjlvUnUyazdaYnYwbkZrUSIsInN1YiI6Imh0dHBzOi8vbG9...",
"instance_url": "https://mycompany.my.salesforce.com",
"id": "https://login.salesforce.com/id/00DB0000000TfcRMAS/005B0000005Bk90IAC",
"token_type": "Bearer",
"issued_at": "1558553873237"
}
```

The response includes these parameters.

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e1153 ">
              <span id="remoteaccess_oauth_web_server_flow__access_token_desc"><a name="remoteaccess_oauth_web_server_flow__access_token_desc"><!-- --></a>OAuth token that an external client 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.</span>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" id="remoteaccess_oauth_web_server_flow__signature_desc" style="vertical-align:top;" headers="d25751e1153 ">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="d25751e1150 ">
              <code>scope</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" id="remoteaccess_oauth_web_server_flow__scope_return_desc" style="vertical-align:top;" headers="d25751e1153 ">
              <p>The scopes associated with the access token.</p>
              <p>Scopes
                further define the type of protected resources that the client can access. You
                assign scopes to an external client app when you build it, and they’re included
                with the OAuth tokens during the authorization flow. </p>
              <p style="margin-bottom:0;">For valid parameters,
                see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&amp;release=264.0.0&amp;type=5" title="OAuth tokens authorize access to protected resources. Connected apps receive tokens on behalf of a client after authorization. Scopes further define the type of protected resources that the connected app can access. You assign scopes to a connected app when you build it, and they’re included with the OAuth tokens during the authorization flow.">OAuth Tokens and Scopes</a>.</p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" id="remoteaccess_oauth_web_server_flow__id_token_desc" style="vertical-align:top;" headers="d25751e1153 ">
              <p>A signed data structure that contains authenticated user
                attributes, including a unique identifier for the user and a timestamp indicating
                when the token was issued. It also identifies the requesting client app. See <a href="http://openid.net/specs/openid-connect-basic-1_0-28.html" target="_blank">OpenID Connect
                  specifications</a>.</p>
              <p style="margin-bottom:0;">This parameter is returned if the
                <samp class="parmname">scope</samp> parameter includes <code>openid</code>.
              </p>
            </td>

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

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

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e1153 ">
              <span id="remoteaccess_oauth_web_server_flow__id_url_return_desc"><a name="remoteaccess_oauth_web_server_flow__id_url_return_desc"><!-- --></a>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>.</span>
            </td>

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

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

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

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

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

The response can also contain these parameters.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col style="width:28.265021092235777%">
          <col style="width:71.73497890776423%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d25751e1333">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d25751e1336">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" id="remoteaccess_oauth_web_server_flow__refresh_token" style="vertical-align:top;" headers="d25751e1333 ">
              <code>refresh_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e1336 ">
              <p>
                <span id="remoteaccess_oauth_web_server_flow__refresh_token_desc_1"><a name="remoteaccess_oauth_web_server_flow__refresh_token_desc_1"><!-- --></a>Token obtained from the web server, user-agent, or
                  hybrid app token flow. This value is a secret. Take appropriate measures to
                  protect it. </span>
              </p>
              <p style="margin-bottom:0;">
                <span id="remoteaccess_oauth_web_server_flow__refresh_token_desc_2"><a name="remoteaccess_oauth_web_server_flow__refresh_token_desc_2"><!-- --></a>This parameter is returned only if your external
                  client app is set up with a <code>refresh_token</code> scope.</span>
              </p>
            </td>

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

            <td data-label="Description" class="slds-cell-wrap" id="remoteaccess_oauth_web_server_flow__sfdc_community_url_desc" style="vertical-align:top;" headers="d25751e1336 ">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" id="remoteaccess_oauth_web_server_flow__sfdc_community_id" style="vertical-align:top;" headers="d25751e1333 ">
              <code>sfdc_site_id</code>
            </td>

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

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

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d25751e1336 ">
              <span id="remoteaccess_oauth_web_server_flow__state_return_desc"><a name="remoteaccess_oauth_web_server_flow__state_return_desc"><!-- --></a>The state requested by the client. This value is
                included only if the <code>state</code> parameter is
                included in the original query string.</span>
            </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.")