Get your API key
All integrations Spring Boot

Spring Boot + MailKite

Spring's JavaMailSender is the framework's swappable mail seam — the same role Rails' ActionMailer delivery methods and Laravel's Mail::extend play. Point it at MailKite's SMTP relay with two properties, or install mailkite-spring-boot-starter for a native bean backed by the API (templates, batch sends, scheduling — things SMTP can't express). Either way, your @Service code that calls JavaMailSender doesn't change.

What you need

Quick start: SMTP relay

spring-boot-starter-mail already wraps javax.mail/jakarta.mail over SMTP — no new dependency, just point it at MailKite:

application.properties
# application.properties
spring.mail.host=smtp.mailkite.dev
spring.mail.port=587
spring.mail.username=mailkite
spring.mail.password=${MAILKITE_API_KEY}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

Autowire JavaMailSender like any other Spring bean:

OrderMailService.java
// OrderMailService.java
@Service
public class OrderMailService {

private final JavaMailSender mailSender;

public OrderMailService(JavaMailSender mailSender) {
this.mailSender = mailSender;
}

public void sendConfirmation(Order order) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("hello@yourdomain.com");
message.setTo(order.getEmail());
message.setSubject("Order #" + order.getId() + " confirmed");
message.setText("Thanks for your order!");
mailSender.send(message);
}
}

Recommended: mailkite-spring-boot-starter

For templates, batch sends, scheduled sends, and dashboard-visible delivery status, add the starter instead of (or alongside — it backs off if you already have a MailSender bean) spring-boot-starter-mail:

pom.xml
<!-- pom.xml -->
<dependency>
<groupId>dev.mailkite</groupId>
<artifactId>mailkite-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>
application.properties
# application.properties
mailkite.api-key=${MAILKITE_API_KEY}

That's it — auto-configuration registers a MailKiteMailSender bean implementing both MailSender and JavaMailSender the moment mailkite.api-key (or the env var MAILKITE_API_KEY) is set. OrderMailService above doesn't change — it still just calls JavaMailSender. HTML bodies and attachments work through Spring's own MimeMessageHelper:

OrderMailService.java
// Same JavaMailSender, now with an HTML body + attachment
MimeMessage mime = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mime, true);
helper.setFrom("hello@yourdomain.com");
helper.setTo("ada@example.com");
helper.setSubject("Your invoice");
helper.setText("<p>Thanks for your order!</p>", true);
helper.addAttachment("invoice.pdf", new ByteArrayResource(invoicePdfBytes));
mailSender.send(mime);

Test it

terminal
# Run the starter's demo app (starters/spring-boot in the MailKite monorepo)
mvn spring-boot:run

# Or exercise your own controller once MAILKITE_API_KEY is set
curl -X POST http://localhost:8080/send \
-d "to=you@yourdomain.com" -d "subject=Test" -d "body=Hello from Spring Boot"

A full runnable example (a form + controller wired to MailKiteMailSender) lives at starters/spring-boot in the MailKite SDK source — see the library guide.

Receive inbound email

MailKite can POST inbound email to a Spring MVC controller. Verify the signature with the Java SDK's static MailKite.verifyWebhook(...) — no client instance, no hand-rolled HMAC:

InboundEmailController.java
// InboundEmailController.java
@RestController
public class InboundEmailController {

@Value("${mailkite.webhook-secret}")
private String webhookSecret;

@PostMapping("/webhooks/mailkite")
public ResponseEntity<String> handle(
@RequestHeader("x-mailkite-signature") String signature,
@RequestBody String rawBody) {

boolean verified = MailKite.verifyWebhook(signature, rawBody, webhookSecret);
if (!verified) {
return ResponseEntity.status(401).build();
}

// Parse rawBody as JSON and process: create a ticket, log, trigger a job, ...
return ResponseEntity.ok()
.header("Content-Type", "application/json")
.body("{\"status\":\"ok\"}");
}
}

Troubleshooting

  • Connection refused (SMTP) — you're probably on port 25. Set spring.mail.port=587.
  • 535 Authentication failed (SMTP)spring.mail.password must be your mk_live_… API key, not a separate SMTP credential.
  • No qualifying bean of type 'JavaMailSender' — with the starter, this means mailkite.api-key/MAILKITE_API_KEY isn't set (auto-configuration only activates when it's present) and no other mail starter is on the classpath either.
  • Wrong From address — set it explicitly in code (Spring has no app-wide default); it must be on a verified domain.
  • Starter silently not sending through MailKite — the starter backs off if a MailSender bean already exists (e.g. spring-boot-starter-mail's SMTP one). Exclude MailSenderAutoConfiguration or remove the SMTP starter if you want MailKite's bean to win.

See the SMTP relay docs for the full connection reference, or Send API for using the MailKite Java SDK directly.