EMAIL VERIFICATION, EXPLAINED

Developer Email Verification Workflows: Sub-200ms REST API, Webhooks & Resilient Integration Patterns

Designing email verification into production systems requires more than checking for an HTTP 200 response. Software architects, backend engineers, and DevOps leads must handle remote SMTP timeouts, greylisting delays, strict SLA budgets, and malicious throwaway email farms without compromising user onboarding velocity. MailCheckup delivers high-throughput REST APIs, cryptographically signed webhooks, and native Model Context Protocol (MCP) tooling designed for resilient, low-latency production engineering.

WORKFLOW PREVIEW

Reliable decisions start with explicit states.

01Model the response
02Control retries
03Keep provenance
Input → Service boundary → Business rule
MAILCHECKUP / USE-CASES / DEVELOPERS↘
Sub-180ms p95 API Latency HMAC-SHA256 Signed Webhooks Native AI MCP Server (JSON-RPC 2.0) Inconclusive & Timeouts Always $0 Free
DEVELOPER INTEGRATION PLAYGROUND & ARCHITECTURE SANDBOX

Developer Email Verification Architecture Sandbox

Test resilient integration patterns across synchronous REST checks, asynchronous bulk queues, signed webhooks, and AI MCP agents. Select language and resilience policy below.

REST & MCP Console 100 Free Credits on Signup
P95 LATENCY BENCHMARK < 165 ms In-Memory Trie & Pre-Warmed DNS
BURST RATE LIMIT CAPACITY 500 req / sec Sliding Window Leaky Bucket
UNKNOWN / TIMEOUT BILLING $0.00 FREE Auto Credit Hold Release on Inconclusive
AI AGENT READINESS MCP COMPLIANT Cursor, Claude & ChatGPT Ready
APPLICATION CLIENT Node.js / Express Auth Handler
MAILCHECKUP ENDPOINT POST /v1/check/single
EXECUTION DECISION Fast-Path Allow with JWT Session
TYPESCRIPT / NODE.JS PRODUCTION IMPLEMENTATION FAIL-OPEN ABORTSIGNAL (250MS)
// Production TypeScript: Sub-200ms Single Verification with Fail-Open SLA
import { Request, Response } from 'express';

export async function verifyUserSignup(req: Request, res: Response) {
  const { email } = req.body;
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 250); // 250ms SLA budget

  try {
    const response = await fetch('https://api.mailcheckup.net/v1/check/single', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.MAILCHECKUP_API_KEY}`
      },
      body: JSON.stringify({ email }),
      signal: controller.signal
    });
    clearTimeout(timeoutId);

    if (!response.ok) {
      // 5xx or 429 transport issue -> Fail open
      return registerUserAndProceed(email, res);
    }

    const data = await response.json();
    if (data.status === 'disposable' || data.status === 'undeliverable') {
      return res.status(400).json({ error: 'Please provide a permanent work email address.' });
    }

    // Deliverable, catch-all, or unknown -> proceed safely
    return registerUserAndProceed(email, res);
  } catch (err: any) {
    // Timeout or network drop -> Fail open without blocking registration
    clearTimeout(timeoutId);
    console.warn(`[MailCheckup] Verification timed out or failed (${err.name}). Failing open.`);
    return registerUserAndProceed(email, res);
  }
}
STRUCTURED API RESPONSE SCHEMA HTTP 200 OK · 142ms
{
  "email": "alex.dev@acme-corp.com",
  "status": "deliverable",
  "sub_status": "mailbox_accepted",
  "is_deliverable": true,
  "is_disposable": false,
  "is_catch_all": false,
  "is_role_account": false,
  "mx_host": "aspmx.l.google.com",
  "smtp_check": true,
  "syntax_valid": true,
  "response_time_ms": 142,
  "credits_charged": 1,
  "checked_at": "2026-10-12T01:30:00Z"
}
MailCheckup developer console, active workspace API keys, webhook endpoint subscriptions, and credit activity
MailCheckup Developer Console: Generate scoped API keys (mck_), configure HMAC-SHA256 webhook destinations, and inspect live in-flight verification runs across backend microservices.

Transport errors vs. verification outcomes: The golden rule of email API engineering

The most common anti-pattern in email verification integrations is conflating transport-layer networking failures with mailbox deliverability decisions. When an API call fails due to a network glitch, a timeout, or a DNS resolution delay, treating the user's email as "invalid" causes severe user friction and false rejections of legitimate paying customers.

Production systems must strictly separate the two layers of the API contract:

1. Transport Layer (HTTP Protocol): Handles HTTP response codes (200, 401, 429, 503), TCP socket drops, and client-side abort signals. A transport failure means the service could not be reached or timed out; it conveys zero information about whether the email address actually exists.

2. Verification Layer (Payload Domain): Present exclusively within an HTTP 200 response payload, conveying the verified state of the mailbox: deliverable, undeliverable, catch_all, disposable, or unknown.

Whenever a transport failure or an upstream recipient timeout occurs, MailCheckup designates the outcome as unknown. Under our developer-first billing model, unknown outcomes are 100% free ($0)—the credit held during execution is immediately released back to your workspace balance.

The 4 core developer integration topologies

Depending on your architecture's latency sensitivity, traffic volume, and automation stack, MailCheckup supports four production integration patterns:

Integration PatternTransport ProtocolLatency TargetTimeout SLAPrimary Production Use Case
Single REST CheckHTTP/2 JSON POST&lt; 180ms p95250ms AbortSignalUser registration forms, checkout gates, password resets.
Bulk List IngestionChunked Multipart CSV/JSONAsynchronous streamPoll every 2–5sApollo lead imports, CRM migrations, bulk list scrubbing.
Signed WebhooksHTTPS POST with HMACEvent-drivenReturn 2xx &lt; 3sPost-verification database sync, HubSpot/Segment trigger.
Model Context ProtocolMCP JSON-RPC 2.0 (Streamable)Interactive agentTool invocation SLAAutonomous AI agents running in Cursor, Claude Desktop, ChatGPT.

Production resiliency: Timeout budgets, exponential backoff & fail-open patterns

External network dependencies should never degrade the availability of mission-critical user onboarding. To guarantee sub-second registration velocity, implement these three core resiliency patterns:

1. Enforce a 250ms–350ms SLA Budget: Use an AbortController (Node.js/Fetch), context.WithTimeout (Go), or httpx.Timeout (Python). MailCheckup's p95 latency is under 180ms; setting a 250ms cutoff catches the tail of corporate servers that attempt greylisting without holding the user's browser in limbo.

2. Implement the Fail-Open Principle: If a timeout or HTTP 5xx error occurs, log the incident, treat the verification state as unknown, and immediately grant the user access. You can flag the account in Postgres or Redis for a delayed background confirmation without blocking the signup funnel.

3. Exponential Backoff with Full Jitter: If high-volume batch jobs encounter an HTTP 429 rate limit, calculate backoff delay using sleep = min(cap, base * 2 ** attempt) * random(0, 1). Jitter spreads out concurrent retries, preventing thundering herds from overwhelming your network connection pool.

Developer HTTP status code & error resolution table

Reference table for error handling, exception boundaries, and automated retry mechanisms:

HTTP Status CodeStatus ReasonSystem MeaningRecommended Client Recovery Pattern
200 OKVerification CompleteMailbox state definitively determined.Parse payload; route based on status (deliverable, disposable, etc.).
400 Bad RequestMalformed RequestMissing email parameter or invalid JSON.Validate client schema locally before dispatching HTTP calls.
401 UnauthorizedInvalid CredentialsMissing or revoked API bearer token.Check mck_ token in server environment secrets.
402 Payment RequiredInsufficient CreditsWorkspace available credit balance is 0.Alert admin or automatically trigger Stripe auto-reload.
429 Too Many RequestsRate Limit ExceededExceeded 500 requests/second burst.Retry with exponential backoff and randomized jitter.
500 / 503 Gateway DelayUpstream Provider TimeoutTemporary network partition or mail server lag.Execute fail-open policy; allow user and enqueue async retry.

Security, secret management & GDPR Article 28 data governance

Enterprise applications handling user contact information must satisfy rigorous security and privacy constraints. MailCheckup adheres to end-to-end data minimization:

Scoped Workspace Credentials: API keys start with the prefix mck_live_ and are cryptographically scoped to individual workspaces. An API key has zero read or write visibility into other customer tenants.

Zero Contact Aggregation or Resale: MailCheckup processes addresses ephemerally in memory to evaluate RFC syntax, DNS records, and SMTP responses. We never compile, aggregate, enrich, or sell customer contact information.

Timing-Safe Webhook Verification: Webhook events include an X-MailCheckup-Signature header generated via HMAC-SHA256. Always verify this signature using timing-safe buffer comparison to prevent timing attacks.

Frequently asked questions (Developer email verification workflows)

How do I authenticate requests to the MailCheckup REST API?

All REST API requests require a Bearer token in the Authorization header: Authorization: Bearer mck_live_.... You can generate and manage API keys in the developer portal under Settings. API keys are shown once upon creation and are strictly scoped to the workspace that generated them. Never expose keys in client-side bundles; always proxy calls through your backend server routes or serverless functions.

What is the recommended client timeout budget for synchronous form signups?

We recommend configuring an AbortController or client timeout of 250ms to 350ms for customer-facing registration gates. Because MailCheckup averages under 180ms at p95, healthy requests resolve comfortably within this budget. If an upstream recipient mail server experiences network congestion and trips the timeout, your backend should fail open—allowing the user to register without interruption.

How do I verify the cryptographic signature on incoming webhooks?

MailCheckup signs every webhook request using HMAC-SHA256. The signature is transmitted in the X-MailCheckup-Signature HTTP header. To verify: compute the HMAC digest of the raw request payload using your webhook secret (e.g., crypto.createHmac('sha256', secret).update(rawBody).digest('hex')) and compare it against the header using constant-time string comparison (e.g., crypto.timingSafeEqual) to prevent timing attacks.

What happens when an upstream recipient mail server greylists our connection?

Greylisting is an anti-spam technique where recipient mail servers intentionally reject initial connection attempts with a temporary 451/421 deferral code. When this happens, MailCheckup flags the address with status: unknown and sub_status: greylisted. Under our billing rules, unknown outcomes are 100% free ($0)—the credit held during in-flight processing is automatically released back to your balance immediately.

Can I run bulk verification asynchronously without holding an open HTTP connection?

Yes. For bulk lists, call POST /v1/lists to initialize a batch, append contacts in chunks of 500 rows using POST /v1/lists/{id}/emails, and start processing with POST /v1/lists/{id}/verify. You can either poll GET /v1/lists/{id} periodically or register a webhook URL to receive a signed list.completed payload containing segmented CSV download tokens when the batch completes.

How does the MailCheckup MCP server connect to AI developer environments like Cursor or Claude?

MailCheckup provides a native Model Context Protocol (MCP) server adhering to the JSON-RPC 2.0 specification over streamable HTTP at https://cp.mailcheckup.net/mcp. By adding this endpoint and your workspace API key to your claude_desktop_config.json or Cursor MCP settings, AI agents gain access to tools like verify_email, list_results, and export_list without custom glue code.

How are API credits deducted for batch and single requests?

One credit is deducted per finished chargeable outcome (deliverable, undeliverable, catch-all, disposable, role account, mailbox full). Inconclusive outcomes (unknown, timeout, mail server unreachable, provider blocked) are completely free with zero credit deductions. Credit packs purchased on MailCheckup never expire, allowing you to consume them flexibly across development, staging, and production environments.

How can we test our integration in local development without consuming credits?

We provide standard test addresses in our developer documentation that return deterministic outcomes without triggering live SMTP connections: valid@mailcheckup-test.net (returns deliverable), invalid@mailcheckup-test.net (returns undeliverable), catchall@mailcheckup-test.net (returns catch-all), and timeout@mailcheckup-test.net (triggers simulated 400ms timeout for fail-open validation).