Mailbeam
Auth0 ActionsIntermediate20 minutesUpdated January 2025

Email Verification with Auth0

Auth0 Actions are serverless functions that run during the authentication pipeline. The pre-user-registration trigger runs before a new user is created in Auth0, making it the perfect place to verify email addresses with Mailbeam.

Prerequisites

  • Auth0 account with a tenant
  • A Mailbeam API key (sign up free)

Create the Action

In the Auth0 Dashboard → Actions → Library, create a new Action for the Pre User Registration trigger.

// Auth0 Action: pre-user-registration
exports.onExecutePreUserRegistration = async (event, api) => {
  const email = event.user.email;
  
  // Skip for social logins (no email address provided at this stage)
  if (!email) return;

  const MAILBEAM_KEY = event.secrets.MAILBEAM_KEY;
  const MIN_SCORE = 60;

  try {
    const response = await fetch("https://api.mailbeam.dev/v1/verify", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${MAILBEAM_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email }),
    });

    if (!response.ok) {
      // API error — fail open
      console.log("[Mailbeam] API returned non-200, failing open");
      return;
    }

    const { valid, score, reason } = await response.json();

    if (!valid || score < MIN_SCORE) {
      const message = reason === "disposable_domain"
        ? "Please use a permanent email address."
        : "Please provide a valid, reachable email address.";

      api.access.deny("invalid_email", message);
    }
  } catch (err) {
    // Network error — fail open
    console.error("[Mailbeam] verify error:", err.message);
  }
};

Add the API key as a secret

In the Action editor, go to Secrets and add:

NameValue
MAILBEAM_KEYmb_live_xxxxxxxxxxxxxxxxxxxx

Deploy and attach

  1. Click Deploy in the Action editor
  2. Go to Actions → Flows → Pre User Registration
  3. Drag your new Action into the flow
  4. Click Apply

Test

// Test via Auth0's built-in Action Testing tab with:
{
  "user": {
    "email": "temp@mailinator.com"
  }
}
// Expected: api.access.deny is called with "invalid_email" error

How api.access.deny works

When api.access.deny is called, Auth0 returns an error to the client:

{
  "error": "invalid_email",
  "error_description": "Please use a permanent email address."
}

Your frontend receives this as part of the Auth0 error callback and can display it to the user.

Best practices

  • Always fail open (return without calling api.access.deny) on API errors
  • Use event.secrets for the API key — never hardcode it
  • Log errors with console.error — they appear in Auth0 tenant logs

Next steps