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.6.0.tar.gz (33.3 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.6.0-py3-none-any.whl (32.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for mailtea-0.6.0.tar.gz
Algorithm Hash digest
SHA256 ba5bdd3194700eee0c5d9c9cf6455706dcf2ac1d27df5b613cb3ca6e827c1772
MD5 57a15a886dc3e6a61a136d070ee31516
BLAKE2b-256 04094e1a9c8564f8935749c88ad22779d940c5c3bba1dbe8e4cb0b1085a958da

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailtea-0.6.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.6.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for mailtea-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9435cca126c286c6d455443c6c3d4d3f2a28e8b1641fb92996b0522d5ccb453a
MD5 ec91090323f7828fe3294fb1c26c67d2
BLAKE2b-256 71affb7fc859b4d10d81c120db560c3d282f8c5099708f7ddeacb83af085bc84

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailtea-0.6.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

0.8.0

2 files

0.7.0

2 files

This release

0.6.0 This release

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

Supported by

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