Skip to content
Inizia con 100 crediti di verifica gratuiti
Qualisend
Tutti gli articoli
Ingegneria / 27 giugno 2026

Verificare le email all'iscrizione con una funzione serverless

4 min di lettura

Qualisend team
Verificare le email all'iscrizione con una funzione serverless

Il bounce più economico è quello che non entra mai nella tua lista. Verificare un indirizzo nel momento in cui viene digitato, con una funzione serverless dietro il modulo di iscrizione, ferma all'ingresso errori di battitura, domini morti e indirizzi usa e getta, invece di costringerti a pagare per eliminarli più tardi e a subire nel frattempo il danno alla deliverability. Questa guida mostra lo schema con una route serverless funzionante.

In breve#

Metti la verifica in una funzione lato server chiamata dal modulo di iscrizione: custodisce la tua chiave API, chiama POST /verify e agisce sull'esito locale immediato. Rifiuta undeliverable, proponi la correzione did_you_mean, segnala disposable e lascia passare tutto il resto. Tutto dipende da due regole: non chiamare mai l'API dal browser (la chiave deve restare sul server) e non bloccare mai un'iscrizione quando l'API è lenta o non disponibile (fail open).

Perché all'iscrizione e non dopo#

La verifica al punto di acquisizione è prevenzione; la pulizia di una lista è un rimedio, e la prevenzione vince su tutta la linea. Un errore di battitura intercettato mentre si digita è un iscritto salvato con una correzione di una riga. Un dominio morto rifiutato all'iscrizione non diventa mai un hard bounce che intacca il tuo tasso di bounce. Un indirizzo usa e getta bloccato all'ingresso non diluisce mai le tue metriche né gonfia la tua fattura. Lo stesso indirizzo trovato durante una pulizia della lista tre mesi dopo ti è già costato un invio, un bounce e un po' di reputazione del mittente.

Lo schema#

Tre componenti:

  1. Il modulo invia l'indirizzo al tuo endpoint, mai direttamente all'API di verifica, perché esporrebbe la tua chiave.
  2. Una funzione serverless custodisce la chiave in una variabile d'ambiente, chiama POST /verify e trasforma il risultato in una decisione.
  3. La tua logica di iscrizione agisce sulla decisione: rifiuta, suggerisce una correzione o accetta.

Una route serverless#

Eccola come Route Handler del Next.js App Router, che su Vercel viene distribuito come funzione serverless. La chiave sta in QUALISEND_API_KEY e il client non la vede mai:

// app/api/validate-email/route.ts
import { NextResponse } from "next/server";

const BASE = "https://app.qualisend.com/api/v1";

export async function POST(req: Request) {
  const { email } = await req.json();

  try {
    const res = await fetch(`${BASE}/verify`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.QUALISEND_API_KEY!}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email }),
      signal: AbortSignal.timeout(4000), // don't let a slow probe stall signup
    });

    // On any API error, fail open — a real user must not be blocked by our outage.
    if (!res.ok) return NextResponse.json({ ok: true, degraded: true });

    const { result } = await res.json();

    if (result.status === "undeliverable") {
      return NextResponse.json({
        ok: false,
        reason: result.reason,          // invalid_email | invalid_domain | rejected_email
        suggestion: result.did_you_mean, // e.g. "jane@gmail.com"
      });
    }
    if (result.sub_flags?.disposable) {
      return NextResponse.json({ ok: false, reason: "disposable" });
    }

    // deliverable, risky, or unknown — accept, but pass along a typo suggestion if any
    return NextResponse.json({ ok: true, status: result.status, suggestion: result.did_you_mean });
  } catch {
    return NextResponse.json({ ok: true, degraded: true }); // timeout or network error → fail open
  }
}

Salva la chiave con gli strumenti per le variabili d'ambiente della tua piattaforma (vercel env add QUALISEND_API_KEY): viene iniettata in fase di esecuzione e non finisce mai nel bundle del client.

Agire in base all'esito#

Il result immediato è l'esito locale (sintassi, DNS, usa e getta, indirizzo generico, errore di battitura), ed è esattamente ciò che ti serve all'iscrizione, perché è veloce e basta per decidere:

RisultatoAzione all'iscrizione
undeliverableRifiuta subito nel modulo: "questo indirizzo non sembra recapitabile".
did_you_mean presenteProponi la correzione: "forse intendevi jane@gmail.com?". È il recupero di maggior valore.
Indicatore disposableRifiuta o contrassegna, a seconda di quanto è rigoroso il tuo prodotto: vedi indirizzi generici, usa e getta e gratuiti.
risky / catch-allAccetta, ma aggiungi un tag per poter inviare con cautela al segmento catch-all.
unknownAccettalo. L'infrastruttura non ha risposto: non perdere mai un'iscrizione vera per questo motivo.
deliverableAccettalo.

Fail open, sempre#

L'unico punto non negoziabile: se la chiamata di verifica va in errore, va in timeout o restituisce una risposta diversa da 2xx, lascia passare l'iscrizione. Un'API di verifica è un filtro di qualità, non un controllo di autenticazione, e bloccare un cliente pagante per un'interruzione temporanea è molto peggio che lasciar entrare un indirizzo dubbio. Sia il ramo !res.ok sia il catch qui sopra restituiscono ok: true proprio per questo motivo. Registra le iscrizioni in modalità degradata e intercettale invece nella tua prossima pulizia della lista.

Domande frequenti

01Verificare all'iscrizione rallenta il modulo?

Quasi per niente, se lo fai bene. L'esito locale arriva in fretta e il timeout di 4 secondi visto sopra limita il caso peggiore: oltre quella soglia applichi il fail open e accetti comunque l'iscrizione. Gli utenti ricevono correzioni "forse intendevi" quasi istantanee e non aspettano mai un server di posta lento, perché agisci sul risultato locale immediato e non fai polling in attesa del test SMTP.

02Devo bloccare gli indirizzi email usa e getta all'iscrizione?

Dipende dal tuo prodotto. Per un servizio a pagamento o sensibile alla reputazione, vale la pena bloccare gli indirizzi usa e getta all'ingresso: chi li usa non ha mai avuto intenzione di sentirti di nuovo. Per un'iscrizione consumer a basso attrito, segnalarli per una revisione successiva può essere meglio che aggiungere attrito. La route qui sopra li rifiuta; modificala in modo che si limiti a segnalarli, se è più adatto al tuo funnel.

03Mi serve il risultato completo confermato via SMTP all'iscrizione?

Di solito no. L'esito locale immediato intercetta la maggior parte delle iscrizioni sbagliate (errori di battitura, domini morti, indirizzi usa e getta) senza alcuna attesa. Riserva il risultato completo confermato via SMTP (tramite GET /jobs o un job in blocco) alla pulizia delle liste, dove la latenza non conta e conta invece intercettare ogni casella morta.

04Come tengo segreta la mia chiave API?

Chiama l'API di verifica solo da codice lato server (una funzione serverless, un route handler o un backend) e salva la chiave in una variabile d'ambiente, mai nel JavaScript lato client. Se la chiave finisce nel bundle del browser, è nel posto sbagliato.


Pronto a collegare tutto? Il piano Free include 100 crediti per provare il flusso, e il riferimento API contiene l'endpoint /verify con esempi da copiare e incollare in sette linguaggi.

La tua reputazione, protetta.

Pulisci la tua prima lista in pochi minuti. 100 crediti gratuiti, senza carta di credito.

Inizia