For AI agents: a documentation index is available at /llms.txt
Skip to main content

Log In via Email OTP

Automate login flows that send a one-time passcode (OTP) to an email address — navigate the login page, trigger the OTP email, read the code, and enter it.

Prerequisites

Steps

The flow has three stages: trigger the OTP email, read the code from the inbox, then enter it in the browser. The examples below show the browser automation steps — substitute getOtpFromInbox() with whichever email API you use.

Connect a browser to trigger the OTP email, wait for the OTP field to appear, then enter the code.

View Full Code on GitHub

1. Install dependencies

npm install puppeteer-core

2. Trigger OTP, read code, enter it

import puppeteer from 'puppeteer-core';

// Swap this stub with your actual inbox API — see the Inbox integrations table below.
async function getOtpFromInbox(email) {
throw new Error('Implement getOtpFromInbox() with your email provider');
}

const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://production-sfo.browserless.io?token=YOUR_API_TOKEN_HERE',
});

try {
const page = await browser.newPage();

// Submit the email to trigger the OTP — the form changes state before the OTP field appears.
await page.goto('https://app.example.com/login', { waitUntil: 'networkidle2' });
await page.type('input[type="email"]', 'user@example.com');
await page.click('button[type="submit"]');
await page.waitForSelector('input[name="otp"], input[autocomplete="one-time-code"]');

// Poll the inbox after the OTP field appears, not before — the email may not be sent yet.
const otp = await getOtpFromInbox('user@example.com');
console.log('Got OTP:', otp);

await page.type('input[name="otp"], input[autocomplete="one-time-code"]', otp);
await page.click('button[type="submit"]');
await page.waitForNavigation({ waitUntil: 'networkidle2' });

console.log('Logged in. URL:', page.url());
} finally {
// Always close to release the session even on error.
await browser.close();
}

3. Check the output

Run with node otp.mjs. Once you supply an getOtpFromInbox() implementation, the script completes the full email OTP login flow.

Inbox integrations

ServiceHow to get the OTP
MailosaurUse the Mailosaur Node/Python SDK — client.messages.get(serverId, ...)
Mailslurpinbox.waitForLatestEmail() with a regex to extract the code
Gmail APISearch for the OTP email subject and parse the body
IMAPUse imaplib (Python) or imap-simple (Node.js) to fetch the latest message

Next steps