Node.js Integration Guide

Emailyze works with Node's built-in fetch (Node 18+) or any HTTP library. No SDK installation required.

Single Email Check

const API_KEY = process.env.EMAILYZE_API_KEY;
const BASE_URL = "https://api.emailyze.dev/v1/check/";

async function checkEmail(email, { verify = false } = {}) {
  const url = new URL(BASE_URL);
  url.searchParams.set("email", email);
  if (verify) url.searchParams.set("verify", "true");

  const resp = await fetch(url.toString(), {
    headers: { "X-API-Key": API_KEY },
  });

  if (!resp.ok) {
    const body = await resp.json().catch(() => ({}));
    throw new Error(`Emailyze API error ${resp.status}: ${body.error ?? resp.statusText}`);
  }
  return resp.json();
}

// Usage
const result = await checkEmail("user@tempmail.com");
if (result.is_disposable) {
  console.log(`Blocked: ${result.domain} (risk: ${result.risk_score})`);
}

TypeScript Types

interface SmtpResult {
  can_connect_smtp: boolean;
  is_catch_all: boolean | null;
  is_deliverable: boolean | null;
  is_disabled: boolean | null;
  has_full_inbox: boolean | null;
}

interface SyntaxResult {
  domain: string;
  username: string | null;
  is_valid_syntax: boolean;
  suggestion: string | null;
}

interface EmailCheckResult {
  email: string | null;
  domain: string;
  is_disposable: boolean;
  provider_type: "disposable" | "personal" | "masked" | "unknown";
  risk_score: number;
  mx_valid: boolean;
  mx_provider: string | null;
  local_part_type: string | null;
  catch_all: boolean;
  syntax: SyntaxResult | null;
  smtp: SmtpResult | null;
  sources: string[];
  checked_at: string;
  latency_ms: number;
}

Batch Check

async function batchCheck(emails: string[]): Promise {
  const resp = await fetch("https://api.emailyze.dev/v1/check/batch/", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.EMAILYZE_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emails }),
  });
  if (!resp.ok) throw new Error(`Batch check failed: ${resp.status}`);
  const data = await resp.json();
  return data.results;
}

async function batchCheckLargeList(emails: string[]): Promise {
  const results: EmailCheckResult[] = [];
  for (let i = 0; i < emails.length; i += 1000) {
    const chunk = emails.slice(i, i + 1000);
    results.push(...(await batchCheck(chunk)));
  }
  return results;
}

Error Handling with Retry

async function checkEmailWithRetry(
  email: string,
  maxRetries = 3
): Promise {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const resp = await fetch(
      `https://api.emailyze.dev/v1/check/?email=${encodeURIComponent(email)}`,
      { headers: { "X-API-Key": process.env.EMAILYZE_API_KEY! } }
    );

    if (resp.status === 429) {
      const retryAfter = Number(resp.headers.get("Retry-After") ?? 2 ** attempt);
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      continue;
    }
    if (!resp.ok) throw new Error(`API error: ${resp.status}`);
    return resp.json();
  }
  throw new Error("Max retries exceeded");
}

Express.js Middleware

import express from "express";

const app = express();
app.use(express.json());

// Middleware: block disposable emails on any route
async function rejectDisposableEmail(
  req: express.Request,
  res: express.Response,
  next: express.NextFunction
) {
  const email = req.body?.email;
  if (!email) return next();

  try {
    const result = await checkEmail(email);
    if (result.is_disposable) {
      return res.status(422).json({
        error: "Please use a permanent email address.",
        code: "disposable_email",
      });
    }
  } catch {
    // Fail open — don't block signup if API is unavailable
  }
  next();
}

// Apply to registration endpoint
app.post("/auth/register", rejectDisposableEmail, (req, res) => {
  // ... create user
  res.json({ success: true });
});

Next.js API Route Example

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

export async function GET(request: NextRequest) {
  const email = request.nextUrl.searchParams.get("email");
  if (!email) {
    return NextResponse.json({ error: "email required" }, { status: 400 });
  }

  const resp = await fetch(
    `https://api.emailyze.dev/v1/check/?email=${encodeURIComponent(email)}`,
    { headers: { "X-API-Key": process.env.EMAILYZE_API_KEY! } }
  );

  const data = await resp.json();
  return NextResponse.json(data);
}

Environment Variables

# .env.local
EMAILYZE_API_KEY=em_live_xxxxxxxxxxxx
// Validate at startup
if (!process.env.EMAILYZE_API_KEY) {
  throw new Error("EMAILYZE_API_KEY environment variable is required");
}