---
schema_version: "1"
id: 4661e93c9953bb7fbcda595c6b25f7ff83964dec872f6d3f5840f1bb3f0a8de2
title: "Headless Identity APIs: Headless Forgot Password Flow for Customers and Partners"
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_headless_forgot_password_flow.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_headless_forgot_password_flow.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 60c72a0a71bca8a96a1dd809ce9e0b32e7388e0380c1d54a38e1ab55028cf506
description: Set up a headless password reset process on your app using the Headless Forgot Password Flow, which calls Headless Forgot Password API. Use this flow along with other headless flows to provide native identity experiences. With this flow, a user who has forgotten their password can verify their identity and create a password without ever leaving the branded experience of your app.
products:
  - Security
  - Cross Cloud
release: "264"
---
# Headless Identity APIs: Headless Forgot Password Flow for Customers and Partners

Set up a headless password reset process on your app using the Headless Forgot Password Flow, which calls Headless Forgot Password API. Use this flow along with other headless flows to provide native identity experiences. With this flow, a user who has forgotten their password can verify their identity and create a password without ever leaving the branded experience of your app.

### 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 (not available in all orgs) and Lightning Experience</td></tr></tbody><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>Enterprise</strong>, <strong>Unlimited</strong>, and <strong>Developer</strong> Editions.</td></tr></tbody></table>

This help content describes how to set up the flow and how it works. To set up an end-to-end example implementation, see the Headless Identity Implementation Guide.

To ensure that you complete all prerequisite steps, see [Headless Identity Implementation Checklists](https://help.salesforce.com/s/articleView?id=xcloud.headless_identity_implementation_checklist.htm&type=5&language=en_US).

The Headless Forgot Password Flow resolves a common situation. When a user forgets their password and can’t log in, this flow provides the functionality to reset it without disrupting your app’s branded experience.

Because you manage Salesforce Customer Identity through Experience Cloud sites, you can configure the Headless Forgot Password Flow only for customers and partners using an Experience Cloud site subdomain, such as https://MyExperienceCloudSite.my.site.com. You can’t set up this flow for employees who access Experience Cloud sites or for employees accessing the Salesforce platform with login.salesforce.com or your org-specific My Domain login URL.

The Headless Forgot Password Flow works similarly for private clients, such as client-server apps, and public clients, such as single-page apps or mobile apps. The main difference is the security settings that you enable for private clients and public clients. These security settings control which parameters you’re required to pass in the initial password reset request. There are two security settings, both on the Experience Cloud Login & Registration page.

- Require authentication to access this API
- Require reCAPTCHA to access this API

For private clients, at minimum, we recommend that you enable **Require authentication to access this API**. With this setting enabled, you must include an access token issued to an internal integration user in your requests to Headless Forgot Password API. The access token must include the `forgot_password` scope. For extra protection, you can also enable **Require RECAPTCHA to access this API**.

For public clients like mobile apps, we recommend that you enable **Require reCAPTCHA to access this API**. With this setting enabled, you must include a reCAPTCHA token in your initial request to Headless Forgot Password API. We don’t recommend enabling **Require authentication to access this API** because a public client can’t keep the access token secret.

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

Public clients must also implement an API gateway between the client and Salesforce to maintain security.

To expand your email template options for the one-time password (OTP) email sent to end users during the flow, opt in to email template allowlisting and create an allowlist with custom templates. See [Use Multiple Email Templates for Headless Flows](https://help.salesforce.com/s/articleView?id=sf.headless_identity_email_template_allowlist.htm&language=en_US).

By default, users enter their username to reset their password. To give users more options, set up headless user discovery. For example, develop a flow where users enter their email address, phone number, or even an order number. See [Headless Login without a Username](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_headless_discovery.htm&type=5&language=en_US).

This diagram shows how your app interacts with Salesforce to reset a password.

![The flow includes an initial request, a response from Salesforce, an email, a second request, and a final success message from Salesforce.](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/identity/images/headless_forgot_password_flow.png)

Let’s take a closer look at the steps in this flow that involve interactions between your user, your app, and Salesforce.

- Your client requests a password reset (1).
- Salesforce returns a success message (2) and checks that the user exists and is verified.
- Salesforce generates and emails a one-time password (3).
- Your client submits the new password (4).
- Salesforce verifies the passwords and returns a success message (5).

## Your Client Requests a Password Reset

After your user starts the password reset process, your client sends a POST request to the headless forgot password endpoint on your Experience Cloud site (1).

Here’s the URI for the POST request.

```
/services/auth/headless/forgot_password
```

Include these headers in the request.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Initialize Password Reset: Request Headers">
        <caption>Initialize Password Reset: Request Headers</caption>
        <colgroup>
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e211">Header</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e214">Required?</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e217">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Header" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e211 ">
              <code>Authorization: Bearer</code>
            </td>

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e214 ">
              <p>Required if you enable <strong class="uicontrol">Require authentication to access this
                  API</strong> on the Experience Cloud Login &amp; Registration page. </p>
              <p>For private
                clients, we strongly recommend that you always enable this setting.</p>
              <p style="margin-bottom:0;">For public
                clients, we never recommend enabling this setting.</p>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e217 ">Contains an access token issued to an internal integration user. To get the access
              token, use any standard OAuth flow that Salesforce supports. Ensure that you assign
              the&nbsp;<code>forgot_password</code>&nbsp;scope to the connected app issuing
              the token, or pass it as a parameter during the OAuth flow.</td>

          </tr>
          <tr class="">
            <td data-label="Header" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e211 ">
              <code>Content-Type</code>
            </td>

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e214 ">No.</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e217 ">Specifies the format of your request, such as <code>application/json</code>.</td>

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

Include these parameters in the request body.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Initialize Password Reset: Request Body Parameters">
        <caption>Initialize Password Reset: Request Body Parameters</caption>
        <colgroup>
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e290">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e293">Required?</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e296">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e290 ">
              <code>username</code>
            </td>

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">Required if you aren't using headless user discovery.</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">The username for the account.</td>

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

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">Required if you're using a headless user discovery Apex handler.</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">An identifier that your Apex handler uses to find a user's Salesforce account. For
              example, collect a user's order number in your app and pass it in the <code>login_hint</code> parameter. We send the <code>login_hint</code> value straight to your Apex handler.</td>

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

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">
              <p>Required if you're using a headless user discovery handler that handles custom data.
                For example, if you're also using the handler with a login flow that handles custom data,
                you must pass custom data in the forgot password flow.</p>
              <p style="margin-bottom:0;">Otherwise, it's optional but can be
                useful to help your handler find the user.</p>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">A JSON string containing additional data that your Apex headless discovery handler
              uses to find a user's Salesforce account. For example, pass information about the user's
              locale.</td>

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

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">No.</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">
              <p>The custom email template developer name.</p>
              <p>If you enable <strong class="uicontrol">Use only
                  allowlisted email templates</strong> in your Experience Cloud settings, then this
                parameter can include only an email template from the allowlist.</p>
              <p>If you don’t enable
                email template allowlisting, this parameter can include any template in your org.</p>
              <p>To
                control the language for a custom email template, create a template in the desired
                language.</p>
              <p style="margin-bottom:0;">If you don’t include this parameter, Salesforce uses the email template
                configured in your Experience Cloud settings, regardless of whether email template
                allowlisting is enabled. With this option, Salesforce determines the language from the
                user’s settings. See <a href="https://help.salesforce.com/s/articleView?id=xcloud.admin_language_locale_currency.htm&amp;type=5&amp;language=en_US" target="_blank">Language, Locale, and Currency
                  Settings</a>.</p>
            </td>

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

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">
              <p>Required if these conditions apply to you.</p>
              <ul>
                <li>You enabled <strong class="uicontrol">Require reCAPTCHA to access this API</strong> on the
                  Experience Cloud Login &amp; Registration page. For public clients, we strongly recommend
                  that you always enable this setting. For private clients, enable this setting as an extra
                  layer of security in addition to enabling <strong class="uicontrol">Require authentication to access this
                    API</strong>.</li>
                <li>You're using reCAPTCHA v2 or v3.</li>
              </ul>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">An encrypted token issued by the Google reCAPTCHA API when a user completes a
              reCAPTCHA challenge.</td>

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

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e293 ">
              <p>Required if these conditions apply to you:</p>
              <ul>
                <li>You enabled <strong class="uicontrol">Require reCAPTCHA to access this API</strong> on the
                  Experience Cloud Login &amp; Registration settings.</li>

                <li>You're using reCAPTCHA Enterprise.</li>

              </ul>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e296 ">
              <p>A JSON object containing these subparameters.</p>
              <ul>
                <li><code>token</code>—An encrypted token issued by the Google
                  reCAPTCHA API when a user completes a reCAPTCHA challenge.</li>
                <li><code>siteKey</code>—The Google reCAPTCHA site key. </li>
                <li>(Optional)<code>expectedAction</code>—The action that you
                  expect the user to take to initiate reCAPTCHA, such as <code>login</code>. This parameter maps to Google's <code>action</code> parameter.</li>
                <li><code>projectId</code>—The project ID from Google.</li>
              </ul>
              <p style="margin-bottom:0;">For more information, see <a href="https://cloud.google.com/recaptcha/docs/setup-overview-web" target="_blank">Google's reCAPTCHA documentation</a>.</p>
            </td>

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

Here’s an example request for a public client that’s using a custom email template. It includes a reCAPTCHA token for security and an `emailtemplate` parameter with the developer name of a custom template.

```json
POST /services/auth/headless/forgot_password HTTP/1.1
Host: MyDomainName.my.site.com
Content-Type: application/json
{
    "username":"lhansen@example.com",,
    "emailtemplate":"unfiled$public/SalesNewCustomerEmail",
    "recaptcha": "<recaptcha token>"
}
```

Here’s an example request for a private client that’s using the default email template. It includes an access token for security.

```
POST /services/auth/headless/forgot_password HTTP/1.1
Host: MyDomainName.my.site.com
Authorization: Bearer 00DR****************
Content-Type: application/json

{
    "username": "lhansen@example.com"
}
```

Here's an example request for a private client that uses headless user discovery.

```
POST /services/auth/headless/forgot_password HTTP/1.1
Host: MyDomainName.my.site.com
Authorization: Bearer 00DR****************
Content-Type: application/json

{
    "login_hint": "<user identifier such as email address, phone number, order number>",
    "customdata": {
        "firstName": "Lyle",
        "lastName": "Hansen"
    }
}
```

## (Optional) Headless User Discovery Handler Finds the User

If you're using a headless user discovery handler, the handler takes the `login_hint` and `customdata` parameters and finds the associated user. The handler confirms that the email address or phone number for the user is verified.

For an example handler, see [Auth.HeadlessUserDiscoveryHandler](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_interface_Auth_HeadlessUserDiscoveryHandler.htm).

## Salesforce Returns a Success Message and Verifies the Username

When Salesforce successfully receives the forgot password request, it sends a success message to the client (2). If you're not using a headless discovery handler, Salesforce then verifies that the username matches an account. If the username doesn’t match an account, the flow stops.

Here’s an example of a successful response.

```
{
    "status": "success",
    "status_code": "otp_sent"
}
```

If the request fails, Salesforce returns an error message describing the request. For most errors, Salesforce returns the error message in this format.

```
{
"status_code": "<error code>",
"<error name>": "<error description>",
"status": "failed"
}
```

For example, if the client uses the wrong type of HTTPS request, Salesforce returns this error response.

```
{
"status_code": "post_required",
"invalid request": "use a POST request",
"status": "failed"
}
```

For the `invalid_recaptcha` error code, the response includes additional information from Google’s reCAPTCHA service. Here’s how these responses are formatted.

```
{
"status_code": "invalid_recaptcha",
"invalid_request: "invalid reCAPTCHA token",
"status": "failed",
"recaptcha_response": {
    "success": <true or false>,
    "challenge_ts": <timestamp of the challenge in ISO format (yyyy-MM-dd'T'HH:mm:ssZZ)>,
    "hostname": "<host name of the client where the reCAPTCHA was solved>",
    "error-codes": [<error codes from Google reCAPTCHA...>]
    }
}
```

Here’s an overview of the error responses.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Initialize Password Reset: Errors">
        <caption>Initialize Password Reset: Errors</caption>
        <colgroup>
          <col style="width:25%">
          <col style="width:25%">
          <col style="width:25%">
          <col style="width:25%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e581">Error Code</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e584">Error Name</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e587">Error Description</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e590">Details and Resolution</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>authentication_req</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>include an authentication header</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">You get this error if you enable the <strong class="uicontrol">Require authentication to access this
                API</strong> setting (always recommended for private clients) and you don’t send the
              access token correctly. Send the access token in an <code>Authorization:Bearer</code> header.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>headless_forgot_password_disabled</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_experience</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>enable the headless forgot password flow</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">Turn on <strong class="uicontrol">Allow password reset via the Headless Forgot Password
                Flow</strong> in your Experience Cloud settings. See <a href="https://help.salesforce.com/s/articleView?id=xcloud.configure_headless_forgot_password_flow.htm&amp;type=5&amp;language=en_US" target="_blank">Configure Experience Cloud Settings for
                the Headless Forgot Password Flow</a>.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>https_required</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>use a URL that starts with HTTPS</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">The request doesn’t conform to the HTTPS protocol. Review the <a href="https://datatracker.ietf.org/doc/html/rfc2616" target="_blank">Hyptertext Transfer Protocol specification</a>, update the request, and resend
              it.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>invalid_authorization</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>authentication failure</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">You get this error if you enabled the <strong class="uicontrol">Require authentication to access this
                API</strong> setting (always recommended for private clients) and the access token
              included in the request isn’t valid. For example, the access token is expired or doesn’t
              include the <code>forgot_password</code> scope. Check the access
              token and get a new one if necessary.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>invalid_domain</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>invalid domain</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">Requests to this endpoint are supported only for Experience Cloud site
              domains.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>invalid_params</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>invalid parameters</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">The request contains unsupported parameters, or the parameters aren’t formatted
              correctly. Review the supported header and body parameters and example requests for
              initializing password reset.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>invalid_recaptcha</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>invalid reCAPTCHA token</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">
              <p>For this error, the response includes an extra <code>recaptcha_response</code> claim that includes the specific reCAPTCHA error from Google.
              </p>
              <p>For more information on specific errors, see these resources in Google’s
                documentation.</p>
              <ul>
                <li><a href="https://developers.google.com/recaptcha/docs/verify" target="_blank">reCAPTCHA v2 and v3</a></li>
                <li><a href="https://cloud.google.com/recaptcha-enterprise/docs/reference/android/com/google/android/recaptcha/RecaptchaErrorCode" target="_blank">reCAPTCHA Enterprise</a></li>
              </ul>
            </td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>invalid_template</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_param</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>invalid email template</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">Confirm that the client is sending the developer name of a custom email template in
              the <code>emailtemplate</code> parameter.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>missing_auth_params</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>include an authentication header or reCAPTCHA
         parameter</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">Requests to this endpoint must include, at minimum, either an access token or a
              reCAPTCHA token, depending on your app type and Experience Cloud settings. Review <a href="https://help.salesforce.com/s/articleView?id=xcloud.configure_headless_forgot_password_flow.htm&amp;type=5&amp;language=en_US" target="_blank">Configure Experience Cloud Settings for
                the Headless Forgot Password Flow</a> and update the request to match your
              settings.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>not_allowed_template</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_param</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>email template not allowlisted</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">You get this error if you enable email template allowlisting and the value in the
              <code>emailtemplate</code> parameter isn’t part of the allowlist.
              For more information about allowlisting, see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_headless_email_template_allowlist.htm&amp;type=5&amp;language=en_US" target="_blank">Use Multiple Email Templates for
                Headless Flows</a>.
            </td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>otp_generation_failed</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>otp_error</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>OTP generation failed</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">Salesforce couldn’t generate an OTP. Try sending the request again.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>post_required</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>use a POST request</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">The request type isn’t supported. Send an HTTPS POST request.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>recaptcha_req</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_request</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>include a reCAPTCHA parameter</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">You get this error if you enable <strong class="uicontrol">Require reCAPTCHA to access this
                API</strong> in your Experience Cloud site settings and the request doesn’t include a
              reCAPTCHA token in the <code>recaptcha</code> parameter. Include a
              reCAPTCHA token.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>unknown_error</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>unknown_error</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>retry your request</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">There was a problem sending the request, but we don’t know what went wrong. Try
              checking your internet connection, refreshing the page, and resending the request.</td>

          </tr>
          <tr class="">
            <td data-label="Error Code" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e581 ">
              <code>user_account_locked</code>
            </td>

            <td data-label="Error Name" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e584 ">
              <code>invalid_user</code>
            </td>

            <td data-label="Error Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e587 ">
              <code>user account is locked</code>
            </td>

            <td data-label="Details and Resolution" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e590 ">The user is locked out of their account. To restore their access, <a href="https://help.salesforce.com/s/articleView?id=platform.users_unlock.htm&amp;type=5&amp;language=en_US" target="_blank">unlock the user</a>.</td>

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

## Salesforce Generates and Emails a One-Time Password

Salesforce verifies that an account with the user’s username exists in the system. If the account exists, it generates a one-time password and sends it in an email (3) to the email address on file. This email is generated using either the default email template or by referencing a custom template from the `emailtemplate` parameter in the initial request. For information about customizing the email template, see [Customize Email Sent from Experience Cloud Sites](https://help.salesforce.com/s/articleView?id=experience.networks_customize_email.htm&type=5&language=en_US).

## Your Client Submits the New Password

When the client receives the success message from Salesforce, the client natively displays a password reset page to the user. This page must include fields for the one-time password and the user’s new password. The new password is subject to the Salesforce password requirements. After the user fills in these fields, the client sends another the username, OTP, and new password in another POST request to the forgot password endpoint (4).

Include these headers in the request.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Change Password: Request Headers">
        <caption>Change Password: Request Headers</caption>
        <colgroup>
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
          <col style="width:33.33333333333333%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e1069">Header</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e1072">Required?</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d79404e1075">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Header" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1069 ">
              <code>Authorization: Bearer</code>
            </td>

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1072 ">
              <p>Required if you enable <strong class="uicontrol">Require authentication to access this
                  API</strong> on the Experience Cloud Login &amp; Registration page. </p>
              <p>For private
                clients, we strongly recommend that you always enable this setting.</p>
              <p style="margin-bottom:0;">For public
                clients, we never recommend enabling this setting.</p>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1075 ">Contains an access token issued to an internal integration user. To get the access
              token, you can use any standard OAuth flow that Salesforce supports. Ensure that you assign
              the&nbsp;<code>forgot_password</code>&nbsp;scope to the connected app issuing
              the token, or pass it as a parameter during the OAuth flow.</td>

          </tr>
          <tr class="">
            <td data-label="Header" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1069 ">
              <code>Content-Type</code>
            </td>

            <td data-label="Required?" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1072 ">No.</td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d79404e1075 ">Specifies the format of your request, such as <code>application/json</code>.</td>

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

Include these parameters in the request body.

Change Password: Request Body Parameters   
| Parameter | Required? | Description |
| --- | --- | --- |
| `username` | Required if you're not using a headless user discovery handler. | The username for the account. |
| `login_hint` | Required if you are using a headless user discovery handler. | The identifier that your Apex handler used to find the user's Salesforce account. |
| `otp` | Yes. | The one-time password that Salesforce generated and emailed to the user. |
| `newpassword` | Yes. | The new password that the user created. |

Here’s an example request for a private client.

```json
POST /services/auth/headless/forgot_password HTTP/1.1
Host: MyDomainName.my.site.com
Authorization: Bearer 00DR****************
Content-Type: application/json

{
"username": "lhansen@example.com",
"otp" : "123abc",
"newpassword" : "abcd1234"
}
```

Here’s a similar request for public clients that doesn’t include an access token. Because the reCAPTCHA token was sent in the initial request, it’s not required in this one.

```
POST /services/auth/headless/forgot_password HTTP/1.1
Host: MyDomainName.my.site.com
Content-Type: application/json
{
"username": "lhansen@example.com",
"otp" : "123abc",
"newpassword" : "abcd1234"
}
```

## Salesforce Verifies the Passwords and Returns a Success Message

When Salesforce receives the password request, it verifies that the one-time password is valid, and it checks that the new password meets the requirements. If these two criteria are met, it sets the new password. After the password is changed, Salesforce sends a success message to the client (5). Here’s what the success message looks like.

```
{
    "status": "success",
    "status_code": "success"
}
```

Your client must notify the user that the change has been accepted and that they can log in with their new password.

![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 sends an incorrect OTP or the new password doesn’t meet the standard Salesforce security requirements, the password reset fails. If the password reset fails, your client can make a set number of attempts to reset the password using the same OTP. You control the maximum number of attempts in your Experience Cloud settings. After too many failed attempts, your client must send a new initial reset password request so that a new one-time password can be generated and emailed to your user.

If the password change isn’t successful, Salesforce returns an error response in this format.

```
{
"status_code": "<error code>",
"<error name>": "<error description>",
"status": "failed"
}
```

Here’s an overview of the errors for this request.

Change Password: Errors    
| Error Code | Error Name | Error Description | Details and Resolution |
| --- | --- | --- | --- |
| `headless_forgot_password_disabled` | `invalid_experience` | `enable the headless forgot password flow` | Turn on **Allow password reset via the Headless Forgot Password Flow** in your Experience Cloud settings. See [Configure Experience Cloud Settings for the Headless Forgot Password Flow](https://help.salesforce.com/s/articleView?id=xcloud.configure_headless_forgot_password_flow.htm&type=5&language=en_US). |
| `https_required` | `invalid_request` | `use a URL that starts with HTTPS` | The request doesn’t conform to the HTTPS protocol. Review the [Hyptertext Transfer Protocol specification](https://datatracker.ietf.org/doc/html/rfc2616), update the request, and resend it. |
| `invalid_domain` | `invalid_request` | `invalid domain` | Requests to this endpoint are supported only for Experience Cloud site domains. |
| `invalid_otp` | `otp_error` | `invalid OTP` | The OTP doesn’t match what Salesforce sent to the user, or it’s expired. Check the OTP and request a new one if necessary. |
| `invalid_params` | `invalid_request` | `invalid parameters` | The request contains unsupported parameters, or the parameters aren’t formatted correctly. Review the supported header and body parameters and example requests for changing the password. |
| `password_policy_check_failure` | `password error` | `password does not follow policy` | The password doesn’t follow the password policy configured for your org. In addition to the policy you set, Salesforce enforces some password requirements for all user passwords. See [Set Password Policies](https://help.salesforce.com/s/articleView?id=xcloud.admin_password.htm&type=5&language=en_US). |
| `post_required` | `invalid_request` | `use a POST request` | The request type isn’t valid. Send an HTTPS POST request. |
| `regenerate_otp` | `otp_error` | `user made too many invalid attempts; regenerate OTP` | The user tried unsuccessfully to use the OTP too many times. Request a new OTP. You can control the maximum number of password reset attempts you allow before the user must request a new OTP. See [Configure Experience Cloud Settings for the Headless Forgot Password Flow](https://help.salesforce.com/s/articleView?id=xcloud.configure_headless_forgot_password_flow.htm&type=5&language=en_US). |
| `unknown_error` | `unknown_error` | `retry your request` | There was a problem sending the request, but we don’t know what went wrong. Try checking your internet connection, refreshing the page, and resending the request. |
| `user_account_locked` | `invalid_user` | `user account is locked` | The user is locked out of their account. To restore their access, [unlock the user](https://help.salesforce.com/s/articleView?id=platform.users_unlock.htm&type=5&language=en_US). |