Version Planning
See the Roadmap for upcoming releases and feature timeline (v0.3.0 → v0.4.0 → v1.0.0).
Changelog¶
[Unreleased]¶
[0.4.0b1] - 2026-09-03¶
Added¶
route=andtag=onsend_bulk(), and aLETTERMINT_BULK_ROUTEsetting: the route and tag a whole bulk send goes out on. A message with its ownX-Lettermint-RouteorX-Lettermint-Tagheader keeps it, as does a prepared payload that already names oneBulkItem.to: the addresses a message was for, withoutccandbcc- A bulk send whose messages carry no route logs a warning once, naming
LETTERMINT_BULK_ROUTE
Changed¶
- Batch responses are paired with their message on the recipient address where Lettermint names one, and on request order where it does not. An answer that cannot be placed fails its message instead of confirming it under another message's
message_id
[0.4.0a1] - 2026-09-02¶
Added¶
- Bulk sending through Lettermint's batch endpoint:
lettermint_django.bulk.send_bulk()for any iterable ofEmailMessageobjects or prepared payload dicts, andsend_bulk_mail()for one templated, personalised message per recipient, both returning per-message results (BulkResult,BulkItem) with Lettermint's reason for every failure; nothing is retried render_bulk_mail(): lazy per-recipient rendering from template strings or files, with shared and per-recipient context and per-recipient languageLmEmailMessage.bulk_id(migration0003): every message accepted in asend_bulkcall carries the call's id (result.bulk_id, or your own viabulk_id=); query withLmEmailMessage.objects.from_bulk()andLmEmailEvent.objects.from_bulk()- Queryset helpers
LmEmailMessage.objects.not_delivered()and.not_opened()for following up on a send - Statuses
scheduledandcanceled(migration0004), set by themessage.scheduled,message.rescheduled,message.releasedandmessage.canceledwebhook events and by scheduled sends X-Lettermint-Tagheader support; the tag is stored onLmEmailMessage.tag(migration0002), queryable withLmEmailMessage.objects.tagged()and filterable in the admin- Backend primitives
build_payload(),send_single()andsend_payloads() LETTERMINT_BATCH_SIZEsettingLETTERMINT_WEBHOOK_PATHsetting: the whole path of the webhook endpoint (defaultlettermint/message-events/), plus system checklettermint_django.W002(webhook served withoutLETTERMINT_WEBHOOK_SECRET)- Bulk sending guide in the documentation
Changed¶
LettermintEmailBackend._send()is nowsend_single()and returns the Lettermint response;_sendremains as an alias- A message counts as sent whenever Lettermint returned a response, even one without a
message_id lettermint_django.urlsmust now be included at the root (path("", include("lettermint_django.urls"))); the path comes fromLETTERMINT_WEBHOOK_PATH. Projects that included it underlettermint/keep the same URL by switching to the root includemessage.inboundwebhook events are acknowledged but no longer stored; inbound mail is not supported and the payload carries the complete message- Webhook values longer than their column (
event,recipient) are truncated instead of failing the delivery
[0.3.0-alpha] - 2026-09-01¶
Added¶
- Optional email tracking: add
lettermint_djangotoINSTALLED_APPSto store sent messages (LmEmailMessage) and webhook events (LmEmailEvent) - Backend stores the Lettermint
message_idand initial status of every sent email when tracking is installed; tracking failures are logged and never block sending - Webhook endpoint (
lettermint_django.urls, URL namelm-message-events) with signature verification through the Lettermint SDK, idempotent event storage and status updates formessage.*events - Django signals
lm_email_event,lm_email_delivered,lm_email_bouncedandlm_email_failed - Query helpers:
LmEmailMessage.objects.get_status(),.delivered(),.bounced(),.failed();LmEmailEvent.objects.for_recipient(),.bounces() - Read-only Django admin for tracked messages and events
LETTERMINT_WEBHOOK_SECRETsetting- Tracking guide in the documentation
Changed¶
- Package layout: models, views, signals, admin and tracking helpers are packages with one module per item; public import paths (
lettermint_django.models,lettermint_django.signals,lettermint_django.urls) are unchanged - Test suite installs the tracking app and covers models, backend capture and the webhook endpoint
[0.2.1-alpha] - 2026-06-03¶
Changed¶
- Refactored
LettermintEmailBackend: extracted string coercion logic to_coerce_str()method and simplified connection checks - Removed unused
content_idparameter from internal attachment handling - Added type hints to client kwargs dict
Tested¶
- Successfully sent first emails through Lettermint on testing environment
[0.2.0] - 2026-06-03¶
Added¶
- Documentation with getting started guides (installation, configuration, usage)
- MkDocs site generation and GitHub Actions deployment workflow
[0.1.0] - 2026-05-30¶
Added¶
LettermintEmailBackend- DjangoBaseEmailBackendimplementation using the Lettermint Python SDK- Support for
to,cc,bcc,reply_to, plain text, HTML, attachments, and custom headers LETTERMINT_API_KEY,LETTERMINT_BASE_URL,LETTERMINT_ROUTE,LETTERMINT_TIMEOUTsettings- Per-message route override via
X-Lettermint-Routeextra header - Full test suite with pytest
- GitHub Actions for CI and PyPI publishing