---
schema_version: "1"
id: 5300cdd7dfa9c34b8d3582f45da6c4fbd8dea0754ce820698079b9abcdd93dca
title: Considerations for Using a Custom One-Time Password Delivery Provider
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/custom_otp_provider_considerations.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.custom_otp_provider_considerations.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 0c0a40b5803c628e425a509c461a3e7d7cadca689d4ee12bdaf59f211d7deddf
description: Before you configure a custom one-time password (OTP) delivery handler to send SMS messages for Experience Cloud use cases, review these considerations.
products:
  - Security
  - Cross Cloud
release: "264"
---
# Considerations for Using a Custom One-Time Password Delivery Provider

Before you configure a custom one-time password (OTP) delivery handler to send SMS messages for Experience Cloud use cases, review these considerations.

### 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><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>Professional</strong>, <strong>Enterprise</strong>, <strong>Unlimited</strong>, and <strong>Developer</strong> Editions</td></tr></tbody></table>

## Security Considerations

- If you use custom OTP providers, your Apex implementation has access to the OTP, which isn't the case if you use the Salesforce default provider. With a custom OTP provider, your Apex handler implementation, not Salesforce, performs identity verification. You're responsible for the security and integrity of your code and implementation.
- You can choose to deliver OTPs via alternative delivery methods, such as iMessage, Rich Communication Services (RCS), and WhatsApp. Before choosing any alternative delivery methods, carefully consider the security implications.
- If you send an SMS message via a custom provider, and the user's phone number isn't verified, Salesforce doesn't attempt to verify it. Salesforce can’t make sure that the OTP gets delivered to a phone number that's verified by Salesforce. As a security best practice, we recommend that you verify all phone numbers and configure your handler to send OTPs only to verified phone numbers.

To understand differences in verification for custom OTP providers and the default Salesforce provider, review these tables.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Custom OTP Provider Verification">
        <caption>Custom OTP Provider Verification</caption>
        <colgroup>
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" rowspan="2" style="vertical-align:top;" id="d75810e102">Use Case</th>
            <th scope="col" class="slds-cell-wrap" rowspan="2" style="vertical-align:top;" id="d75810e105">Apex <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm" target="_blank"><code>System.UserManagement</code></a>
              Methods</th>
            <th scope="colgroup" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" id="d75810e113"><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_twofactormethodsinfo.htm" target="_blank">TwoFactorMethodsInfo </a> Verification
              Requirement</th>
            <th scope="colgroup" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" id="d75810e119"><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_twofactormethodsinfo.htm" target="_blank">TwoFactorMethodsInfo </a> Post-Verification
              Result</th>
          </tr>
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e128">User-Verified Number (<samp class="parmname">HasUserVerifiedmobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e134">Admin-Verified Number (<samp class="parmname">HasVerifiedMobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e140">User-Verified Number (<samp class="parmname">HasUserVerifiedmobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e146">Admin-Verified Number (<samp class="parmname">HasVerifiedMobileNumber</samp>)</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e102 ">Self-registration</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e105 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initSelfRegistration" target="_blank"><code>initSelfRegistration</code> and
              </a><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifySelfRegistration" target="_blank"><code>verifySelfRegistration</code></a></td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e113 d75810e128 d75810e134 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e140 ">Unchanged</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e146 "><code>true</code></td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e102 ">Passwordless login</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e105 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initPasswordlessLogin" target="_blank"><code>initPasswordlessLogin</code></a> and
              <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyPasswordlessLogin" target="_blank"><code>verifyPasswordlessLogin</code></a>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e113 d75810e128 d75810e134 ">One of these fields must be
              <code>true</code>
            </td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e140 ">Unchanged</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e146 "><code>true</code></td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e102 ">Verification method registration</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e105 ">
              <ul>
                <li><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initRegisterVerificationMethod" target="_blank"><code>initRegisterVerificationMethod</code></a> and <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyRegisterVerificationMethod" target="_blank"><code>verifyRegisterVerificationMethod</code></a></li>

                <li><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_registerVerificationMethod" target="_blank"><code>registerVerificationMethod</code></a></li>

              </ul>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e113 d75810e128 d75810e134 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e140 ">Unchanged</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e146 "><code>true</code></td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e102 ">Verification (including multi-factor authentication)</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e105 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initVerificationMethod" target="_blank"><code>initVerificationMethod</code></a> and
              <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyVerificationMethod" target="_blank"><code>verifyVerificationMethod</code></a>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e113 d75810e128 d75810e134 ">One of these fields must be
              <code>true</code>
            </td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e140 ">Unchanged</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e119 d75810e146 "><code>true</code></td>

          </tr>
        </tbody>
      </table> <table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small " summary="Default OTP Provider Verification">
        <caption>Default OTP Provider Verification</caption>
        <colgroup>
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
          <col style="width:16.666666666666664%">
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" rowspan="2" style="vertical-align:top;" id="d75810e307">Use Case</th>
            <th scope="col" class="slds-cell-wrap" rowspan="2" style="vertical-align:top;" id="d75810e310">Apex <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm" target="_blank"><code>System.UserManagement</code></a></th>
            <th scope="colgroup" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" id="d75810e317"><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_twofactormethodsinfo.htm" target="_blank">TwoFactorMethodsInfo </a> Verification
              Requirement</th>
            <th scope="colgroup" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" id="d75810e323"><a href="https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_twofactormethodsinfo.htm" target="_blank">TwoFactorMethodsInfo </a> Post-Verification
              Result</th>
          </tr>
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e332">User-Verified Number (<samp class="parmname">HasUserVerifiedmobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e338">Admin-Verified Number (<samp class="parmname">HasVerifiedMobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e344">User-Verified Number (<samp class="parmname">HasUserVerifiedmobileNumber</samp>)</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d75810e350">Admin-Verified Number (<samp class="parmname">HasVerifiedMobileNumber</samp>)</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e307 ">Self-registration</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e310 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initSelfRegistration" target="_blank"><code>initSelfRegistration</code> and
              </a><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifySelfRegistration" target="_blank"><code>verifySelfRegistration</code></a></td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e317 d75810e332 d75810e338 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e344 "><code>true</code></td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e350 ">Unchanged</td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e307 ">Passwordless login</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e310 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initPasswordlessLogin" target="_blank"><code>initPasswordlessLogin</code></a> and
              <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyPasswordlessLogin" target="_blank"><code>verifyPasswordlessLogin</code></a>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e317 d75810e332 ">Required</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e317 d75810e338 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e344 "><code>true</code></td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e350 ">Unchanged</td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e307 ">Verification method registration</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e310 ">
              <ul>
                <li><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initRegisterVerificationMethod" target="_blank"><code>initRegisterVerificationMethod</code></a> and <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyRegisterVerificationMethod" target="_blank"><code>verifyRegisterVerificationMethod</code></a></li>

                <li><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_registerVerificationMethod" target="_blank"><code>registerVerificationMethod</code></a></li>

              </ul>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" colspan="2" style="vertical-align:top;" headers="d75810e317 d75810e332 d75810e338 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e344 "><code>true</code></td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e350 ">Unchanged</td>

          </tr>
          <tr class="">
            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e307 ">Verification (including multi-factor authentication)</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e310 "><a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_initVerificationMethod" target="_blank"><code>initVerificationMethod</code></a> and
              <a href="https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_UserManagement.htm#apex_System_UserManagement_verifyVerificationMethod" target="_blank"><code>verifyVerificationMethod</code></a>
            </td>

            <td data-label="User-Verified Number (HasUserVerifiedmobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e317 d75810e332 ">Required</td>

            <td data-label="Admin-Verified Number (HasVerifiedMobileNumber)" class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e317 d75810e338 ">Not required</td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e344 "><code>true</code></td>

            <td class="slds-cell-wrap" style="vertical-align:top;" headers="d75810e323 d75810e350 ">Unchanged</td>

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

## Other Implementation Considerations

- This feature is supported only for Salesforce Customer Identity. You can't use it for internal users, also known as employees.
- This feature is supported for all [Experience Cloud user licenses](https://help.salesforce.com/s/articleView?id=platform.users_license_types_external_identity.htm&type=5&language=en_US) and the [External Identity license](https://help.salesforce.com/s/articleView?id=platform.users_license_types_external_identity.htm&type=5&language=en_US). It doesn't require the [Identity Verification Credits add-on license](https://help.salesforce.com/s/articleView?id=xcloud.identity_licenses.htm&type=5&language=en_US).
- Because this feature relies on a custom provider to deliver the message, Salesforce Customer Support can't troubleshoot issues with delivery. To fix delivery issues, work with your provider.
- You must contact Salesforce Customer Support to use this feature. If Support gives you access to this feature, you have the option to configure a custom OTP provider for all Experience Cloud sites in your org. To keep your OTP delivery method consistent, if you request access to this feature, we recommend using a custom OTP provider for all your Experience Cloud sites. However, if you don't configure a custom OTP delivery Apex handler for a site, it continues to use the Salesforce default delivery service.
- If Support gives you access to this feature, it isn't automatically enabled. To use this feature, you must add a working custom OTP delivery handler to your Experience Cloud site's settings.
- If you switch to a using a custom OTP provider, we don't recommend that you switch back to the Salesforce default provider.