Skip to content

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.

  1. Create a mailbox and use its address as the sign-up email.

  2. Trigger the sign-up elsewhere (it emails an OTP to your address).

  3. Call wait_for_email with an optional from / subject / regex filter — it blocks until a match lands or the timeout elapses.

  4. Read extracted.otp / extracted.link and submit it back.

wait-for-otp.ts
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=…"

The extracted object comes from the same OTP/link extraction machinery that has pulled codes out of real mail for years.

FieldMeaning
otp_codeThe numeric / alphanumeric one-time code, if one was found.
verification_linkThe first click-through verification URL, if one was found.
credentialsUsername/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.

FilterBehavior
fromMatch the sender address (substring, case-insensitive).
subjectMatch the subject (substring, case-insensitive).
regexMatch the message body against a regular expression.
sinceOnly consider messages newer than this timestamp (default: the call time).
timeout_secondsHow long to block. Server caps at the configured maximum (default 300s).