---
title: "Browser agent email verification: pause, validate, resume"
description: "Pause a browser agent for email verification, retrieve a code or link from your own test inbox, validate the attempt, and safely resume or request human help."
url: https://mailera.app/en/blog/browser-agent-email-verification
published: 2026-10-25
updated: 2026-10-25
---

# Browser agent email verification: pause, validate, resume

Keep the browser session open while a controller retrieves a code or link from your existing test inbox. Resume only when the email matches the current attempt, and hand control to a person when it doesn't.

## 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](https://mailera.app/en/product); 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](https://mailera.app/en/blog/otp-email-api-test-inbox) covers retrieval separately.

![Controller states for requesting verification, waiting, validating, submitting, and confirming success, with failure branches to stop or human review.](https://mailera.app/media/55f4954e885d7e04/browser-agent-email-verification-pause-validate-resume-en-1200.jpg)
_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](https://mailera.app/en/providers/microsoft) 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.](https://mailera.app/media/217359b4b870c539/browser-agent-email-verification-pause-validate-resume-read-en-1200.jpg)
_Restrict retrieval to the test-mailbox group and Read permission._

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

| Attempt context | What it binds |
| --- | --- |
| Mailbox ID and intended recipient | The lookup to the correct test inbox |
| Application origin | Browser actions to the application under test |
| Expected sender and subject | Candidate selection to the expected email |
| Request start time | Freshness checks to this request |
| Browser-session identifier | Submission to the waiting browser context |
| Deadline and attempt state | Waiting 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](https://mailera.app/en/developers) 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](https://github.com/browser-use/browser-use): 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.

```bash
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](https://mailera.app/en/docs) 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:

```bash
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:

```bash
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.

## What changes when the email contains a verification link?

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](https://mailera.app/en/mcp). 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](https://modelcontextprotocol.io/specification/2025-06-18/server/tools) defines that discovery flow and recommends tool-call timeouts and validation of results before passing them to an LLM.

The [existing-mailbox MCP guide](https://mailera.app/en/blog/email-mcp-server-existing-mailboxes) 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.](https://mailera.app/media/739618839e4282f6/browser-agent-email-verification-pause-validate-resume-en-1200.jpg)
_Keep email content outside the agent's instruction boundary and credentials outside the browser._

## What are the common mistakes and recovery steps?

| Symptom | What to check | Safe next action |
| --- | --- | --- |
| No matching email | Intended mailbox, request context, and Inbox or Junk placement | Inspect the mailbox and Junk before requesting another email. Stop at the deadline. |
| Mailbox appears disconnected or sleeping | `GET /mailboxes/{id}/status` and mailbox sync information | Repair sign-in if needed. A deliberate `POST /mailboxes/{id}/sync` requires `sync` permission; the Read-only key cannot perform it. |
| Old or unrelated code | Recipient, message time, attempt reference, and consumed-candidate state | Reject the candidate. Don't widen the lookup until something submits successfully. |
| Browser session expired | Current session identity and verification screen | Terminate the attempt and restart deliberately. Don't submit its code into a replacement session. |
| Application rejects the code | Current application state and whether another request superseded the attempt | Stop and investigate before resending or submitting again. |
| Submission outcome is uncertain | Explicit success or failure state in the application | Request 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](https://mailera.app/en/security) 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](https://mailera.app/en/docs)
