Skip to main content

mailtea (Python)

The official Python SDK for Mailtea — a thin, zero-dependency wrapper over the REST API. Python 3.9+.

Install

pip install mailtea

Usage

import os
from mailtea import Mailtea

mailtea = Mailtea(os.environ["MAILTEA_API_KEY"])

sent = mailtea.emails.send(
    from_="you@yourdomain.com",
    to="recipient@example.com",
    subject="Hello from Mailtea",
    html="<p>Your first email, sent with <strong>Mailtea</strong>.</p>",
)
print(sent.id)

email = mailtea.emails.get(sent.id)
print(email.status)

The API key can be passed to Mailtea(api_key) or read from MAILTEA_API_KEY. Self-hosting or local dev? pass base_url= or set MAILTEA_API_BASE_URL.

Every method equally accepts a single wire-format dict — handy when you already hold the JSON payload:

sent = mailtea.emails.send({
    "from": "you@yourdomain.com",
    "to": "recipient@example.com",
    "subject": "Hello from Mailtea",
    "html": "<p>Your first email, sent with <strong>Mailtea</strong>.</p>",
})
print(sent["id"])  # responses support ["..."] and attribute access alike

Keyword arguments use snake_case wire names; a trailing underscore escapes Python reserved words (from_="from").

API

Method Description
emails.send(params) Send a transactional email → {"id": ...}
emails.batch(emails) Send up to 100 emails → {"data": [{"id": ...}]}
emails.get(id) Retrieve an email and its delivery status
emails.list(params=None) List emails → {"data", "total", "limit", "offset", "has_more"}
emails.update(id, params) Reschedule a scheduled email
emails.reschedule(id, scheduled_at) Convenience wrapper over update
emails.cancel(id) Cancel a scheduled email
emails.analytics(params=None) Aggregate transactional metrics over an optional date window
emails.inbound.list(params=None) List received emails in a publication (cursor-paginated)
emails.inbound.get(id) Retrieve a received email with body, headers, and attachments
emails.inbound.reply(id, params=None) Reply to a received email (threads by construction)
emails.inbound.attachments.list(id) List a received email's attachments (signed download URLs)
emails.inbound.attachments.get(id, attachment_id) Retrieve one inbound attachment
contacts.create / upsert / list / get / update / delete Manage audience contacts (upsert = create; the endpoint upserts)
posts.create(...) Create a newsletter post (draft, or send=True) → {"id": ...}
posts.send(id, scheduled_at=None) Send a draft post to the audience, now or scheduled
posts.send_test(id, params) Send a [TEST] copy of a post → {"sent_to", "failed_to"}
posts.list(params) List posts (offset-paginated) → {"data", "total"}
posts.get(id, params=None) Retrieve a post by id
posts.update(id, params) Update a draft post (subject, html, text, from, reply_to, name)
posts.delete(id, params=None) Delete a draft post
segments.create / list / get / update / delete Manage audience segments
topics.create / list / get / update / delete Manage topic definitions (visibility="public" → shown on the reader preference page)
senders.create / list / get / update / delete Manage named From identities (email immutable)
templates.create / list / get / update / publish / duplicate / delete Manage reusable email templates
templates.render(params) Render a spec to HTML without saving → {"html", "text"}
templates.versions(id, params=None) List a template's design history, newest first (metadata only)
templates.restore_version(id, version, params=None) Put an older design back — a content write, so the template returns to draft
suppressions.list / add / remove Manage the team-wide do-not-send list
suppressions.export() Export the whole suppression list as CSV (raw text)
domains.create / list / get / verify / update / delete Manage sending domains (add, read DNS records, verify)
domains.tracking.create / list / verify / delete Manage CNAME tracking sub-domains under a domain
webhooks.create / list / get / update / delete Manage outbound event subscriptions
contact_properties.create / list / update / delete Manage custom contact fields (team-scoped)
api_keys.create / list / revoke Manage API keys (settings:write)
automations.create / list / get / update / delete Manage automation graphs (steps + optional connections)
automations.validate(params) Dry-run a graph → {"valid", "issues"} (no automation needed)
automations.activate / pause / archive Lifecycle (cancel_runs defaults false on pause, true on archive)
automations.versions(id, ...) / automations.version(id, version, ...) List stored versions; retrieve one with its graph
automations.metrics(id, params=None) Per-step funnel counts and branch splits (test runs excluded)
automations.test(id, params) One test run against a real contact — sends real, billed email
automation_runs.list / get / cancel Inspect and cancel runs (a run pins the version it started on)
events.send(params) Record a custom event → {"enrolled_automations", "resumed_runs"}
events.list(params) List recorded events (cursor-paginated)
event_definitions.create / list / get / update / delete Manage the event catalog (name immutable)

Payloads follow the REST wire format (reply_to, scheduled_at, …), passed as keyword arguments or a plain dict. Errors raise MailteaError with status, details, and request_id.

emails.send also accepts tags, custom headers, attachments, and scheduled_at. Attachments carry base64 content; set a content_id (plus content_type) to embed an inline image referenced by cid: in the HTML:

mailtea.emails.send(
    from_="you@yourdomain.com",
    to="recipient@example.com",
    subject="Your receipt",
    html='<p>Thanks!</p><img src="cid:logo" />',
    tags=[{"name": "category", "value": "receipt"}],
    attachments=[
        {"filename": "receipt.pdf", "content": pdf_base64},
        {"filename": "logo.png", "content": logo_base64,
         "content_type": "image/png", "content_id": "logo"},  # inline
    ],
)

Verifying webhooks

Mailtea signs every outbound webhook with Standard Webhooks. verify_webhook_signature checks the signature and rejects replays. Pass the raw request body (not re-serialized JSON) and the endpoint's whsec_… signing secret:

from mailtea import verify_webhook_signature

ok = verify_webhook_signature(
    secret=signing_secret,                       # whsec_… from webhooks.create
    msg_id=request.headers["webhook-id"],
    timestamp=request.headers["webhook-timestamp"],
    payload=raw_body,                            # exact bytes/string received
    signature_header=request.headers["webhook-signature"],
)
if not ok:
    return 401

sign_webhook(secret, msg_id, timestamp, payload) produces the same header, handy for faking deliveries in tests. Both are stdlib-only.

Develop

cd sdks/python
python3 -m unittest discover -s tests -t .

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mailtea-0.10.0.tar.gz (40.5 kB view details)

Uploaded Source

Built Distribution

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

mailtea-0.10.0-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

Details for the file mailtea-0.10.0.tar.gz.

File metadata

  • Download URL: mailtea-0.10.0.tar.gz
  • Upload date:
  • Size: 40.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mailtea-0.10.0.tar.gz
Algorithm Hash digest
SHA256 6b3cedb74517b1b54b58c4152a77f8c42a4108df541da31f7b77ae4fed459b85
MD5 d8a79e52b4b546f4fcdc2c0e3a89f6c5
BLAKE2b-256 d8964eb1134a20efc945aab529e75c96fd41a93b9452e0853caa84a3d890c916

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailtea-0.10.0.tar.gz:

Publisher: publish-pypi.yml on mailtea-app/mailtea

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mailtea-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: mailtea-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 34.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mailtea-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb1fbcb85c8dea1f4c03ea528e1326e421124137026539eeb7adf0633749954b
MD5 906af05c8d9fdf29550ac5e66a729a28
BLAKE2b-256 e5dcdd23ba841e204be0c0e5bfec73ac2c5395a77661e8d07059e13ee388756d

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailtea-0.10.0-py3-none-any.whl:

Publisher: publish-pypi.yml on mailtea-app/mailtea

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.10.0 This release

2 files

0.9.1

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page