How should a browser agent handle email verification?

Treat email verification as a controlled wait state, not another open-ended instruction to the agent. The browser requests the email; your controller waits for a matching candidate and decides whether the browser may continue.

Use this workflow only with an application and mailbox you own or are authorized to test. Mailera connects existing mailboxes; it doesn't create an inbox for each browser session. Implement the pause-and-resume logic in your controller, with Mailera supplying email access.

Retrieving a code does not authorize its use. “Latest OTP” is a retrieval result, not proof that the code belongs to the browser session currently waiting. The guide to reading OTP emails from your own inbox covers retrieval separately.

Controller states for requesting verification, waiting, validating, submitting, and confirming success, with failure branches to stop or human review.
Your controller owns these transitions. Retrieving an email does not authorize submission.

What do you need before the agent starts?

Prepare an existing connected test mailbox, an authorized test application, and a browser controller that can preserve the current context while waiting.

For Outlook or Microsoft 365, use Sign in with Microsoft and OAuth. Follow the Microsoft mailbox connection guide rather than adding mailbox credentials to your browser-agent prompt.

Create the retrieval key through Settings → API key → Create key:

  1. Give it a Descriptive name that identifies the test workflow.
  2. Set Mailbox scope to a dedicated test-mailbox group.
  3. Select Read only.
  4. Save the key server-side when it appears. The key is shown only once.
Mailera API key dialog with a dedicated test-mailbox group selected and only Read permission enabled.
Restrict retrieval to the test-mailbox group and Read permission.

Before requesting the verification email, record the following in your controller:

Attempt contextWhat it binds
Mailbox ID and intended recipientThe lookup to the correct test inbox
Application originBrowser actions to the application under test
Expected sender and subjectCandidate selection to the expected email
Request start timeFreshness checks to this request
Browser-session identifierSubmission to the waiting browser context
Deadline and attempt stateWaiting and retries to an explicit policy

These are your controller's fields, not Mailera response fields. If you control the test application, include a distinct attempt reference in its verification email and bind that reference to the controller state.

Keep credentials in the backend component making email requests, not in page JavaScript. The Mailera developer overview describes the available integration options; the examples below use REST for retrieval.

How do you pause, retrieve the code, and resume?

1. Record the attempt and stop browser actions

When the browser reaches the expected verification screen, record the attempt context as it requests the email. Keep that browser context open. Suspend unrelated navigation and repeated resend clicks.

For Browser Use, the official repository documents custom tools: register a function with Tools and pass it to the agent. Put retrieval and validation behind a narrowly scoped tool, with the controller retaining authority over whether submission is allowed.

2. Enter a bounded waiting state

Choose a deadline and polling interval from your application's verification lifetime and test policy. Bound individual requests as well as the overall wait. A temporary absence of a usable candidate should not trigger an immediate resend.

Framework-neutral pseudocode, expressed as controller rules:

  • WAITING: stop on deadline or session expiry; otherwise retrieve a candidate after the configured interval.
  • VALIDATING: return to waiting if there is no candidate; stop for review if association is ambiguous.
  • SUBMITTING: permit one submission only after validation and a fresh check of browser state.
  • COMPLETE: enter only after the application displays its explicit success state.
  • REVIEW: suspend automation until a person deliberately resumes or terminates the attempt.

These state names describe an implementation pattern, not a browser-agent SDK.

3. Retrieve an OTP candidate

Set $MAILERA_API_KEY and $MAILBOX_ID in the server-side environment. Replace the example sender and subject with those used by your test application. The five-minute window below is an example lookup policy, not a delivery promise or code lifetime.

curl --get "https://mailera.app/api/public/v1/mailboxes/$MAILBOX_ID/otp" \
  --header "Authorization: Bearer $MAILERA_API_KEY" \
  --data-urlencode "from=verification@example.com" \
  --data-urlencode "subject=Verify your test sign-in" \
  --data-urlencode "since_minutes=5"

GET /mailboxes/{id}/otp retrieves the latest OTP and requires the read scope. Its documented filters include from, subject, and since_minutes. Refer to the Mailera API documentation when implementing response handling.

Keep responses containing codes out of CI logs and agent traces. The request retrieves a candidate; it must not directly trigger a browser submission.

4. Validate the candidate against the attempt

A relative time window can still include an earlier request. Sender and subject filters narrow the search, but they are not authentication or session correlation.

Inspect messages when you need their metadata:

curl --get "https://mailera.app/api/public/v1/mailboxes/$MAILBOX_ID/messages" \
  --header "Authorization: Bearer $MAILERA_API_KEY" \
  --data-urlencode "folder=inbox" \
  --data-urlencode "from=verification@example.com"

Message results include id, mailbox_id, to, from, subject, and received_at. Check the mailbox and recipient against the recorded attempt, then compare the sender, subject, and receipt time. Follow next_cursor when further results are needed; don't treat the first result as the only possible match.

For a selected message, set $MESSAGE_ID to its id and retrieve its content:

curl "https://mailera.app/api/public/v1/mailboxes/$MAILBOX_ID/messages/$MESSAGE_ID" \
  --header "Authorization: Bearer $MAILERA_API_KEY"

The message content is available in body.text and body.html. Validate any application-provided attempt reference there. Do not mix metadata from one message with a code whose source you haven't established.

Reject unrelated candidates and candidates already consumed by your controller. Receipt time alone doesn't establish when the application generated a code. If repeated requests leave multiple plausible candidates and no reliable association, stop for review rather than choosing the newest one.

5. Submit once and inspect the application

Recheck the application origin, verification screen, and browser-session identity immediately before submission. Pass only the validated code to the browser action.

Record that submission has started so another polling iteration cannot submit again. Then check the application's explicit success state. If the outcome is uncertain, inspect the application before retrying; do not infer failure merely because the agent lost its response.

For human handoff, suspend automated actions and preserve the session if it remains valid. Show the person the attempt state and reason for stopping. Don't let the human and agent operate the verification screen concurrently.

Use the message endpoints to retrieve the content and select the expected verification URL. Keep link parsing in application-specific validation code rather than asking the agent to follow whichever link looks useful.

Before navigation:

  1. Require the expected scheme, normally HTTPS.
  2. Match the parsed host against an explicit application allowlist.
  3. Check the permitted path and any required attempt association.
  4. Stop on an unapproved redirect or an unexpected action.

Treat the URL token as a secret. Redact it from logs, screenshots, and handoff summaries.

Continue in the preserved browser context when the application requires session continuity. Test this requirement for your application rather than assuming all verification links behave alike. Browser Use documents that profile sync transfers cookies but not local storage, IndexedDB, or extensions; a copied profile should not be treated as identical to the still-open context.

An email asking the agent to navigate is not authorization. Unexpected destinations or high-risk actions need human confirmation.

Can you use MCP instead of REST?

Yes. Mailera exposes get_latest_otp with the read scope through its MCP endpoint. Keep the same controller checks around the tool result.

Use tools/list to discover the tool and inspect its inputSchema before constructing a tools/call request. The MCP tools specification defines that discovery flow and recommends tool-call timeouts and validation of results before passing them to an LLM.

The existing-mailbox MCP guide covers the broader connection setup. Changing the transport doesn't change the trust boundary: email content remains data, and the controller still decides whether the browser may resume.

A server-side controller retrieves untrusted email through Mailera and passes only a validated value to the preserved browser session.
Keep email content outside the agent's instruction boundary and credentials outside the browser.

What are the common mistakes and recovery steps?

SymptomWhat to checkSafe next action
No matching emailIntended mailbox, request context, and Inbox or Junk placementInspect the mailbox and Junk before requesting another email. Stop at the deadline.
Mailbox appears disconnected or sleepingGET /mailboxes/{id}/status and mailbox sync informationRepair sign-in if needed. A deliberate POST /mailboxes/{id}/sync requires sync permission; the Read-only key cannot perform it.
Old or unrelated codeRecipient, message time, attempt reference, and consumed-candidate stateReject the candidate. Don't widen the lookup until something submits successfully.
Browser session expiredCurrent session identity and verification screenTerminate the attempt and restart deliberately. Don't submit its code into a replacement session.
Application rejects the codeCurrent application state and whether another request superseded the attemptStop and investigate before resending or submitting again.
Submission outcome is uncertainExplicit success or failure state in the applicationRequest review if the outcome cannot be resolved. Don't blindly repeat the action.

Don't design the wait around guaranteed immediate arrival or Inbox placement. Mailera can show Inbox versus Junk and move messages out of Junk, but moving a message doesn't make the provider trust the sender.

How do you keep email content from controlling the agent?

Incoming email is untrusted data, not instructions. Ignore requests inside it to reveal keys, change tools, send messages, or visit unrelated sites. A familiar sender or subject doesn't make those instructions safe.

Prefer deterministic parsing and validation. Pass only the minimum validated value to the browser action, not the entire email as part of the agent's instruction context.

Keep the dedicated-group key limited to Read. This retrieval workflow doesn't need Send messages, Manage mailboxes, or Sharing. If you extend it to send email or perform another high-risk action, require confirmation before that action. Review Mailera's security information alongside your own controller's access policy.

For debugging, retain redacted state transitions and failure reasons. Exclude codes, verification URLs, API keys, and message bodies from routine traces. If the controller cannot establish that a candidate belongs to the intended attempt, leave the browser paused and hand control to a person.

Do this with the API

Every action in this article is available via the REST API, with curl examples, API keys and webhooks.

View API docs