> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prelude.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate Prelude with Auth0 for phone verification

> Replace Auth0's default SMS provider with Prelude to raise verification delivery rates and cut cost.

## Why route Auth0 verification through Prelude

Auth0 sends verification codes through one default SMS provider. Prelude picks a route per message: it sends across 30+ providers and moves to the next best route when one fails. Route choice follows what performs in the destination country, and codes can arrive over SMS, WhatsApp, Viber, or RCS.

Prelude also scores each request before it sends, so repeated or automated verification attempts are blocked rather than billed. Setup is a phone provider entry and a log stream in Auth0.

## Prerequisites

* An Auth0 project.
* A Prelude account.

## Step 1: Configure Prelude for Auth0

* Create a new Secret Key for your Auth0 integration on All Service > Configure > Keys and don't forget to save or copy it.
* Enable the Auth0 integration by going to Verify API > Configure > Integrations in the [Prelude dashboard](https://app.prelude.so/).
* Create a new Webhook Key for your Auth0 integration and don't forget to save or copy it.

## Step 2: Add a custom phone provider with the Auth0 Dashboard

Follow these steps to connect Prelude to your Auth0 project as a custom phone provider:

1. **Open the Auth0 Dashboard** and go to **Branding > Phone Provider**.
2. On the Phone Message Provider page, you'll notice **Twilio** is selected by default.
3. In the **Phone Provider** section, select the **Custom** option.
4. Under **Delivery Method**, choose **Text** and **Voice**. Both are supported by Prelude, but **Voice** should be explicitly enabled from the [Prelude dashboard](https://app.prelude.so/).
5. In the **Provider Configuration** area:
   * Click the key icon to add a secret. Name it `PRELUDE_SECRET_KEY` and paste your Prelude API Key.
   * Click the box icon to add dependencies:
     * Add `@prelude.so/sdk` (leave the version field empty).
     * Add `ua-parser-js` (leave the version field empty).
6. Paste the following code into the editor. This code will send verification requests to Prelude and enrich them with device and context signals for better security and deliverability.

```js Provider Configuration theme={null}
const parser = require("ua-parser-js");
const Prelude = require("@prelude.so/sdk");

function categorizeDevice(data) {
  const osName = (data.os.name || "").toLowerCase();
  const deviceModel = (data.device.model || "").toLowerCase();
  const deviceType = (data.device.type || "").toLowerCase();

  if (deviceModel === "ipad") return "ipados";
  if (deviceModel === "macintosh") return "web";
  if (deviceModel === "iphone") return "ios";
  if (deviceType === "smarttv") return "tvos";
  if (osName.includes("android")) return "android";
  if (!deviceType && !data.device.model && !data.device.vendor) return "web";

  return undefined;
}

function getDeviceModel(ua) {
  if (!ua.device || (!ua.device.vendor && !ua.device.model)) {
    return undefined;
  }

  const { vendor, model } = ua.device;

  if (vendor) {
    return `${vendor}/${model || ""}`.trim();
  }

  return model || undefined;
}

exports.onExecuteCustomPhoneProvider = async (event, api) => {
  const client = new Prelude({
    apiToken: event.secrets.PRELUDE_SECRET_KEY,
  });

  const { recipient, code, delivery_method } = event.notification;
  const { ip, language } = event.request;

  const ua = parser(event.request.user_agent);

  const correlationId = `auth0:${event.tenant.id}:${event.user.user_id}`;

  const method = delivery_method === "voice" ? "voice" : "auto";

  await client.verification.create({
    headers: {
      X-Prelude-Integration: "auth0",
    },
    target: {
      type: "phone_number",
      value: recipient.replace(/[\s-]/g, ""),
    },
    metadata: {
      correlation_id: correlationId,
    },
    signals: {
      ip,
      os_version: ua.os.version,
      device_model: getDeviceModel(ua),
      device_platform: categorizeDevice(ua),
    },
    options: {
      locale: language,
      custom_code: code,
      method,
    },
  });
};
```

7. Click the **Save** button at the bottom of the page to apply your configuration.
8. (Optional) If you created your Auth0 tenant before September 2025, you may need to enable **Use Tenant-Level Messaging Provider** in **Security > Multi-factor Auth (MFA) > Phone number**.

<Info>
  If you are already using Prelude with Auth0, contact our support team at [support@prelude.so](mailto:support@prelude.so) after the migration to see your conversion rate. Migration takes effect as soon as you enable **Use Tenant-Level Messaging Provider**.
</Info>

## Step 3: Set up the verification webhook

To enable Prelude to verify Auth0 authentication events, you'll need to configure a log stream webhook in your Auth0 dashboard. Follow these steps:

1. In the Auth0 dashboard, navigate to **Monitoring > Log Streams**.
2. Click **Create Log Stream**.
3. Choose **Custom Webhook** as the stream type.
4. Name your log stream (e.g., `Prelude Check`) to easily identify it later.
5. Fill in the configuration fields as follows:

| Setting                          | Value / Action                                                                                            |
| -------------------------------- | --------------------------------------------------------------------------------------------------------- |
| **Name**                         | Enter a descriptive name (e.g., `Prelude Check`).                                                         |
| **Payload URL**                  | Paste the webhook URL from the Prelude dashboard's Auth0 configuration.                                   |
| **Authorization Token**          | Enter the Webhook key's secret from the Prelude dashboard's Auth0 configuration.                          |
| **Content Type**                 | `application/json`                                                                                        |
| **Prioritized Logs**             | Leave **unchecked**.                                                                                      |
| **Filter by Log Event Category** | Select **Login - Success**, **User/Behavioral - Notification**, and **Other logs**.                       |
| **Starting Cursor**              | Leave **unchecked**.                                                                                      |
| **Obscure log stream data**      | Enable **XXXHash** (recommended for privacy), but **uncheck "phone"** so Prelude can match verifications. |
| **Content Format**               | Select **JSON object**.                                                                                   |

6. Click **Save** to apply your webhook configuration.

> **Note:** It's important to leave the "phone" field unobscured so Prelude can properly process and verify phone number authentications. All other sensitive fields can remain obscured for privacy.

Once saved, Auth0 will begin sending relevant authentication events to Prelude for verification.

To learn more about enabling and configuring MFA and passwordless authentication in Auth0, refer to:

* [Enable MFA](https://auth0.com/docs/secure/multi-factor-authentication/enable-mfa)
* [SMS-based Passwordless Authentication](https://auth0.com/docs/authenticate/passwordless#sms-based-passwordless-authentication)

## Correlation ID

A correlation ID is automatically generated within the Auth0 action integration using the format:

```
auth0:${event.tenant.id}:${event.user.user_id}
```

This unique identifier helps with tracking verification flows across systems.

## Test the integration

Auth0 now routes phone verification through Prelude. Trigger an MFA or passwordless SMS challenge from your application: Auth0 hands the verification to Prelude, and the code reaches the user over Prelude's routes.

<Info>
  Sandboxed phone numbers do not work with this integration. Auth0 generates its own verification code and checks it internally.
</Info>
