AxioAPI

Test signup emails with Playwright and a temp mail API

2026-10-05

Signup and password-reset flows depend on email, which makes them hard to test. A temp mail API gives every test its own inbox, so the test can wait for the real email and read it instead of mocking it.

What you need

Create a key in your account. Never commit it to source control; read it from the environment or your CI secret store.

  • An AxioAPI key, stored as the AXIOAPI_KEY environment variable.
  • Playwright Test, or any HTTP client in your language.
  • A staging environment that really sends email.

The test

The test creates an inbox with POST /api/v1/temp-mail/inboxes, which returns an inbox ID and an address. It submits the address in the signup form, polls the message list until an email arrives, and deletes the inbox at the end.

// signup.spec.js
import { test, expect } from '@playwright/test';

const API = 'https://axioapi.com/api/v1';
const headers = { Authorization: `Bearer ${process.env.AXIOAPI_KEY}`, Accept: 'application/json' };

async function waitForMail(request, inbox, timeoutMs = 60000) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    const res = await request.get(`${API}/temp-mail/inboxes/${inbox}/messages`, { headers });
    const { items } = (await res.json()).data;
    if (items.length > 0) return items[0];
    await new Promise((resolve) => setTimeout(resolve, 3000));
  }
  throw new Error('No email arrived in time');
}

test('signup sends a confirmation email', async ({ page, request }) => {
  const created = await request.post(`${API}/temp-mail/inboxes`, { headers });
  const { id, address } = (await created.json()).data;

  try {
    await page.goto('https://staging.example.com/signup');
    await page.fill('[name=email]', address);
    await page.click('button[type=submit]');

    const message = await waitForMail(request, id);
    expect(message.subject).toContain('Confirm');
  } finally {
    await request.delete(`${API}/temp-mail/inboxes/${id}`, { headers });
  }
});

How it works

  • The create call returns data.id and data.address.
  • The list call returns data.items. Each item is a message summary; open one with GET /api/v1/temp-mail/inboxes/{inbox}/messages/{message} to read the full body.
  • DELETE removes the inbox and is free, so always run it in a finally block.

Keep it reliable and cheap

Every poll is billed, so wait a few seconds between polls and set a timeout instead of looping forever. Check the endpoint prices on the Temp Mail API page.

Use a fresh inbox for every test so tests never read each other's mail, and rotate the address if your app rejects an address it has already seen.

Disposable inboxes are for testing. Do not use them for accounts you need to keep.