Setting up Cofactor agents to receive email
Give test accounts a mailbox, allow your app's sender domain, and let the agent read codes, links, and invitations during a run.
Let your tests read the email your application sends — sign-in codes, magic links, invitations, password resets, notifications. Cofactor gives a test account its own mailbox on @testuser.runcofactor.com; mail your app sends to that address is captured, and the agent reads it during a run.
- A mailbox per account — every credential can have an inbox address; seeded users get a fresh one on every run.
- Sender allow list — only mail from domains you approve is delivered, so a mailbox can't be spammed or spoofed.
- Agent reads it — a step that says "open the verification email and use the code" just works; the agent searches, waits for, and reads the message itself.
01Give the account a mailbox
Every mailbox is tied to a credential. Three ways to get one:
| Situation | What to do |
|---|---|
| New credential | In Add credential, choose to provision an inbox. Cofactor assigns a unique address on @testuser.runcofactor.com and uses it as the login email. |
| Existing credential (any login type) | Pair an inbox from the credential's settings. The account can still sign in with a username or token; the inbox just gives it an address to receive mail. |
| A fresh user per run | Turn on Create email inbox on the seed's credential output — see Seeding a fresh test user. |
The credentials list shows an Email inbox badge on every credential that has one. Your application must know that address — it's the email you register, invite, or send to. See Credentials and login for the credential side.
02Allow your sender domain
Cofactor only delivers mail whose sender is on your organization's allow list. Everything else is dropped, silently, before it reaches a mailbox.
- Open the application and go to its Messages tab.
- Under Allow a sender domain, enter the domain your app sends from and add it.
Rules for the list:
- Exact match, one entry per domain.
myapp.comdoes not covermail.myapp.comornotifications.myapp.com— add each domain your app sends from. - Both the visible From address and the envelope sender count. Mail is delivered if either is on the list. Email providers often use a separate bounce/envelope domain (for example
em1234.myapp.comor the provider's own domain) — if mail isn't arriving, check the raw headers of a real message and add that domain too. - Matching is case-insensitive.
The sender domain is the domain in your app's outgoing mail, not the
testuser.runcofactor.comdomain of the mailbox.
03Write the step
Describe what to read and what to do with it — the agent has an inbox tool scoped to the credential in use and handles searching, waiting for delivery, and opening the message:
- "Open the verification email sent to
$var.new_user.usernameand enter the 6-digit code." - "Follow the Accept invitation link from the most recent email."
- "Wait for the password-reset email, open the reset link, and set the password to
$var.new_user.password."
Don't hard-code a code or link in the step's inputs — it changes every run. If a login flow itself needs a code (OTP, magic link), select a credential with a paired inbox and the login handles it; see Credentials and login.
04See what arrived
The application's Messages tab lists every message delivered to its mailboxes — filter by mailbox, search subject or body, and open a message to see what the agent saw. Use it to confirm delivery before blaming the step.
05Troubleshooting
| Symptom | Likely cause |
|---|---|
| Nothing arrives in Messages | Sender domain not on the allow list (check both From and envelope domains), or the app sent to a different address than the credential's inbox. |
| Message is in Messages but the step failed | The step's description didn't match the email (searching "magic link" when the subject is the product name). Describe the message loosely — "the most recent sign-in email" — rather than quoting a subject. |
| Code expired | The step waited too long before reading; put the read immediately after the action that triggers the email. |
| Mail delivered to the wrong test | Two credentials sharing an address. Each credential gets its own inbox — don't reuse one across accounts. |