Repository navigation
feat: add messages resend - #36
Merged
Merged
Conversation
- New operation: POST /messages/{messageId}/resend (team token) with an
optional ResendMessageRequest body (recipients) and an optional
Idempotency-Key header. Returns 202 with a PendingSendMailResponse.
- MessageData gains resent_from_message_id.
- POST /send/batch items are now SendBatchMailItem: every SendMailRequest
field plus an optional per-email idempotency_key.
- POST /send/batch documents an ApiErrorBody for 409.
- Description updates.
Co-Authored-By: Claude <noreply@anthropic.com>
- messages.resend(message_id, body=None, *, idempotency_key=None,
timeout=None) sends the stored content of a sent message again as a
new message and returns the pending send response. Without a body it
resends to every original recipient; {"recipients": [...]} chooses
some of them. No body is sent when none is given.
- Like reschedule and cancel, it uses the team token when it is set and
otherwise the sending token.
- Document it in the README and test the request, both tokens, the
Idempotency-Key header and the 410 and 429 errors.
Co-Authored-By: Claude <noreply@anthropic.com>
The field stays nullable and is now optional, so code that constructs MessageData keeps type-checking. Co-Authored-By: Claude <noreply@anthropic.com>
bjarn
added this pull request to stack #38
October 18, 2026 17:20
bjornftw
approved these changes
Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Non-breaking. Suggested bump: minor (3.1.0 → 3.2.0).
lettermint.typesand the operation table from the latest API spec.messages.resend(message_id, body=None, *, idempotency_key=None, timeout=None)onLettermintandAsyncLettermint. It returns aPendingSendMailResponsefor the new message.{"recipients": [...]}sends it to only some of them. If you pass no body, the request has no body.idempotency_key=sets theIdempotency-Keyheader, likemessages.process()andemails.send().messages.reschedule()andmessages.cancel(), it uses the team token when one is set. Otherwise it uses the sending token.410(the content is no longer retained) raises a plainAPIError.RESEND_LIMIT_REACHED(429) raisesRateLimitError.messagestable, the token note and a short example.API changes in the regenerated types
POST /messages/{messageId}/resend→messages.resend. BodyResendMessageRequest { recipients?: list[str] }(optional), optionalIdempotency-Keyheader,202→PendingSendMailResponse. Errors: 401, 403, 404, 409, 410, 422, 429, 500operations.py,types.ResendMessageRequestMessageData.resent_from_message_id: optional and nullable (NotRequired[str | None]). It holds the ID of the message this one resent and is absent orNonewhen the message is not a resend. Code that buildsMessageDatadicts keeps type-checkingtypes.MessageDataPOST /send/batchitems are nowSendBatchMailItem, which has everySendMailRequestfield plus an optional per-emailidempotency_key(1-255 characters).SendBatchMailRequest = list[SendBatchMailItem]types.SendBatchMailItemPOST /send/batch409can now also be anApiErrorBody(IDEMPOTENCY_CONFLICT)operations.py413on the send endpoints,409semantics)SendMailRequestandEmailMessageare unchanged.Usage
Checks
python -m ruff check src tests scripts: all checks passedpython -m ruff format --check src tests scripts: 26 files already formattedpython -m mypy: no issues in 33 source filespython scripts/unasync.py --check:src/lettermint/_syncis up to datepython scripts/generate.py --checkwith the generator: no differences, headers ok. Without the generator (as in CI): headers okpython -m pytest tests/: 246 passed on Python 3.10, 3.11, 3.12, 3.13 and 3.14python -m buildandtwine check --strict dist/*: passed. The wheel smoke test (UPGRADE.md and py.typed are in the wheel, and the client imports): passedmain: every generated TypedDict has the same required keys as before (resent_from_message_idis a new optional key), and no exports were removed. Amypy --strictfile with the existingsend_batchcall shapes passesNot run locally
Suggested release tag
v3.2.0(together with the batch per-email idempotency keys PR)🤖 Generated with Claude Code