Search the docs

Find a page, a section, or an endpoint.

Verification codes

Waiting for a sign-up email and reading the code out of it.

Your agent fills in a sign-up form with an address it owns, and the service emails a code or a confirmation link. This is how it gets that back: one request that waits for the mail, with the code already pulled out of it.

Wait for the message

GET /v1/messages/await holds the request open until a message arrives at the address, or until timeout seconds pass — 60 by default, at most 280. Make the call, then submit the form; the answer comes back when the mail does.

curl -G https://pidgeon.ai/api/v1/messages/await \
-H "Authorization: Bearer $PIDGEON_API_KEY" \
-d identity_id=$IDENTITY_ID \
-d has_code=true \
-d timeout=120

The answer is { message, timed_out, cursor }. When nothing came in time, message is null and timed_out is true — call again with after: cursor and nothing that arrives in between is missed. Start the wait before you submit the form, or pass the cursor from an earlier call, so a fast service cannot answer before you are listening.

Narrow what counts

ParameterWaits for
identity_idThe address. Required, and the key has to be able to read it.
fromAn exact sender, or @example.com for anybody at that domain.
subject_containsA subject containing these words, ignoring case.
has_codetrue: only a message with a code or a verification link in it. Skips the welcome.
afterOnly mail that arrived after this cursor.

What is extracted

Every message — here, on GET /v1/messages/{id} and in a list — carries extracted:

  • codes — candidates, most likely first, each with value and kind (numeric or alphanumeric). Spaces are removed, so 123 456 comes back as 123456.
  • links — verification, confirmation and sign-in links first, then the rest. Unsubscribe, preference and social links are left out.

It is a list rather than one answer because finding a code in an email is a heuristic: an order number or a phone number can sit right above it. Take the first; if the service refuses it, the second is right there, and the message itself is in the same response for a person to look at.

Codes are read from the new text of the message, never from quoted history, so a code from an earlier email in the thread is not offered again.

From an agent

The MCP server has await_message, with the same parameters. A model that has just submitted a sign-up form calls it and reads extracted.codes[0].value from the answer.

Limits

Thirty waits a minute per workspace. A held request counts once however long it waits; a caller looping on timed_out is the one that runs into it.