---
title: "Catch-All Inboxes for QA"
description: "A * account catches mail for every address on your domain that has no account of its own. A fresh address per test, no setup per address."
canonical_url: "https://smtp.dev/docs/guides/catch-all/"
last_updated: "2026-07-16T01:19:47.947Z"
---

Signup flows need a new email address every run. Instead of creating an account per test user, [create one catch-all account](/docs/features/account#catch-all-addresses): username `*`, your domain, one password.

Now any address on the domain is deliverable. Exact matches still win - mail for `support@qa.example.com` goes to the `support` account if it exists, everything else lands in the catch-all.

## Generating Addresses

Derive the local part from the test, so every run is isolated and traceable:

```js
const address = `qa-${crypto.randomUUID()}@qa.example.com`
```

Or keep one real account and use [plus aliases](/docs/features/account#plus-sign-aliasing) - `qa+run42@qa.example.com` delivers to `qa@qa.example.com`, and the full alias stays in the `To` header.

## Finding the Message

Everything arrives in the catch-all's INBOX, so filter by recipient. Get the account and mailbox ids once:

```bash
curl -G "https://api.smtp.dev/accounts" \
  --data-urlencode "address=*@qa.example.com" \
  -H "X-API-KEY: smtplabs_your_api_key_here"

curl "https://api.smtp.dev/accounts/{accountId}/mailboxes" \
  -H "X-API-KEY: smtplabs_your_api_key_here"
```

Then match on the `To` header:

```js
const { member } = await api(`/accounts/${accountId}/mailboxes/${inboxId}/messages`)
const message = member.find(m => m.to.some(t => t.address === address))
```

The polling helper from the [CI guide](/docs/guides/ci) works here too - pass a different `match`.

<note>

[List Messages](/docs/api#list-messages) returns 30 messages per page, newest first. A busy catch-all fills pages fast - match on something unique and poll right after the action that triggers the email.

</note>
