Skip to main content

mailtm

A community (unofficial) Python client for the mail.tm temporary email API. No API key or signup required — create a disposable inbox and receive emails over REST or via the Mercure real-time hub.

PyPI - Version PyPI - License PyPI - Python Versions

Table of contents

Installation

Requires Python 3.8+ and requests (installed automatically).

From PyPI:

pip install mailtm-unofficial

From GitHub:

pip install git+https://github.com/irawrre/mailtm.git

From source / for development:

git clone https://github.com/irawrre/mailtm.git
cd mailtm
pip install .

Quick start

from mailtm import MailTM

with MailTM() as mail:
    # Creates a random address (e.g. qk3xh2m9ab@nembul.com) and logs in.
    account = mail.create_account()
    print("Email:", account.address)

    # Wait until a message arrives (matches sender and/or subject).
    message = mail.wait_for_message(from_="no-reply@github.com", timeout=120)
    print(message.subject)

    # Fetch the full message with body + attachments.
    message = mail.get_message(message.id)
    print(message.text)

    for attachment in message.attachments:
        data = mail.download_attachment(attachment)
        open(attachment.filename, "wb").write(data)

Mail.tm is a receive-only service — you can't send email from these addresses, only receive it. Accounts are deleted automatically after a while; you can also delete them yourself with mail.delete_account().

Features

  • Domains — list, pick an active public domain
  • Accounts — create (auto-generates address/password), login, get /me, delete
  • Messages — list/paginate, fetch full detail, mark seen, delete, download .eml source
  • Attachments — download attachment bytes
  • Pollingwait_for_message(...) with sender/subject/body filters and timeout
  • Real-timestream_messages() blocks on the Mercure SSE hub and yields an event every time a message lands

API reference

Domains

mail.get_domains(page=1)          # -> Paginated[Domain]
mail.iter_domains()               # -> Iterator[Domain]
mail.get_domain(domain_id)        # -> Domain
mail.get_random_domain()          # -> Domain (first active, non-private)

Accounts

mail.create_account(address=None, password=None, autologin=True)  # -> Account
mail.login(address, password)     # -> Account (stores bearer token)
mail.get_token(address, password) # -> Token
mail.me()                         # -> Account
mail.get_account(account_id)      # -> Account
mail.delete_account(account_id=None)

create_account() generates the address and password for you when they're omitted and stores them on the client, so you can call mail.login(mail.address, mail.password) again later.

Messages

mail.get_messages(page=1)         # -> Paginated[Message]
mail.iter_messages()              # -> Iterator[Message]
mail.get_message(message_id)      # -> Message (full, with body + attachments)
mail.mark_seen(message_id, seen=True)  # -> bool
mail.delete_message(message_id)
mail.get_source(source_id)        # -> dict (raw source + downloadUrl)
mail.download_message(message_id) # -> bytes (.eml file)
mail.download_attachment(attachment_or_url)  # -> bytes
mail.wait_for_message(from_=..., subject=..., contains=..., timeout=60)  # -> Message

Real-time

mail.stream_messages(account_id=None)  # -> EventStream (blocking Mercure SSE)

Real-time events

Instead of polling you can block on the Mercure hub. Each event carries the account resource with an updated used counter, fired whenever a message is received:

from mailtm import MailTM

with MailTM() as mail:
    account = mail.create_account()
    for event in mail.stream_messages().iter_events():
        print("Account storage now:", event.account().used)

Error handling

All failures raise APIError subclasses carrying the HTTP status code:

Exception Status Meaning
ValidationError 400/422 Malformed or invalid payload
AuthenticationError 401 Bad or missing bearer token
NotFoundError 404 Resource does not exist
RateLimitError 429 More than 8 requests per second
APIError other Any other API error

Rate limits

  • The general rate limit is 8 queries per second per IP address.
  • POST /accounts, GET /domains, and POST /token need no authentication; everything else requires a bearer token.
  • Deleting an account is permanent.

Development

git clone https://github.com/irawrre/mailtm.git
cd mailtm
pip install -e .
pip install pytest
pytest

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

mailtm_unofficial-0.1.1.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mailtm_unofficial-0.1.1-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file mailtm_unofficial-0.1.1.tar.gz.

File metadata

  • Download URL: mailtm_unofficial-0.1.1.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for mailtm_unofficial-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c8aef4104b7a95ef4b3f30eb4989bf76237513fd7555f77adf685ba2e4cb240a
MD5 88b4755e157095c24c1e18a42ad29669
BLAKE2b-256 48d6101084263260a0a514e2b4dcb999570bf0726170d7bee9fb20ad8d590845

See more details on using hashes here.

File details

Details for the file mailtm_unofficial-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for mailtm_unofficial-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 30c47406489398b283372276ceb05a72d200473d05ab29cd5c372601cfa11cf0
MD5 3e5308f7b71d13ca0285970e38b71c88
BLAKE2b-256 a11a1d1b158cd7faa43853c27d9f4e50c50b7ee3b9dba841f2dd2127f72a03fb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page