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.7.0.tar.gz (36.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.7.0-py3-none-any.whl (33.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mailtea-0.7.0.tar.gz
  • Upload date:
  • Size: 36.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.7.0.tar.gz
Algorithm Hash digest
SHA256 32c7930ce9f94a8ffd8f907a6a941b60c4922fa479e6fd2b0e44cd152afd8e9c
MD5 1c5d4479a0756a048c45d8e3471ac235
BLAKE2b-256 be99ae27c569655a65873b4062113518fa5c14c7bab5e9cfe782e146532dfb64

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: mailtea-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 33.6 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.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 885fd9d89d650453b8ee688617c231964c424d5fca1bbab69441a7f1aea5bc03
MD5 7b7d894e64eb00592bb343c34851f524
BLAKE2b-256 be9d2fa3859e457f7841e9fb25ae63f56d198e8e3a40cbe42d695302f25fac84

See more details on using hashes here.

Provenance

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

This release

0.7.0 This release

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

Supported by

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