Skip to main content

Mailkube Python SDK

Project description

mailkube

CI PyPI License: Apache 2.0 Python Ruff Code of Conduct

The official Python SDK for Mailkube — send transactional email and verify inbound webhooks. Fully typed, sync and async, Python 3.12+.

Full product and API documentation: mailkube.com/docs.

Install

pip install mailkube
# or
uv add mailkube

Configuration

from mailkube import Mailkube

client = Mailkube(
    api_key="mk_...",                    # or set MAILKUBE_API_KEY
    base_url="https://api.mailkube.com/mta/v1/",  # or set MAILKUBE_BASE_URL; this is the default
    timeout=30.0,                        # per-request timeout in seconds
)

AsyncMailkube takes the same arguments. Both also accept http_client= — your own httpx.Client / httpx.AsyncClient — if you need custom transport, proxies, or mTLS; the SDK will not close a client you pass in.

Send an email

from mailkube import Mailkube

with Mailkube() as client:
    email = client.emails.send(
        from_="Acme <hello@yourdomain.com>",
        to="customer@example.com",
        cc="manager@example.com",
        reply_to="support@yourdomain.com",
        subject="Hello world",
        html="<p>It works!</p>",
    )
    print(email.id, email.message_id)

from_ maps to the wire from field (from is a reserved keyword). Supply html and/or text, or a template_id with template_version and variables. Attachments accept raw bytes or a base64 string. See SendEmailParams for the full field list (cc, bcc, reply_to, headers, attachments, template_id, topic, idempotency_key, …).

Async

import asyncio
from mailkube import AsyncMailkube

async def main():
    async with AsyncMailkube() as client:
        email = await client.emails.send(
            from_="Acme <hello@yourdomain.com>",
            to="customer@example.com",
            subject="Hello world",
            html="<p>It works!</p>",
        )
        print(email.id)

asyncio.run(main())

Idempotency

Pass idempotency_key to safely retry a send without risking a duplicate — sent as the Idempotency-Key header, not in the body:

email = client.emails.send(
    from_="Acme <hello@yourdomain.com>",
    to="customer@example.com",
    subject="Your receipt",
    html="<p>Thanks for your order.</p>",
    idempotency_key="order-4821-receipt",
)
print(email.idempotent_replayed)  # True if this key was already used

Reusing a key with a different payload raises ConflictError instead of silently sending the new content.

Errors

Every failure raises a subclass of MailkubeError (AuthenticationError, InvalidRequestError, RateLimitError — which carries .retry_afterServerError, MailkubeConnectionError, …). Each API error exposes .error_name, .message, and .status_code.

Threading

Echo a message's message_id in the In-Reply-To / References headers of a later send:

reply = client.emails.send(
    from_="Acme <hello@yourdomain.com>",
    to="customer@example.com",
    subject="Re: Your order",
    html="<p>An update.</p>",
    headers={"In-Reply-To": first.message_id, "References": first.message_id},
)

Verify webhooks

webhooks.verify is a pure, stdlib-only helper — call it in your request handler with the raw body:

from mailkube import verify, SignatureVerificationError, UnknownEvent

try:
    event = verify(raw_body, request.headers, signing_secret)
except SignatureVerificationError:
    ...  # reject with 400

if isinstance(event, UnknownEvent):
    ...  # a newer event type than this SDK version knows about — still usable
else:
    print(event.type)

An unrecognized event type is returned as UnknownEvent instead of raising, so a new server event type never forces an SDK upgrade on receivers.

Logging

Silent by default. Turn on request/response logging with:

import mailkube

mailkube.enable_logging(level="DEBUG")

or set the MAILKUBE_LOG environment variable. Authorization and Idempotency-Key headers are redacted from log output.

Client lifecycle

Create one client and reuse it. Mailkube is thread-safe; AsyncMailkube is bound to its event loop. Use the client as a (async) context manager, or call .close() / .aclose().

More examples

Runnable scripts in examples/:

Contributing

See CONTRIBUTING.md for the development setup and the quality gates every change must pass. Security issues: see SECURITY.md.

License

Apache-2.0 © 2026 Mailtactic, Corp.

Project details


Download files

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

Source Distribution

mailkube-1.1.0.tar.gz (70.7 kB view details)

Uploaded Source

Built Distribution

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

mailkube-1.1.0-py3-none-any.whl (26.4 kB view details)

Uploaded Python 3

File details

Details for the file mailkube-1.1.0.tar.gz.

File metadata

  • Download URL: mailkube-1.1.0.tar.gz
  • Upload date:
  • Size: 70.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mailkube-1.1.0.tar.gz
Algorithm Hash digest
SHA256 acbfec054962bdafb8e62da21e0ceaf3f0b62d3227da3c6d23e9a9376ad8e8f6
MD5 f98edb58b97cc971737d8b148f38dbba
BLAKE2b-256 4e32c08bc4988fc04501624dd9148bdba17f180e88a1460cb24029f8e2bdcbfd

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailkube-1.1.0.tar.gz:

Publisher: release.yml on mailkube/mailkube-python

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

File details

Details for the file mailkube-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: mailkube-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mailkube-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 72dc90a6612ee327cf23db71a77ab6d80be6b4a6682d89bd69aeb80d9b169eba
MD5 38bb7926e9bee343c112d8be2e02a630
BLAKE2b-256 4f375576a2f12d76c95fac1a687daecba50077408d0ec333278fd641e377360b

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailkube-1.1.0-py3-none-any.whl:

Publisher: release.yml on mailkube/mailkube-python

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

Supported by

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