MailFlat — Python SDK
Official Python client for MailFlat: disposable, automation-friendly email inboxes with one-line OTP retrieval. Spin up a real inbox, read the verification code your app just sent, and move on — no flaky polling, no shared mailbox state.
pip install mailflat
Quickstart
from mailflat import MailFlat
mf = MailFlat(api_key="mf_live_...") # or set MAILFLAT_API_KEY
# 1 · spin up a disposable inbox
inbox = mf.create(label="signup-test")
print(inbox.address) # → signup-test-8f3@x7k2m.mailflat.net
# 2 · your app/browser submits the form using inbox.address ...
# 3 · grab the OTP (polls until it arrives or times out)
otp = inbox.wait_for_otp(timeout=30)
print(otp) # → "123456"
# inbox auto-clears in 2h — no cleanup needed (or call inbox.delete())
For AI agents
Hand an agent one API key and it spins up real inboxes on demand:
mf = MailFlat() # reads MAILFLAT_API_KEY
inbox = mf.create(label="deep-research")
browser.fill("#email", inbox.address)
browser.click("Sign up")
otp = inbox.wait_for_otp(timeout=30)
browser.fill("#code", otp)
API
MailFlat(api_key=None, *, base_url="https://mailflat.net", timeout=30.0, max_retries=2)
Client. api_key falls back to the MAILFLAT_API_KEY environment variable. Use base_url
for self-hosted / BYOD deployments. Supports use as a context manager (with MailFlat() as mf:).
create(*, prefix=None, label=None, subdomain=None, domain=None, retention_hours=None) -> Inbox— open a new inbox.create_inbox(...)is an alias.list() -> list[Inbox]— inboxes opened with this key.inbox(address) -> Inbox— attach to an existing address without a network call.
Inbox
.address— the email address..messages(*, direction="in") -> list[Message]— messages, newest first..latest(*, direction="in") -> Message | None— most recent message..wait_for_otp(*, timeout=30, poll_interval=1.0) -> str— poll until an OTP arrives; returns the code..wait_for_message(*, timeout=30, poll_interval=1.0, direction="in") -> Message— poll until a message arrives..send(to, *, subject="", body="", html=None) -> dict— send a DKIM-signed email from this inbox..mark_read(message_id) -> dict— mark a message read so later polls can skip it..burn() -> dict— delete every message but keep the address..download_attachment(message_id, attachment_id) -> bytes— fetch an attachment's bytes..delete() -> dict— delete the inbox and all its messages.
Reads return received mail by default.
direction="out"returns mail you sent from this address,"all"returns both. This matters for agent-to-agent flows: without it,send()followed bywait_for_message()returns your own outgoing message.
Message
.otp, .subject, .sender, .text, .html, .to_address, .direction, .received_at,
.links, .attachments, .spam, .headers, .is_read, .raw.
.links— URLs found in the body (HTML hrefs first). For "click the verification link" flows..attachments— metadata;msg.attachments[0].download()fetches the bytes. ⚠️send()cannot attach files yet, so you cannot produce an attachment from the SDK alone — send one from a normal mail client to test this path..spam—{score, required, is_spam, rules, scanner}, orNonewhen never scanned (which is not the same as a score of 0). ⚠️ Spam scanning is currently disabled on mailflat.net, so today this isNonefor every message..headers— raw headers, exactly as they arrived. Names are case-insensitive per RFC 5322 but this is a plain dict, so do not index it: the real key isMessage-ID, andheaders["Message-Id"]raisesKeyError. Use.header("message-id")or.message_id..mark_read()/.delete()— act on this message directly.
Errors
All errors subclass MailFlatError: AuthenticationError (401), MailFlatPermissionError (403,
still exported as PermissionError for compatibility — the new name no longer shadows the built-in),
NotFoundError (404), RateLimitError (429, carries .retry_after when the server sent one),
APIError (other), OTPTimeoutError
(no OTP before timeout), EncryptedInboxError (the inbox is end-to-end encrypted, so the
server cannot read its contents — use a non-encrypted inbox for agent automation).
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mailflat-0.4.1.tar.gz.
File metadata
- Download URL: mailflat-0.4.1.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6617a2cb0717ea0536e339bb6072bcc031383e8e8bffa999f32ef5a20645f23
|
|
| MD5 |
90f71f2141103981d9203dd18b714e42
|
|
| BLAKE2b-256 |
ad2cf1a7e8e14cafa9c58fd42461aa919d6a328e7fe092f2369d16b892545a7a
|
File details
Details for the file mailflat-0.4.1-py3-none-any.whl.
File metadata
- Download URL: mailflat-0.4.1-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
501d5a10046e63833f7dd9a7d7f9c2f7366d6d8c759f79f84ca52f44935b7858
|
|
| MD5 |
78d70abcbece6b390b8fdd9cff1c0e11
|
|
| BLAKE2b-256 |
c267cfed10a72484c8c04b677c8c1dee7f95a68d39bc9dfdbdba7a0681d81dfc
|