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.1.tar.gz (71.1 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.1-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for mailkube-1.1.1.tar.gz
Algorithm Hash digest
SHA256 56074af462cb095781ced22ea77fa3c1e111fa9cce932036eaf499b23227b580
MD5 66955ae3286c9c3e6f164a68589f921b
BLAKE2b-256 a4c08e4c3cd0edab7297a1f80b0b70ad8aeb71b640ff2f278f244d01352498da

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailkube-1.1.1.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.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for mailkube-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 80b5caa1d7c2f2713895aaa192288a93de9210fe1373bee700471448009b0872
MD5 e2aa8af8f08a78f9bc77d15919c6143b
BLAKE2b-256 4ecebc75457cdb984d1eed5ced72546bcea59fb0adbe54009299775a0bc225ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for mailkube-1.1.1-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