LettermintLettermint
  • Knowledge base
  • Community
  • Changelog
  • Support
  • Documentation
  • Sending API
  • Team API
Getting started
Guides
    Node.jsPHPPythonGoLaravelMagento 2WordPressNuxtJava
    SMTP
Platform
Resources
Guides

Java

The official Lettermint Java SDK sends email through a fluent builder API. You chain the parts of a message and call send(), and it drops into any JVM app: Spring Boot services, background workers, and batch jobs. Add it with a single Maven or Gradle dependency.

Every message is delivered through Lettermint's European infrastructure, which runs entirely inside the EU and processes mail in line with GDPR. That makes the SDK a solid choice for transactional email from a Java app, such as order confirmations, password resets, and account notifications.

Requirements

Before you start you need:

  • Java 8 or newer, with Maven or Gradle to manage the dependency
  • A Lettermint account with a verified sending domain
  • A Project API token from your project settings

If your domain is not verified yet, follow the domain setup guide first so your mail reaches the inbox instead of the spam folder.

1. Installation

Add the SDK to your project using Maven or Gradle:

2. Send your first email

Initialize the client with your Project API token:

Code
import co.lettermint.Lettermint; import co.lettermint.endpoints.EmailEndpoint; EmailEndpoint email = Lettermint.email(System.getenv("LETTERMINT_PROJECT_TOKEN"));

Send your first email:

Code
import co.lettermint.models.SendEmailResponse; SendEmailResponse response = email .from("John Doe <john@yourdomain.com>") .to("recipient@example.com") .subject("Hello from Lettermint!") .text("Hello! This is a test email.") .send(); System.out.println("Email sent with ID: " + response.getMessageId());

3. Email Features

Basic Email

Send a simple text or HTML email:

Code
email .from("John Doe <john@yourdomain.com>") .to("recipient@example.com") .subject("Your account is ready!") .html("<h1>Welcome!</h1><p>Thanks for signing up.</p>") .text("Welcome! Thanks for signing up.") .send();

Multiple Recipients

Send to multiple recipients using CC and BCC:

Code
email .from("John Doe <john@yourdomain.com>") .to("user1@example.com", "user2@example.com") .cc("manager@yourdomain.com") .bcc("archive@yourdomain.com") .subject("Monthly Newsletter") .html("<h1>This Month's Updates</h1>") .send();

Custom Headers and Reply-To

Add custom headers and set reply-to addresses:

Code
import java.util.HashMap; import java.util.Map; Map<String, String> headers = new HashMap<>(); headers.put("X-Priority", "1"); headers.put("X-Ticket-ID", "12345"); email .from("support@yourdomain.com") .to("customer@example.com") .replyTo("help@yourdomain.com") .subject("Support Ticket #12345") .headers(headers) .html("<p>Your support ticket has been updated.</p>") .send();

Metadata

Add metadata for tracking and webhook payloads:

Code
import java.util.HashMap; import java.util.Map; Map<String, Object> metadata = new HashMap<>(); metadata.put("order_id", "12345"); metadata.put("customer_id", "cust_789"); metadata.put("campaign", "order_confirmation"); email .from("notifications@yourdomain.com") .to("user@example.com") .subject("Order Confirmation") .metadata(metadata) .html("<p>Your order has been confirmed.</p>") .send();

Metadata is included in webhook payloads but not added to the actual email headers. Use it for tracking and analytics purposes.

Tags

Categorize emails for filtering and analytics:

Code
email .from("alerts@yourdomain.com") .to("admin@example.com") .subject("System Alert") .tag("system-alerts") .html("<p>Critical system alert detected.</p>") .send();

One tag per message. Tags can contain letters, numbers, hyphens, underscores, and spaces (max 255 characters). See Tags documentation for more details.

Route Selection

Direct emails to specific routes within your project:

Code
email .from("notifications@yourdomain.com") .to("user@example.com") .subject("Welcome!") .route("transactional") .html("<p>Welcome to our platform.</p>") .send();

Idempotency

Pass an idempotency key so a retry never sends the same email twice. If a request with the same key is repeated within the idempotency window, Lettermint returns the original result instead of sending again:

Code
email .from("notifications@yourdomain.com") .to("user@example.com") .subject("Order Confirmation") .idempotencyKey("order-confirmation-12345") .html("<p>Your order has been confirmed.</p>") .send();

Derive the key from something stable in your domain, such as an order or invoice ID, so the same business event always maps to the same key. See the idempotency documentation for the full behaviour.

File Attachments

Attach files to your emails:

Code
import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; // Read file content Path filePath = Paths.get("/path/to/document.pdf"); byte[] fileContent = Files.readAllBytes(filePath); String encodedContent = Base64.getEncoder().encodeToString(fileContent); email .from("invoices@yourdomain.com") .to("customer@example.com") .subject("Your Invoice") .html("<p>Please find your invoice attached.</p>") .attach("invoice.pdf", encodedContent) .send();

4. Send an order confirmation

A real transactional send usually pulls several of these features together. This example sends a receipt with an HTML and plain-text body, tags it for analytics, attaches the order and customer IDs as metadata, and uses an idempotency key so a retry never emails the customer twice:

Code
import co.lettermint.Lettermint; import co.lettermint.endpoints.EmailEndpoint; import co.lettermint.models.SendEmailResponse; import java.util.HashMap; import java.util.Map; public class OrderConfirmation { private final EmailEndpoint email = Lettermint.email(System.getenv("LETTERMINT_PROJECT_TOKEN")); public SendEmailResponse send(Order order) { Map<String, Object> metadata = new HashMap<>(); metadata.put("order_id", order.getId()); metadata.put("customer_id", order.getCustomerId()); return email .from("Acme Store <orders@yourdomain.com>") .to(order.getCustomerEmail()) .replyTo("support@yourdomain.com") .subject("Order " + order.getNumber() + " confirmed") .html("<h1>Thanks for your order</h1><p>Order " + order.getNumber() + " totalling " + order.getTotal() + " is confirmed.</p>") .text("Thanks for your order. Order " + order.getNumber() + " totalling " + order.getTotal() + " is confirmed.") .tag("order-confirmation") .metadata(metadata) .idempotencyKey("order-confirmation-" + order.getId()) .route("transactional") .send(); } }

The metadata you attach here travels with every webhook event for the message, so a later delivery or bounce maps straight back to the order in your database.

5. Response

Code
SendEmailResponse response = email .from("John Doe <john@yourdomain.com>") .to("recipient@example.com") .subject("Test") .text("Hello!") .send(); System.out.println(response.getMessageId()); // Email ID System.out.println(response.getStatus()); // Current status

Track delivery, opens, and bounces

Sending is only half of a transactional setup. To see what happens after a message leaves your app, combine the SDK with Lettermint's platform features:

  • Email tracking records opens and clicks, with bot filtering so your metrics stay accurate.
  • Webhooks push delivery, bounce, and complaint events to your server in real time, so you can update order records or suppress bad addresses.
  • Test addresses let you trigger a hard or soft bounce on demand while you build and verify your webhook handler.

Tracking is configured per route, so turn it on for the route your app sends through, then read the results from your dashboard or your webhook endpoint.

FAQ

Which Java versions are supported?

Java 8 or newer. Add the SDK with a single Maven or Gradle dependency, and it works in any JVM app, including Spring Boot services and batch jobs.

How do I stop the same email being sent twice?

Add an idempotency key with .idempotencyKey(), derived from a stable ID such as an order number. A repeated request with the same key returns the original result instead of sending again. See the idempotency documentation.

How do I handle send errors?

Wrap send() in a try/catch. The SDK throws ValidationException for 422 errors such as invalid parameters or an exceeded limit, HttpRequestException for other HTTP errors, and LettermintException for general failures including timeouts.

Is Lettermint email GDPR compliant and EU-hosted?

Yes. Lettermint runs exclusively on European infrastructure and processes email in line with GDPR, so transactional mail from your Java app is handled inside the EU.

How do I track opens, clicks, and bounces?

Enable tracking on your route and subscribe to webhooks to receive delivery, open, and bounce events. Use the test addresses to simulate bounces while you build your handler.

Next Steps

Tags

Organize and filter emails with tags.

Tracking

Track opens, clicks, and deliverability.

Webhooks

Receive real-time delivery notifications.

SMTP Alternative

Send via SMTP instead of the API.

GitHub Repository

Find the complete source code, report issues, or contribute on GitHub.

Last modified on August 7, 2026
NuxtIntroduction
On this page
  • Requirements
  • 1. Installation
  • 2. Send your first email
  • 3. Email Features
    • Basic Email
    • Multiple Recipients
    • Custom Headers and Reply-To
    • Metadata
    • Tags
    • Route Selection
    • Idempotency
    • File Attachments
  • 4. Send an order confirmation
  • 5. Response
  • Track delivery, opens, and bounces
  • FAQ
  • Next Steps
<dependency> <groupId>co.lettermint</groupId> <artifactId>lettermint</artifactId> <version>2.0.0</version> </dependency>
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java
Java