# Mailtrap Java SDK The Mailtrap Java SDK is the official Java client library for integrating with the Mailtrap email platform API. Mailtrap provides a comprehensive email testing and sending infrastructure designed for developers who need to safely test, send, and manage transactional emails in their applications. The SDK abstracts the complexity of HTTP requests and provides a type-safe, fluent API for all Mailtrap services including production email sending, sandbox testing, bulk operations, and contact management. This SDK requires JDK 11 or higher and is built using modern Java features including the builder pattern, validation annotations, and fluent interfaces. It provides four main API categories: Sending API for production emails, Testing API for sandbox development, Bulk Sending API for high-volume campaigns, and General API for account management. The library handles authentication, request validation, error handling, and serialization automatically, allowing developers to focus on building email functionality rather than managing API integration details. ## Installation and Configuration Add the Maven dependency to your project ```xml io.mailtrap mailtrap-java 1.1.0 ``` ```groovy // Gradle Groovy implementation 'io.mailtrap:mailtrap-java:1.1.0' // Gradle Kotlin DSL implementation("io.mailtrap:mailtrap-java:1.1.0") ``` ## Client Initialization Create a Mailtrap client with API token authentication ```java import io.mailtrap.client.MailtrapClient; import io.mailtrap.config.MailtrapConfig; import io.mailtrap.factory.MailtrapClientFactory; // Basic configuration for production sending MailtrapConfig config = new MailtrapConfig.Builder() .token("your_api_token_here") .build(); MailtrapClient client = MailtrapClientFactory.createMailtrapClient(config); // Configuration for testing/sandbox mode MailtrapConfig sandboxConfig = new MailtrapConfig.Builder() .token("your_api_token_here") .sandbox(true) .inboxId(1337L) .build(); MailtrapClient sandboxClient = MailtrapClientFactory.createMailtrapClient(sandboxConfig); // Switch between APIs dynamically client.switchToEmailSendingApi(); client.switchToEmailTestingApi(1337L); client.switchToBulkSendingApi(); ``` ## Send Basic Email Send a simple text email using the Sending API ```java import io.mailtrap.model.request.emails.Address; import io.mailtrap.model.request.emails.MailtrapMail; import io.mailtrap.model.response.emails.SendResponse; import java.util.List; MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com")) .to(List.of(new Address("recipient@example.com"))) .subject("Hello from Mailtrap!") .text("Welcome to Mailtrap Sending!") .build(); try { SendResponse response = client.sendingApi().emails().send(mail); System.out.println("Email sent successfully!"); System.out.println("Message IDs: " + response.getMessageIds()); } catch (Exception e) { System.err.println("Failed to send email: " + e.getMessage()); } ``` ## Send HTML Email with Recipient Names Send HTML email with formatted addresses including recipient names ```java import io.mailtrap.model.request.emails.Address; import io.mailtrap.model.request.emails.MailtrapMail; import java.util.List; MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com", "John Smith")) .to(List.of( new Address("user1@example.com", "Alice Johnson"), new Address("user2@example.com", "Bob Williams") )) .cc(List.of(new Address("manager@example.com", "Manager"))) .bcc(List.of(new Address("archive@example.com"))) .replyTo(new Address("support@yourdomain.com", "Support Team")) .subject("Welcome to Our Service") .html("""

Welcome!

Thank you for joining our service.

Get Started """) .text("Welcome! Thank you for joining our service. Visit: https://example.com") .build(); SendResponse response = client.sendingApi().emails().send(mail); ``` ## Send Email with Attachments Send email with file attachments including inline images ```java import io.mailtrap.model.request.emails.EmailAttachment; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.List; // Read and encode file byte[] pdfBytes = Files.readAllBytes(Paths.get("document.pdf")); String pdfBase64 = Base64.getEncoder().encodeToString(pdfBytes); byte[] imageBytes = Files.readAllBytes(Paths.get("logo.png")); String imageBase64 = Base64.getEncoder().encodeToString(imageBytes); MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com")) .to(List.of(new Address("recipient@example.com"))) .subject("Invoice with Attachments") .html("""

Your Invoice

Company Logo

Please find your invoice attached.

""") .attachments(List.of( EmailAttachment.builder() .filename("invoice.pdf") .content(pdfBase64) .type("application/pdf") .disposition("attachment") .build(), EmailAttachment.builder() .filename("logo.png") .content(imageBase64) .type("image/png") .disposition("inline") .contentId("logo.png") .build() )) .build(); SendResponse response = client.sendingApi().emails().send(mail); ``` ## Send Email with Custom Variables and Categories Send email with metadata for tracking and categorization ```java import java.util.Map; MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com")) .to(List.of(new Address("recipient@example.com"))) .subject("Order Confirmation") .text("Your order #12345 has been confirmed.") .category("transactional") .customVariables(Map.of( "order_id", "12345", "customer_id", "67890", "total_amount", "99.99", "currency", "USD" )) .headers(Map.of( "X-Priority", "1", "X-Custom-Header", "CustomValue" )) .build(); SendResponse response = client.sendingApi().emails().send(mail); ``` ## Send Email Using Template Send email with a pre-defined template and dynamic variables ```java import java.util.Map; MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com", "Company Name")) .to(List.of(new Address("recipient@example.com", "John Doe"))) .templateUuid("813e39db-c74a-4830-b037-0e6ba8b1fe88") .templateVariables(Map.of( "user_name", "John Doe", "confirmation_link", "https://example.com/confirm/abc123", "expiry_date", "2024-12-31", "support_email", "support@example.com" )) .build(); SendResponse response = client.sendingApi().emails().send(mail); ``` ## Send Bulk Email Send high-volume emails using the Bulk Sending API ```java MailtrapConfig bulkConfig = new MailtrapConfig.Builder() .token("your_api_token_here") .bulk(true) .build(); MailtrapClient bulkClient = MailtrapClientFactory.createMailtrapClient(bulkConfig); MailtrapMail mail = MailtrapMail.builder() .from(new Address("newsletter@yourdomain.com")) .to(List.of(new Address("subscriber@example.com"))) .subject("Monthly Newsletter") .html("

This Month's Updates

Check out what's new...

") .build(); SendResponse response = bulkClient.bulkSendingApi().emails().send(mail); ``` ## Send Batch Emails Send multiple emails in a single request with shared base properties ```java import io.mailtrap.model.request.emails.MailtrapBatchMail; import io.mailtrap.model.request.emails.BatchEmailBase; import io.mailtrap.model.response.emails.BatchSendResponse; import java.util.List; // Define common properties BatchEmailBase base = BatchEmailBase.builder() .from(new Address("sender@yourdomain.com")) .subject("Personalized Newsletter") .html("

Hello {{name}}

Your personalized content...

") .category("newsletter") .build(); // Individual email requests List requests = List.of( MailtrapMail.builder() .to(List.of(new Address("user1@example.com"))) .templateVariables(Map.of("name", "Alice")) .build(), MailtrapMail.builder() .to(List.of(new Address("user2@example.com"))) .templateVariables(Map.of("name", "Bob")) .build(), MailtrapMail.builder() .to(List.of(new Address("user3@example.com"))) .subject("Special Subject Override") // Override base subject .templateVariables(Map.of("name", "Charlie")) .build() ); MailtrapBatchMail batchMail = MailtrapBatchMail.builder() .base(base) .requests(requests) .build(); BatchSendResponse response = client.bulkSendingApi().emails().batchSend(batchMail); System.out.println("Batch sent: " + response.isSuccess()); System.out.println("Errors: " + response.getErrors()); ``` ## Send Test Email to Sandbox Send email to testing inbox for development and debugging ```java MailtrapConfig testConfig = new MailtrapConfig.Builder() .token("your_api_token_here") .sandbox(true) .inboxId(1000001L) .build(); MailtrapClient testClient = MailtrapClientFactory.createMailtrapClient(testConfig); MailtrapMail mail = MailtrapMail.builder() .from(new Address("dev@yourdomain.com")) .to(List.of(new Address("test@example.com"))) .subject("Test Email") .text("This is a test email sent to sandbox.") .build(); // Send using testing API SendResponse response = testClient.testingApi().emails().send(mail, 1000001L); // Alternative: Switch existing client to testing mode client.switchToEmailTestingApi(1000001L); SendResponse response2 = client.send(mail); ``` ## Manage Testing Inboxes Create, update, and manage testing inboxes ```java import io.mailtrap.model.request.inboxes.CreateInboxRequest; import io.mailtrap.model.request.inboxes.UpdateInboxRequest; import io.mailtrap.model.response.inboxes.Inbox; import java.util.List; long accountId = 123456L; long projectId = 789L; // Create new inbox CreateInboxRequest createRequest = new CreateInboxRequest( new CreateInboxRequest.InboxCreateData("My Test Inbox") ); Inbox newInbox = client.testingApi().inboxes() .createInbox(accountId, projectId, createRequest); System.out.println("Created inbox ID: " + newInbox.getId()); // Get all inboxes List inboxes = client.testingApi().inboxes().getInboxes(accountId); inboxes.forEach(inbox -> System.out.println("Inbox: " + inbox.getName() + " (ID: " + inbox.getId() + ")") ); // Update inbox UpdateInboxRequest updateRequest = new UpdateInboxRequest( new UpdateInboxRequest.InboxUpdateData("Updated Inbox Name", "mock") ); Inbox updated = client.testingApi().inboxes() .updateInbox(accountId, newInbox.getId(), updateRequest); // Mark all messages as read client.testingApi().inboxes().markAsRead(accountId, newInbox.getId()); // Clean inbox (delete all messages) client.testingApi().inboxes().cleanInbox(accountId, newInbox.getId()); // Reset credentials client.testingApi().inboxes().resetCredentials(accountId, newInbox.getId()); // Delete inbox client.testingApi().inboxes().deleteInbox(accountId, newInbox.getId()); ``` ## Retrieve and Analyze Test Messages Get messages from testing inbox and analyze content ```java import io.mailtrap.model.request.accountaccesses.ListMessagesQueryParams; import io.mailtrap.model.response.messages.Message; import io.mailtrap.model.response.messages.SpamScore; import java.util.List; long accountId = 123456L; long inboxId = 1000001L; // Get messages with filtering ListMessagesQueryParams params = ListMessagesQueryParams.builder() .page(1) .search("invoice") .build(); List messages = client.testingApi().messages() .getMessages(accountId, inboxId, params); for (Message message : messages) { System.out.println("Subject: " + message.getSubject()); System.out.println("From: " + message.getFromEmail()); System.out.println("Sent at: " + message.getSentAt()); long messageId = message.getId(); // Get full message details Message fullMessage = client.testingApi().messages() .getMessage(accountId, inboxId, messageId); // Get HTML content String htmlContent = client.testingApi().messages() .getHtmlMessage(accountId, inboxId, messageId); // Get plain text content String textContent = client.testingApi().messages() .getTextMessage(accountId, inboxId, messageId); // Get raw message String rawMessage = client.testingApi().messages() .getRawMessage(accountId, inboxId, messageId); // Analyze spam score SpamScore spamScore = client.testingApi().messages() .getSpamScore(accountId, inboxId, messageId); System.out.println("Spam score: " + spamScore.getScore()); // Get HTML analysis var htmlAnalysis = client.testingApi().messages() .getMessageHtmlAnalysis(accountId, inboxId, messageId); System.out.println("HTML errors: " + htmlAnalysis); } ``` ## Forward and Update Test Messages Forward messages to external addresses and update message status ```java import io.mailtrap.model.request.messages.ForwardMessageRequest; import io.mailtrap.model.request.messages.UpdateMessageRequest; long accountId = 123456L; long inboxId = 1000001L; long messageId = 999L; // Forward message to external email ForwardMessageRequest forwardRequest = new ForwardMessageRequest( "external-recipient@example.com" ); client.testingApi().messages() .forwardMessage(accountId, inboxId, messageId, forwardRequest); // Mark message as read UpdateMessageRequest updateRequest = new UpdateMessageRequest( new UpdateMessageRequest.MessageUpdateData("true") ); client.testingApi().messages() .updateMessage(accountId, inboxId, messageId, updateRequest); // Delete message client.testingApi().messages() .deleteMessage(accountId, inboxId, messageId); ``` ## Manage Contacts Create, update, and delete contacts with custom fields ```java import io.mailtrap.model.request.contacts.CreateContact; import io.mailtrap.model.request.contacts.CreateContactRequest; import io.mailtrap.model.request.contacts.UpdateContact; import io.mailtrap.model.request.contacts.UpdateContactRequest; import io.mailtrap.model.response.contacts.ContactResponse; import java.util.List; import java.util.Map; import java.util.Collections; long accountId = 123456L; long listId1 = 10L; long listId2 = 20L; // Create contact CreateContact contact = new CreateContact( "customer@example.com", Map.of( "first_name", "John", "last_name", "Doe", "company", "Acme Corp", "phone", "+1-555-0123" ), List.of(listId1, listId2) ); CreateContactRequest createRequest = new CreateContactRequest(contact); ContactResponse created = client.contactsApi().contacts() .createContact(accountId, createRequest); System.out.println("Contact created with ID: " + created.getData().getId()); // Update contact UpdateContact updateContact = new UpdateContact( "customer@example.com", Map.of( "first_name", "Jane", "last_name", "Smith" ), List.of(listId1), // New lists to add List.of(listId2), // Lists to remove false // Unsubscribed status ); UpdateContactRequest updateRequest = new UpdateContactRequest(updateContact); ContactResponse updated = client.contactsApi().contacts() .updateContact(accountId, "customer@example.com", updateRequest); // Delete contact (by email or ID) client.contactsApi().contacts() .deleteContact(accountId, "customer@example.com"); ``` ## Manage Contact Lists Create and retrieve contact lists for segmentation ```java import io.mailtrap.model.response.contactlists.ContactList; import java.util.List; long accountId = 123456L; // Get all contact lists List contactLists = client.contactsApi().contactLists() .findAll(accountId); for (ContactList list : contactLists) { System.out.println("List: " + list.getName()); System.out.println(" ID: " + list.getId()); System.out.println(" Contacts: " + list.getContactsCount()); System.out.println(" Active: " + list.isActive()); } ``` ## Manage Custom Contact Fields Create and manage custom fields for contact metadata ```java import io.mailtrap.model.request.contactfields.CreateContactField; import io.mailtrap.model.request.contactfields.CreateContactFieldRequest; import io.mailtrap.model.request.contactfields.UpdateContactField; import io.mailtrap.model.request.contactfields.UpdateContactFieldRequest; import io.mailtrap.model.response.contactfields.ContactField; import java.util.List; long accountId = 123456L; // Get all contact fields List fields = client.contactsApi().contactFields() .getAllContactFields(accountId); // Create custom field (maximum 40 fields per account) CreateContactField newField = new CreateContactField( "purchase_history", "text" // Options: text, number, date, boolean ); CreateContactFieldRequest createRequest = new CreateContactFieldRequest(newField); ContactField created = client.contactsApi().contactFields() .createContactField(accountId, createRequest); // Get specific field ContactField field = client.contactsApi().contactFields() .getContactField(accountId, created.getId()); // Update field UpdateContactField updateField = new UpdateContactField("lifetime_value"); UpdateContactFieldRequest updateRequest = new UpdateContactFieldRequest(updateField); client.contactsApi().contactFields() .updateContactField(accountId, created.getId(), updateRequest); // Delete field client.contactsApi().contactFields() .deleteContactField(accountId, created.getId()); ``` ## Bulk Import Contacts Import up to 50,000 contacts in a single operation ```java import io.mailtrap.model.request.contactimports.ContactImport; import io.mailtrap.model.request.contactimports.ImportContactsRequest; import io.mailtrap.model.response.contactimports.ContactImportResponse; import java.util.List; import java.util.Map; long accountId = 123456L; long listId = 10L; // Prepare contacts for import List contacts = List.of( new ContactImport( "user1@example.com", Map.of("first_name", "Alice", "company", "Tech Corp") ), new ContactImport( "user2@example.com", Map.of("first_name", "Bob", "company", "Design Inc") ), new ContactImport( "user3@example.com", Map.of("first_name", "Charlie", "company", "Media Ltd") ) ); ImportContactsRequest importRequest = new ImportContactsRequest( contacts, List.of(listId) ); // Start import ContactImportResponse importResponse = client.contactsApi().contactImports() .importContacts(accountId, importRequest); long importId = importResponse.getImportId(); System.out.println("Import started with ID: " + importId); // Check import status ContactImportResponse status = client.contactsApi().contactImports() .getContactImport(accountId, importId); System.out.println("Import status: " + status.getStatus()); System.out.println("Processed: " + status.getProcessedCount() + " / " + status.getTotalCount()); ``` ## Export Contacts Create and retrieve contact exports ```java import io.mailtrap.model.request.contactexports.CreateContactsExportRequest; import io.mailtrap.model.response.contactexports.ContactExportResponse; import java.util.List; long accountId = 123456L; // Create export for specific lists CreateContactsExportRequest exportRequest = new CreateContactsExportRequest( List.of(10L, 20L) // List IDs to export ); ContactExportResponse exportResponse = client.contactsApi().contactExports() .createContactExport(accountId, exportRequest); long exportId = exportResponse.getExportId(); System.out.println("Export started with ID: " + exportId); // Check export status ContactExportResponse status = client.contactsApi().contactExports() .getContactExport(accountId, exportId); System.out.println("Export status: " + status.getStatus()); if (status.isCompleted()) { System.out.println("Download URL: " + status.getDownloadUrl()); } ``` ## Manage Email Templates Create, update, and use email templates ```java import io.mailtrap.model.request.emailtemplates.CreateEmailTemplate; import io.mailtrap.model.request.emailtemplates.CreateEmailTemplateRequest; import io.mailtrap.model.request.emailtemplates.UpdateEmailTemplate; import io.mailtrap.model.request.emailtemplates.UpdateEmailTemplateRequest; import io.mailtrap.model.response.emailtemplates.EmailTemplate; import java.util.List; long accountId = 123456L; // Get all templates List templates = client.emailTemplatesApi() .getAllTemplates(accountId); // Create template CreateEmailTemplate newTemplate = new CreateEmailTemplate( "Welcome Email", "

Welcome {{name}}!

Thanks for joining {{company}}.

", "Welcome {{name}}! Thanks for joining {{company}}." ); CreateEmailTemplateRequest createRequest = new CreateEmailTemplateRequest(newTemplate); EmailTemplate created = client.emailTemplatesApi() .createEmailTemplate(accountId, createRequest); // Get template EmailTemplate template = client.emailTemplatesApi() .getEmailTemplate(accountId, created.getId()); // Update template UpdateEmailTemplate updateTemplate = new UpdateEmailTemplate( "Updated Welcome Email", "

Welcome {{name}}!

We're excited to have you.

", "Welcome {{name}}! We're excited to have you." ); UpdateEmailTemplateRequest updateRequest = new UpdateEmailTemplateRequest(updateTemplate); client.emailTemplatesApi() .updateEmailTemplate(accountId, created.getId(), updateRequest); // Delete template client.emailTemplatesApi() .deleteEmailTemplate(accountId, created.getId()); ``` ## Manage Sending Domains Configure and verify custom sending domains ```java import io.mailtrap.model.request.sendingdomains.CreateSendingDomain; import io.mailtrap.model.request.sendingdomains.CreateSendingDomainRequest; import io.mailtrap.model.request.sendingdomains.SendingDomainsSetupInstructionsRequest; import io.mailtrap.model.response.sendingdomains.SendingDomain; import java.util.List; long accountId = 123456L; // Create sending domain CreateSendingDomain domain = new CreateSendingDomain("mail.yourdomain.com"); CreateSendingDomainRequest createRequest = new CreateSendingDomainRequest(domain); SendingDomain created = client.sendingApi().sendingDomains() .create(accountId, createRequest); System.out.println("Domain ID: " + created.getId()); System.out.println("Verification status: " + created.getStatus()); // Get all sending domains List domains = client.sendingApi().sendingDomains() .getSendingDomains(accountId); // Get specific domain SendingDomain domainDetails = client.sendingApi().sendingDomains() .getSendingDomain(accountId, created.getId()); // Send setup instructions via email SendingDomainsSetupInstructionsRequest instructionsRequest = new SendingDomainsSetupInstructionsRequest("admin@yourdomain.com"); client.sendingApi().sendingDomains() .sendSendingDomainsSetupInstructions( accountId, created.getId(), instructionsRequest ); // Delete domain client.sendingApi().sendingDomains() .deleteSendingDomain(accountId, created.getId()); ``` ## Manage Suppressions Search and manage email suppressions ```java import io.mailtrap.model.response.suppressions.Suppression; import java.util.List; long accountId = 123456L; // Search for suppressions by email List suppressions = client.sendingApi().suppressions() .search(accountId, "blocked@example.com"); for (Suppression suppression : suppressions) { System.out.println("Email: " + suppression.getEmail()); System.out.println("Reason: " + suppression.getReason()); System.out.println("Created: " + suppression.getCreatedAt()); // Delete suppression to allow sending again client.sendingApi().suppressions() .deleteSuppression(accountId, suppression.getId()); } ``` ## Get Account Information Retrieve account details and permissions ```java import io.mailtrap.model.response.accounts.Account; import java.util.List; // Get all accounts accessible with API token List accounts = client.generalApi().accounts().getAllAccounts(); for (Account account : accounts) { System.out.println("Account: " + account.getName()); System.out.println(" ID: " + account.getId()); System.out.println(" Email: " + account.getEmail()); System.out.println(" Plan: " + account.getPlan()); System.out.println(" Status: " + account.getStatus()); } ``` ## Manage Account Access and Permissions List and manage user access to accounts ```java import io.mailtrap.model.request.accountaccesses.ListAccountAccessQueryParams; import io.mailtrap.model.request.permissions.ManagePermission; import io.mailtrap.model.request.permissions.ManagePermissionsRequest; import io.mailtrap.model.response.accountaccesses.AccountAccess; import io.mailtrap.model.response.permissions.Resource; import java.util.List; long accountId = 123456L; // List account accesses ListAccountAccessQueryParams params = ListAccountAccessQueryParams.builder() .page(1) .perPage(50) .build(); List accesses = client.generalApi().accountAccesses() .listUserAndInviteAccountAccesses(accountId, params); for (AccountAccess access : accesses) { System.out.println("User: " + access.getUserEmail()); System.out.println("Role: " + access.getRole()); System.out.println("Status: " + access.getStatus()); } // Get available resources for permissions List resources = client.generalApi().permissions() .getResources(accountId); // Manage permissions for a user long accountAccessId = 789L; List permissions = List.of( new ManagePermission( "inbox", 1001L, true // Admin access ), new ManagePermission( "project", 2001L, false // Read-only access ) ); ManagePermissionsRequest permissionsRequest = new ManagePermissionsRequest(permissions); client.generalApi().permissions() .managePermissions(accountAccessId, accountId, permissionsRequest); // Remove account access long accessToRemove = 789L; client.generalApi().accountAccesses() .removeAccountAccess(accessToRemove, accountId); ``` ## Get Billing Information Retrieve current billing cycle usage ```java import io.mailtrap.model.response.billing.BillingUsage; long accountId = 123456L; BillingUsage usage = client.generalApi().billing() .getCurrentBillingCycleUsage(accountId); System.out.println("Billing period: " + usage.getStartDate() + " to " + usage.getEndDate()); System.out.println("Emails sent: " + usage.getEmailsSent()); System.out.println("Email limit: " + usage.getEmailLimit()); System.out.println("Tests sent: " + usage.getTestsSent()); System.out.println("Test limit: " + usage.getTestLimit()); System.out.println("Percentage used: " + (usage.getEmailsSent() * 100.0 / usage.getEmailLimit()) + "%"); ``` ## Error Handling Handle different types of exceptions from the Mailtrap API ```java import io.mailtrap.exception.BaseMailtrapException; import io.mailtrap.exception.InvalidRequestBodyException; import io.mailtrap.exception.http.HttpClientException; import io.mailtrap.exception.http.HttpServerException; MailtrapMail mail = MailtrapMail.builder() .from(new Address("sender@yourdomain.com")) .to(List.of(new Address("recipient@example.com"))) .subject("Test Email") .text("Test content") .build(); try { SendResponse response = client.sendingApi().emails().send(mail); System.out.println("Email sent successfully!"); System.out.println("Message IDs: " + response.getMessageIds()); } catch (InvalidRequestBodyException e) { // Validation errors (missing required fields, invalid format, etc.) System.err.println("Invalid request: " + e.getMessage()); System.err.println("Check your email fields and try again."); } catch (HttpClientException e) { // 4xx errors (authentication, rate limits, invalid data) System.err.println("Client error: " + e.getMessage()); System.err.println("Status code: " + e.getStatusCode()); if (e.getStatusCode() == 401) { System.err.println("Check your API token."); } else if (e.getStatusCode() == 429) { System.err.println("Rate limit exceeded. Wait before retrying."); } } catch (HttpServerException e) { // 5xx errors (server problems) System.err.println("Server error: " + e.getMessage()); System.err.println("Status code: " + e.getStatusCode()); System.err.println("Retry the request later."); } catch (BaseMailtrapException e) { // Other Mailtrap-specific errors System.err.println("Mailtrap error: " + e.getMessage()); } catch (Exception e) { // Unexpected errors System.err.println("Unexpected error: " + e.getMessage()); e.printStackTrace(); } ``` ## Advanced Configuration with Custom HTTP Client Use a custom HTTP client implementation for specialized requirements ```java import io.mailtrap.http.CustomHttpClient; import io.mailtrap.http.RequestData; import java.time.Duration; import java.util.List; // Implement custom HTTP client if needed CustomHttpClient customClient = new CustomHttpClient() { // Implement all required methods with your custom logic // For logging, proxies, custom timeouts, etc. }; // Configure with custom settings MailtrapConfig config = new MailtrapConfig.Builder() .token("your_api_token_here") .connectionTimeout(Duration.ofSeconds(30)) .httpClient(customClient) // Optional custom HTTP client .build(); MailtrapClient client = MailtrapClientFactory.createMailtrapClient(config); ``` ## Summary The Mailtrap Java SDK provides a comprehensive solution for integrating email functionality into Java applications. Its primary use cases include transactional email delivery for production applications, safe email testing in isolated sandbox environments, bulk email campaigns for marketing and newsletters, and complete contact management for customer communication. The SDK excels at development and testing workflows by allowing teams to test email delivery, rendering, and spam scores without sending to real recipients, while seamlessly switching to production sending when ready. Integration patterns are straightforward with the SDK's fluent builder APIs and clear separation of concerns. Developers typically initialize a single MailtrapClient instance configured for their primary use case (sending, testing, or bulk), then access specialized APIs through the client's getter methods. The SDK handles all authentication, validation, and error handling automatically, with strongly-typed request and response objects ensuring compile-time safety. For production deployments, the SDK supports custom HTTP client implementations for advanced requirements like connection pooling, proxy configuration, and custom retry logic. The library's dependency on standard Jakarta validation and Jackson serialization makes it compatible with most Java frameworks including Spring Boot, Quarkus, and Jakarta EE applications.