otp-gateway
Zero-dependency Python library for receiving OTP codes via IMAP.
Watch your inbox for verification emails from 30+ platforms — GitHub, Google, Discord, OpenAI, and more. No third-party APIs, no SMS gateways. Just IMAP.
Features
- 🔑 13 OTP extraction patterns — digits, alphanumeric, multi-language
- 📬 IMAP auto-polling with configurable timeout & interval
- 🔗 Verification link extraction from email bodies
- 📛 Alias generation for catch-all domains
- 🔄 Smart dedup — never returns the same OTP twice
- 🐍 Zero dependencies — only Python stdlib
- 🖥️ CLI + Python API — use from terminal or import in code
Install
pip install otp-gateway
Or just copy otp_gateway/ into your project — zero external deps.
Quick Start
Python API
from otp_gateway import OTPGateway, OTPConfig
# Configure
config = OTPConfig(
imap_email="you@gmail.com",
imap_password="your-app-password", # Gmail: use App Password
domain="yourdomain.com", # optional: for alias generation
)
gw = OTPGateway(config)
# Option 1: Watch a specific email address
result = gw.wait_for_otp("github-abc123@yourdomain.com")
print(result["value"]) # "847291"
# Option 2: Generate alias + wait
alias = gw.generate_alias("github")
print(alias) # "github-a7k2m3@yourdomain.com"
# ... use this email to sign up ...
result = gw.wait_for_otp(alias, timeout=90)
print(result["value"]) # the OTP code
# Option 3: One-shot check (no waiting)
result = gw.search_otp("some@email.com")
if result:
print(result["type"]) # "code", "link", or "raw"
print(result["value"]) # the OTP code or link
CLI
# Interactive setup
otp-gateway init
# Or pass credentials directly
otp-gateway --email you@gmail.com --password "xxxx" --domain yourdomain.com generate github
otp-gateway --email you@gmail.com --password "xxxx" wait github-a7k2m3@yourdomain.com
# Or use a config file
otp-gateway --config ~/.otp_gateway/config.json generate openai
otp-gateway --config ~/.otp_gateway/config.json check some@email.com
otp-gateway --config ~/.otp_gateway/config.json list
Config
JSON config file (~/.otp_gateway/config.json)
{
"imap_server": "imap.gmail.com",
"imap_port": 993,
"imap_email": "you@gmail.com",
"imap_password": "your-app-password",
"domain": "yourdomain.com"
}
Environment variables
export OTP_IMAP_SERVER=imap.gmail.com
export OTP_IMAP_EMAIL=you@gmail.com
export OTP_IMAP_PASSWORD=your-app-password
export OTP_DOMAIN=yourdomain.com
Programmatic
config = OTPConfig(
imap_server="imap.gmail.com",
imap_port=993,
imap_email="you@gmail.com",
imap_password="your-app-password",
domain="yourdomain.com",
)
How It Works
- Catch-all routing: Set up your domain to forward all
*@yourdomain.comto one Gmail inbox - Alias generation:
otp-gatewaycreates unique aliases likegithub-a7k2m3@yourdomain.com - IMAP polling: When you request an OTP, it polls your inbox for emails sent to that alias
- Pattern matching: 13 regex patterns extract the OTP code or verification link
- Dedup: Tracks seen message IDs so the same OTP is never returned twice
Catch-all domain setup
| Provider | Setup |
|---|---|
| Cloudflare | Email Routing → Catch-all → forward to Gmail |
| Namecheap | Forwarding → Catch-all |
| Google Domains | Email → Forwarding → Add catch-all |
| Any SMTP | Configure your mail server's catch-all |
Gmail App Password
- Go to Google Account → Security → App Passwords
- Generate a new app password for "Mail"
- Use that 16-char password as
imap_password
Supported Platforms
The library works with any platform that sends OTP via email. Built-in alias prefixes for:
| Platform | Prefix | Platform | Prefix | |
|---|---|---|---|---|
| GitHub | gh |
Discord | dsc |
|
go |
Twitter/X | tw |
||
| OpenAI | oai |
Anthropic | ant |
|
| HuggingFace | hf |
DeepSeek | ds |
|
| Groq | grq |
Replicate | rep |
|
| Modal | mod |
Railway | rlw |
|
| AWS | aws |
Azure | azr |
|
| Cloudflare | cf |
Binance | bnb |
|
| Supabase | spb |
Vercel | vrc |
|
| Cohere | coh |
Mistral | mst |
Add custom prefixes:
gw.add_prefix("myplatform", "mp")
alias = gw.generate_alias("myplatform") # mp-a7k2m3@yourdomain.com
Response Format
{
"type": "code", # "code", "link", or "raw"
"value": "847291", # the OTP code or link
"from": "noreply@github.com",
"subject": "Your GitHub verification code",
"date": "Mon, 25 Jun 2026 12:00:00 +0000",
"msg_id": "42"
}
Error Handling
from otp_gateway import OTPGateway, OTPConfig, OTPTimeoutError, IMAPConnectionError
try:
code = gw.get_otp("test@example.com", timeout=60)
except OTPTimeoutError:
print("OTP not received in time")
except IMAPConnectionError:
print("Can't connect to IMAP server")
Tests
pip install pytest
pytest tests/ -v
All tests use mocks — no real IMAP connection needed.
Requirements
- Python 3.10+
- No external dependencies (stdlib only)
License
MIT
Metadata
Release files for otp-gateway 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| otp_gateway-2.0.0.tar.gz | 15.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| otp_gateway-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.4 kB
Release files / otp_gateway-2.0.0.tar.gz
| Download URL | otp_gateway-2.0.0.tar.gz |
|---|---|
| Size | 15.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9090aaa6476059a7d13d64461244ab1d2da337f4175f0bc98c45e93d92edbf5
|
|
BLAKE2b-256 checksum How to use checksums |
773940692c65ce3e48ec166e931457d7215ff0908e68fde8046a1c9cd384966d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / otp_gateway-2.0.0-py3-none-any.whl
| Download URL | otp_gateway-2.0.0-py3-none-any.whl |
|---|---|
| Size | 13.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
179376cd7fc22afa8456b761443ef477b6249d55b1362049aca86d8fa958fcc0
|
|
BLAKE2b-256 checksum How to use checksums |
fdb524d8497b079563623d144d2b073c11b2fb894c761233dcd68a11a125f438
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|