Skip to content
Skip to main content

Extract OTP and 2FA codes from email

OTPs are the single most annoying thing in test automation: a CI runner can’t open Gmail to grab a six-digit code. The Nylas CLI has two commands that solve this — nylas otp get for a single fetch and nylas otp watch for a streaming poll loop. Both work across every provider Nylas supports.

This recipe covers single-shot capture, scripted CI usage, and the watch mode for long-running flows.

nylas otp get

That command scans recent messages on the active grant, identifies a verification code, and copies it to your clipboard. The whole round-trip is sub-second on a healthy mailbox.

For scripts and CI, you want the value on stdout instead of the clipboard:

CODE=$(nylas otp get --raw)

--raw returns the bare code with no formatting, so you can drop it into the next command without parsing.

# Trigger the signup
curl -X POST https://api.example.com/signup -d '{"email":"[email protected]"}'
# Give the verification email a moment to land
sleep 3
# Pull the code
CODE=$(nylas otp get --raw)
# Hand it back to the API
curl -X POST https://api.example.com/verify -d "{\"code\":\"$CODE\"}"

This pattern eats the entire problem — your tests no longer need a fixture inbox, a mocked provider, or a per-environment SMTP server. They just point at a real Nylas-managed grant and read the code.

For long-running flows where you don’t know when the OTP will land:

nylas otp watch --interval 5

The watcher polls the inbox every 5 seconds and prints each new code as it arrives. Pipe it through head -n 1 to grab just the next one and exit:

NEXT_CODE=$(nylas otp watch | head -n 1)

Authentication scales the same way: drop NYLAS_API_KEY into the environment of an ephemeral CI runner and nylas otp get works without a config file.

The OTP commands abstract over Gmail, Microsoft 365, Exchange (EWS), Yahoo Mail, iCloud Mail, and any IMAP server you’ve connected. The matching logic — currently 6-digit numerics with sender heuristics — sits in the Nylas backend, so you don’t tune regex per provider.

  • The active grant matters. nylas otp get reads from whatever account nylas auth list shows as current. Switch with nylas auth switch.
  • Recency window. The CLI considers messages from the last few minutes only. Older codes won’t match — you don’t want yesterday’s GitHub OTP picked up by today’s signup test.
  • Multiple codes in one message. When more than one number-shaped string appears, the CLI prefers the one closest to phrases like “verification code”, “OTP”, or “PIN”. For pathological mail formats, fall back to a custom regex over nylas email read --raw.