{"slug": "how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex", "title": "How can an AI agent read an email verification code without writing a regex?", "summary": "Agentboxd released an email verification API that lets AI agents extract sign-up codes and confirmation links without regex, using a server-side pattern matcher plus an AI classifier that returns a confidence score. The endpoint GET /v1/inboxes/:id/verification (SDK waitForVerification, MCP get_verification_code) holds a request open for up to 60 seconds until a verification email newer than a supplied timestamp arrives, avoiding polling loops and stale codes. Pattern matching alone caps confidence at 0.7, while the classifier raises it to 0.95 on a clear verification email and drops it to 0.2 on a clear negative.", "body_md": "*Sign-up forms stop agents with “we sent you a code”. The obvious fix, a six-digit regex over the inbox, works in a demo and breaks on real mail. Here is why, and the one call that replaces it.*\n\n**TL;DR** Give the agent its own inbox, note the time, trigger the email, then call `GET /v1/inboxes/:id/verification` (SDK `waitForVerification`, MCP `get_verification_code`). It waits up to 60 seconds and returns the code or link with a confidence score. The extraction runs on our server the moment the email arrives, and an AI check confirms it is really a verification email.\n\nBecause verification emails are full of other numbers. Order numbers, dates, prices, phone numbers, copyright years and ticket IDs all look like codes to `\\d{6}`. And many codes don’t look like six digits at all: some are four or eight digits, some are letters and digits, some are split by a space or a hyphen.\n\n``` js\n// The usual first attempt\nconst code = message.text.match(/\\b\\d{6}\\b/)?.[0];\n\n// What it finds in real sign-up emails:\n//   \"Order 482913 confirmed\"          → 482913   (an order number)\n//   \"© 2026 Example Inc.\"             → no match, but \"2026\" at 4 digits would be\n//   \"Call +1 415 555 0199\"            → no match, or part of a phone number\n//   \"Your code: KQ7-M2X\"              → no match (letters and a hyphen)\n//   \"G-583920 is your Google code\"    → 583920, luckily\n```\n\nLinks are worse. A sign-up email has a confirm button, but also “log in”, “manage preferences”, “unsubscribe”, tracking pixels and a privacy policy. Taking the first link can unsubscribe the agent instead of confirming it. And an agent that polls the inbox in a loop either waits too long or reads the previous code.\n\nEvery inbound email is checked for a code or link the moment it is stored, before your agent asks. The rules favour precision, because a wrong code is worse than none: the agent can always read the message itself.\n\n`482 913` → `482913`, `KQ7-M2X` → `KQ7M2X`, `G-583920` → `583920`).\nOn top of the pattern match, an AI classifier reads the email and answers one question: is this a login, one-time-code or confirm-your-email message? Pattern matching alone is capped at a confidence of 0.7. A clear yes from the classifier raises it to 0.95; a clear no drops it to 0.2. The classifier’s own answer is returned too, as `jev_probability`. How the classifier works is in [How we classify every email an AI agent receives](https://agentboxd.com/blog/classifying-inbound-email-for-ai-agents-jev?utm_source=devto&utm_medium=social&utm_campaign=xpost-email-verification-codes).\n\nThree steps: note the time, trigger the email, wait. The wait endpoint holds the request open until a verification email newer than `since` arrives, up to 60 seconds, and returns the newest one, since the latest code is the valid one. No polling loop, no sleep.\n\n``` js\nimport { Agentboxd } from 'agentboxd';\n\nconst mr = new Agentboxd({ apiKey: process.env.AGENTBOXD_API_KEY! });\n\n// 1. Note the time BEFORE triggering the email, so an older code can't be picked up.\nconst since = new Date().toISOString();\n\n// 2. Trigger the sign-up (browser automation, an API call, whatever your agent does).\nawait signUpOnTheSite({ email: inbox.address });\n\n// 3. Wait up to 60 seconds for the code or link to arrive.\nconst v = await mr.messages.waitForVerification(inbox.id, { since, timeout: 60, from: 'example.com' });\n\nif (!v) throw new Error('no verification email within 60 s');\nif (v.confidence < 0.9) console.warn('low confidence: read the message', v.message_id);\n\nawait enterCode(v.code ?? undefined); // or open v.link\npython\nfrom datetime import datetime, timezone\nfrom agentboxd import Agentboxd\n\nmr = Agentboxd()  # reads AGENTBOXD_API_KEY\n\nsince = datetime.now(timezone.utc).isoformat()\nsign_up_on_the_site(email=inbox[\"address\"])\n\nv = mr.messages.wait_for_verification(inbox[\"id\"], timeout=60, since=since, from_=\"example.com\")\nif v is None:\n    raise TimeoutError(\"no verification email within 60 s\")\nprint(v[\"code\"] or v[\"link\"], v[\"confidence\"])\ncurl -s \"https://api.agentboxd.com/v1/inboxes/$INBOX_ID/verification?timeout=60&since=2026-09-29T10:00:00Z&from=example.com\" \\\n  -H \"Authorization: Bearer $AGENTBOXD_API_KEY\"\n{\n  \"data\": {\n    \"code\": \"583920\",\n    \"link\": null,\n    \"confidence\": 0.95,\n    \"jev_probability\": 0.97,\n    \"message_id\": \"0b3e8f4c-…\",\n    \"from\": \"Example <no-reply@example.com>\",\n    \"subject\": \"Your Example verification code\",\n    \"received_at\": \"2026-09-29T10:00:07.412Z\"\n  }\n}\n```\n\nTwo details matter. Pass `since` from before you triggered the email: the default is the moment your request arrives, so a code that landed a second earlier would be missed. And pass `from` (a case-insensitive part of the sender) when the inbox is shared, so a code from another site can’t be picked up. On timeout you get `data: null`, not an error.\n\n| Confidence | What it means | Suggested action | \n|---|---|---|\n| 0.95 | Pattern found and the classifier confirmed a verification email | Use the code or link | \n| 0.5 – 0.7 | Pattern found, not confirmed yet (or AI processing is off for the workspace) | Use it for a sign-up you just started; otherwise read the message | \n| 0.2 | The classifier says this is not a verification email | Don’t use it; read the message | \n\nYes. A temporary inbox is receive-only, lives on its own domain, and deletes itself and its mail when its time is up (1 minute to 24 hours, 15 minutes by default). Use it for trials and one-off sign-ups; keep a permanent inbox for accounts the agent will log back into.\n\n```\n// A receive-only inbox that deletes itself (and its mail) after 15 minutes.\nconst inbox = await mr.inboxes.createTemporary({ ttlSeconds: 900 });\nconst since = new Date().toISOString();\nawait signUpOnTheSite({ email: inbox.address });\nconst v = await mr.messages.waitForVerification(inbox.id, { since, timeout: 60 });\n```\n\nSome sites refuse known disposable domains. Temporary inboxes are on a separate domain for exactly that reason: if it gets listed, your permanent agent addresses are unaffected. If a site refuses it, use a permanent inbox.\n\nYes. The answer has `code`, `link` or both; one of them is set whenever a verification email was found.\n\nYou get the newest verification email after `since`. Codes are usually replaced when a new one is sent, so the newest is the one that works.\n\nYes: the `get_verification_code` tool does the same wait, and `create_temporary_inbox` makes a throwaway address. See the [MCP server docs](https://agentboxd.com/docs/mcp?utm_source=devto&utm_medium=social&utm_campaign=xpost-email-verification-codes).\n\nOnly if the workspace allows AI processing (the default, `categorize`), and then only to the classifier, for the confirmation step. With AI processing off, the pattern match still returns the code, without the confirmation. Details in [AI processing and privacy](https://agentboxd.com/docs/ai-processing?utm_source=devto&utm_medium=social&utm_campaign=xpost-email-verification-codes).\n\nStart with the [quickstart](https://agentboxd.com/docs/quickstart?utm_source=devto&utm_medium=social&utm_campaign=xpost-email-verification-codes): an inbox is one API call, and the free plan is enough to try this today.\n\n*Originally published on the [Agentboxd blog](https://agentboxd.com/blog/email-verification-codes-ai-agents-without-regex?utm_source=devto&utm_medium=social&utm_campaign=xpost-email-verification-codes).*", "url": "https://wpnews.pro/news/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex", "canonical_source": "https://dev.to/elkiks/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex-2e3k", "published_at": "2026-09-29 11:37:43+00:00", "updated_at": "2026-09-29 11:46:41.653935+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "natural-language-processing"], "entities": ["Agentboxd"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex", "markdown": "https://wpnews.pro/news/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex.md", "text": "https://wpnews.pro/news/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex.txt", "jsonld": "https://wpnews.pro/news/how-can-an-ai-agent-read-an-email-verification-code-without-writing-a-regex.jsonld"}}