Repository navigation
feat: add per-email idempotency keys to batch send - #64
Merged
Merged
Conversation
EmailMessage.idempotencyKey(String) and EmailBuilder.idempotencyKey(String) set a per-email key that emails().sendBatch() sends as the item's idempotency_key. If an email with the same key and content was accepted in the last 24 hours, the API returns its original result and does not send it again. The SDK checks that keys are 1 to 255 characters and unique within a batch. emails().send() rejects a message with a per-email key; SendOptions.idempotencyKey(...) remains the Idempotency-Key header for single sends and whole batches. Co-Authored-By: Claude <noreply@anthropic.com>
bjarn
force-pushed
the
feat/batch-idempotency-keys
branch
from
October 18, 2026 16:08
6190796 to
cfe5b81
Compare
bjarn
added this pull request to stack #65
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.
Stacked on #63 — merge that first.
What changed
Non-breaking; suggested bump: minor (released together with #63 as 3.2.0).
EmailMessage.idempotencyKey(String)/idempotencyKey()andEmailBuilder.idempotencyKey(String). They set a per-email key thatemails().sendBatch()sends as the item'sidempotency_key. If an email with the same key and content was accepted in the last 24 hours, the API returns its original result and does not send it again.sendBatch()now buildsSendBatchMailItems. Its signature is unchanged (List<EmailMessage>, optionalSendOptions), and messages without a key produce exactly the same JSON as before.LettermintValidationException, before any request): a key must be 1-255 characters (checked in the setter), and keys must be unique within a batch (messages[i].idempotencyKey).emails().send()/EmailBuilder.send()reject a message that has a per-email key, so a per-email key is never sent in a single-send body and is not confused with theIdempotency-Keyheader.SendOptions.idempotencyKey(...)is unchanged and remains the header for single sends and whole batches. These checks only apply to the new field, so nothing that was accepted before is rejected now.sendBatchJavadoc and README explain that if a batch fails part-way,ApiException.getDetails()has anacceptedlist (index,message_id). The README batch section has a snippet, and the builder table lists the new method.Usage
Checks
./gradlew clean build(JDK 17, with the generator;checkGeneratedTypesup to date, 205 files): BUILD SUCCESSFUL../gradlew clean build(JDK 24, without the generator, as in CI): BUILD SUCCESSFUL, 90 tests passed. The new test covers the wire format of the per-email keys, the header option alongside them, null removing a key, length and uniqueness checks, the builder path, and rejection on singlesend().javap -public) againstmain: additions only (idempotencyKeyonEmailMessageandEmailBuilder), plus the generatedMessageDataconstructor change from feat: add messages resend #63.Not run locally
Suggested release tag
v3.2.0(together with #63)🤖 Generated with Claude Code