Skip to content
Facteur
FRGet started

Email testing

An inbox your tests can query

A dedicated SMTP server per inbox, an API that waits for the message on your behalf, and everything inside it already broken out.

invoice.spec.tsTypeScript
// Several criteria, ALL or ANY matching.
const messages = await facteur.messages.search({
  inbox: 'j3k9x2mq',
  match: 'all',
  sentTo: address,
  subject: 'Your invoice',
  receivedAfter: startOfTest,
});

// Full MIME, nothing hidden.
const [message] = messages;
message.subject;       // 'Your July invoice'
message.html.body;     // raw HTML body
message.text.body;     // text equivalent
message.headers['message-id'];
otp.spec.tsTypeScript
// Extracted on arrival, not by your regex.
message.otp;      // '265279'
message.links;    // [{ href, text }, ...]
message.codes;    // every code detected

// A full 2FA journey with no phone.
const device = await facteur.authenticator.create();
const secret = device.sharedSecret;

await page.getByLabel('Secret key').fill(secret);
await page.getByLabel('Code').fill(await device.otp());

Reception

What the engine does

Unlimited addresses, none to create first

*@<inbox>

Any address ending in the inbox domain lands there. You generate a unique address per test, with no API call and no risk of collision between parallel runs.

Blocking wait, no polling

messages.await

The API holds the connection open until a message matching your criteria arrives, with a timeout you set. Your tests no longer contain an arbitrary sleep, so they stop being flaky.

Full MIME

HTML, text, complete headers, encoding. What arrived on port 25 is what you read.

Attachments, verifiable without downloading them

message.attachments

Name, size and SHA-256 checksum of every attachment, kept apart from signature images. Compare the checksum against your local file to verify exact content, without transferring a single byte.

Automatic extraction

OTP codes, links and buttons are pulled out of the body on arrival. No more brittle regex copied into every test suite.

Send, reply and forward

Reply to a message, forward it to a verified external address, or send an email from an inbox address to test an inbound loop.

Custom domain

Use your own domain rather than ours, when your tests depend on the recipient domain: spam filters, allow lists, personalisation.

Retention set per inbox

From 1 to 60 days depending on your plan. In performance mode the content is never written to disk: we confirm reception and drop the message.

Isolation per team

Each inbox has its own access list, quotas and API keys. Team A’s CI neither sees nor consumes team B’s.

Connectivity

Two ways in

The REST API covers everything, and nothing needs installing to call it. That leaves the case where the message should wake you, rather than the other way round.

REST API

An OpenAPI-documented API, with its public reference and its guides. Nothing to install: the waiting happens on the server and the extraction on reception, so a test calls the message search with no dependency at all. The Playwright and Cypress plugins are on npm, and installing them stays optional: they buy comfort, not capability. The Integrations page carries the address of each.

Webhooks

Every message received can trigger an HMAC-signed HTTP call to your system, with retries and a delivery log.

Your first inbox in two minutes

The free plan asks for no card. If you are switching tools, the steps fit on one page and can be tried on a single test.