Skip to content
Not available yet. Replyz is built and tested, but not deployed: https://api.replyz.io is the planned address and does not answer yet. These pages describe the API as it is built today and may change before launch.

Waiting for mail

GET /v1/inboxes/{id}/wait is a long-poll on one inbox. It answers as soon as matching mail is there, or with status: "timeout" when the time is up. It is made for “I just signed up somewhere, now give me the verification email”. To watch every inbox with one call, use the event feed.

Parameter Default Rules
since now − 10 minutes ISO 8601 time. Only messages received at or after it
from none Case-insensitive pattern for the whole sender address: * = any characters, ? = one character. Example: *@accounts.example.com
subject none Case-insensitive part of the subject
thread_id none Only messages of that thread
exclude_returned false true skips messages already returned (see “Read flag”)
limit 10 1–50 messages in one answer
timeout 25 0–60 seconds to hold. 0 checks once and answers at once
extract none otp, link or otp,link: add the code and links to each message. See Get a verification code

All filters must match. Messages without a sender or subject never match from or subject.

  1. wait checks at once. If anything matches, it answers immediately with all matches, newest first, up to limit. It never waits to fill limit.
  2. Otherwise it holds. Every new message of the account wakes it to check again, until something matches or timeout passes.
  3. Both outcomes are HTTP 200:
{ "status": "timeout", "messages": [], "next": "No matching mail yet. Call wait again." }

An ok answer has status: "ok" and the messages (see the Quickstart).

  • since defaults to 10 minutes back, so a code that arrived just before the call is returned at once.
  • Within those 10 minutes the same message comes back on every call (with returned_before: true), unless you pass exclude_returned=true or a later since.
  • A message becomes visible a little after its received_at. Do not set since to the exact moment of your call: use the default, or a time a minute or two before you triggered the email (this also covers clock differences).

A message counts as read once wait, GET /v1/messages/{id} or POST /v1/messages/{id}/extract has returned it. Listing messages, threads, the event feed and attachment downloads never mark anything. Each message carries returned_before: whether it had been returned before this call.

With exclude_returned=true, a message whose earlier answer your agent never processed (for example after a crash) is skipped too. Find it with the message list.

  • An account can hold at most 5 long-polls at the same time, wait and events?wait= together.
  • A call that answers at once (mail already there, or timeout=0) does not use a slot.
  • A 6th hold gets 429 too_many_waits with Retry-After: 1. A long hold can also end with it after 20 or 40 seconds if all slots were taken in between.

Set your HTTP client timeout above the timeout you ask for, for example timeout + 15 seconds (curl --max-time 65 for timeout=50). If your agent’s HTTP tool has a fixed shorter limit, lower timeout to fit under it.

  • wait looks at the 500 newest messages that match the inbox, since, thread_id and exclude_returned, then applies from and subject. Keep since recent.
  • Two wait calls running at the same time can both return the same message, each with returned_before: false.
  • An expired or suspended account never holds: it answers at once with mail already stored, or timeout.
  • wait on a deleted inbox answers 404 not_found.

No push delivery: webhooks are not offered. An MCP and a CLI version of wait are coming soon.

Reference: GET /v1/inboxes/{id}/wait.