Docs · Guides

Verify sign-ups

Check each sign-up's email address as the form is sent, so typos are caught while the person is still there, and bad addresses never reach your list.

Preview: may change before launch · Updated

Preview

This is how the API is planned to work. Names and fields may change before launch. The APIs are in early access: join early access to get a key when they're ready.

What works today

There's no API key to do this with yet. Today, the free email verifier checks one address at a time, 10 a day, with the same verdicts.

Where the check runs

On your server, in the handler that receives the form. Never call the API from the browser: the key would be visible to anyone. The browser sends the form as usual, your server checks the address, and answers with an error to show or carries on with the sign-up.

The code

Checking a sign-up
// On your server, never in the browser: the key must stay secret.
const MAGPIE = "https://api.magpie-cloud.com/v1";

async function verifyEmail(email) {
  try {
    const res = await fetch(`${MAGPIE}/verify`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.MAGPIE_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email }),
      // Don't keep someone waiting on a slow mail server.
      signal: AbortSignal.timeout(10_000),
    });
    if (!res.ok) {
      console.error("Email check failed", res.status);
      return null;
    }
    return await res.json();
  } catch {
    return null; // timed out, or unreachable
  }
}

export async function checkSignUp(email) {
  const result = await verifyEmail(email);
  // No answer from us is never the person's fault: let them in, check later.
  if (!result) return { ok: true, recheck: true };

  switch (result.verdict) {
    case "valid":
      return { ok: true, verdict: "valid" };
    case "invalid":
      return { ok: false, message: "That address can't get email. Is there a typo?" };
    case "catch_all":
    case "risky":
      // Let them in, but confirm the address before you rely on it.
      return { ok: true, verdict: result.verdict, confirm: true };
    default: // "unknown"
      return { ok: true, recheck: true };
  }
}

A check can take up to a minute when a mail server is slow. Nobody should wait that long on a form, so this gives up after 10 seconds and lets the person in, marked to check again later from a background job, with a long timeout.

If our API fails (a 5xx, a 429, or a timeout), let the sign-up through. A 401 or 402 is a problem on your side to fix: log it, but don't turn people away for it.

What to do with each verdict

VerdictAt sign-up
validLet them in.
invalidTurn it away with a message, so they can fix a typo.
catch_allLet them in, and send a confirmation link: the domain accepts every address, so only a click proves this one.
riskyThe same: let them in, and confirm the address.
unknownLet them in, and check again later.

checks.disposable is true for throwaway email services, and checks.free for free providers. Whether to accept those is up to you: for a business product you might ask for a work address.

What to store

Keep the verdict and when you checked, with the person's record. You don't need the rest of the response. See Data handling.

Questions about the APIs? Email pele@magpiecrm.com.