Skip to main content

On This Page

Automating Email Verification in CI/CD with Temporary Email APIs

3 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

Testing Email Flows in CI/CD with Temporary Email APIs

Francisco Perez introduces a method for testing email delivery using the uncorreotemporal.com API. This infrastructure utilizes real SMTP delivery via AWS SES in production to ensure tests pass through the same ingestion path as production email.

Why This Matters

Mocking email delivery often fails to catch production issues like broken rendering, malformed links, or SDK incompatibilities. By using real temporary inboxes instead of mocks or shared SMTP servers, engineers can validate the entire delivery path—including spam filtering and DKIM verification—ensuring that critical registration flows do not fail silently in production due to environmental differences.

Key Insights

  • Real SMTP ingestion via AWS SES ensures emails pass through production-grade filters and DKIM verification (2026).
  • WebSocket event streams eliminate polling latency and API rate-limiting issues in high-concurrency CI pipelines by providing instant ‘new_message’ notifications.
  • Automated TTL (Time-To-Live) settings, such as 5 to 10-minute expirations, prevent orphaned test data and manual cleanup overhead.
  • Isolated inboxes per test run prevent cross-contamination, a common failure point in shared SMTP staging environments where multiple tests access the same address.
  • The session_token mechanism allows for anonymous inbox creation and authentication without requiring pre-registered API keys for basic CI/CD flows.

Working Examples

Creating an anonymous temporary inbox via REST API.

import httpx

def create_inbox(ttl_minutes: int = 10) -> dict:
    resp = httpx.post(
        "https://uncorreotemporal.com/api/v1/mailboxes",
        params={"ttl_minutes": ttl_minutes},
    )
    resp.raise_for_status()
    return resp.json()

Subscribing to an inbox WebSocket for low-latency message arrival notifications.

import asyncio
import json
import websockets

async def wait_for_message_ws(address: str, session_token: str, timeout: int = 30) -> str:
    encoded = urllib.parse.quote(address, safe="")
    uri = f"wss://uncorreotemporal.com/ws/inbox/{encoded}?token={session_token}"
    async with websockets.connect(uri) as ws:
        async def _read():
            async for raw in ws:
                event = json.loads(raw)
                if event.get("event") == "new_message":
                    return event["message_id"]
        return await asyncio.wait_for(_read(), timeout=timeout)

Practical Applications

  • Use case: GitHub Actions integration using Pytest fixtures to automate registration flows. Pitfall: Using a single hardcoded address for multiple test runs causes cross-contamination and flakiness.
  • Use case: Extracting 6-digit OTPs using regex from plain-text email bodies for login verification. Pitfall: Mocking the email service hides failures in template rendering or incorrect link formatting.
  • Use case: High-concurrency testing with 50+ parallel workers using WebSockets to avoid 429 Rate Limit errors. Pitfall: Polling the message list endpoint every 2 seconds across 50 workers generates 1,500 requests per minute.

References:

Continue reading

Next article

The Asynchronous Deception: Monitoring GPT-5.4 Streaming Performance

Related Content