wait_for_email — the OTP flow
Agents sign up for things. The high-value, time-boxed task is “wait for the verification email and
read the code before the 5-minute window closes.” wait_for_email is the primitive for exactly that:
a blocking call that returns the next matching message with the OTP code and verification link
already extracted.
No polling loop. Postern blocks server-side on the inbox (IMAP IDLE on WildDuck) and hands you a structured result the moment a matching message arrives.
The shape of the flow
Section titled “The shape of the flow”-
Create a mailbox and use its address as the sign-up email.
-
Trigger the sign-up elsewhere (it emails an OTP to your address).
-
Call
wait_for_emailwith an optionalfrom/subject/regexfilter — it blocks until a match lands or the timeout elapses. -
Read
extracted.otp/extracted.linkand submit it back.
Wait for it
Section titled “Wait for it”import { Postern } from "@postern/sdk";
const postern = new Postern({ apiKey: process.env.POSTERN_API_KEY! });const inbox = await postern.inboxes.create({ username: "signup-agent" });
// Trigger a sign-up that emails an OTP to inbox.address.await fetch("https://acme.test/signup", { method: "POST", body: JSON.stringify({ email: inbox.address }),});
// Block until it lands (up to 2 min), then read the structured result.const result = await inbox.waitForEmail({ from: "no-reply@acme.test", subject: "verification", timeout_seconds: 120,});
if (result.timed_out) throw new Error("no email in time");
console.log(result.extracted.otp); // "492013"console.log(result.extracted.link); // "https://acme.test/verify?token=…"{ "name": "wait_for_email", "arguments": { "address": "signup-agent@x4p.mszazu.com", "from": "no-reply@acme.test", "subject": "verification", "timeout_seconds": 120 }}{ "timed_out": false, "message": { "id": "msg_8Tz", "from": "no-reply@acme.test", "subject": "Verify your email" }, "extracted": { "otp_code": "492013", "verification_link": "https://acme.test/verify?token=…" }}Because the host gets the code in the same turn, the agent can submit it without losing the window. This is what makes Postern feel different from “an inbox you poll.”
curl -sS -X POST \ "$POSTERN_API_BASE_URL/v1/inboxes/signup-agent@x4p.mszazu.com/wait" \ -H "Authorization: Bearer $POSTERN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "from": "no-reply@acme.test", "subject": "verification", "timeout_seconds": 120 }'The request hangs (long-poll) until a matching message arrives or the timeout elapses. Set your HTTP
client’s read timeout above timeout_seconds.
What gets extracted
Section titled “What gets extracted”The extracted object comes from the same OTP/link extraction machinery that has pulled codes out of
real mail for years.
| Field | Meaning |
|---|---|
otp_code | The numeric / alphanumeric one-time code, if one was found. |
verification_link | The first click-through verification URL, if one was found. |
credentials | Username/password pairs when the message contains them. |
In the SDK these are extracted.otp, extracted.link, and extracted.credentials. Need extraction
without a wait? Import extractOtp / extractLink / extractCredentials and run them on any string.
Filters
Section titled “Filters”| Filter | Behavior |
|---|---|
from | Match the sender address (substring, case-insensitive). |
subject | Match the subject (substring, case-insensitive). |
regex | Match the message body against a regular expression. |
since | Only consider messages newer than this timestamp (default: the call time). |
timeout_seconds | How long to block. Server caps at the configured maximum (default 300s). |
- MCP
wait_for_email— the tool definition and host behavior. - API · wait_for_email — the endpoint contract.
- Inboxes — the receive model behind it.