# Mailtrap Elixir Client ## Introduction The Mailtrap Elixir client is an official library providing complete integration with Mailtrap's email delivery and testing infrastructure. It enables developers to send transactional emails in production environments and safely test email functionality without delivering to real recipients. The library offers both direct HTTP API access for flexibility and specialized clients optimized for Mailtrap's Sandbox (testing) and Sending (production) APIs. Built with a modular architecture, the client supports two integration patterns: direct API usage for fine-grained control and Bamboo framework adapters for seamless Phoenix application integration. It provides a fluent email builder API with comprehensive support for attachments, custom headers, variables, multiple recipients, and both HTML and plain text content, making it suitable for everything from simple notifications to complex transactional emails with tracking capabilities. ## API Documentation ### Create Mailtrap Generic API Client Creates an authenticated HTTP client for accessing Mailtrap's REST API endpoints. This generic client provides access to all Mailtrap API functionality including account management, inbox operations, and other non-email-specific endpoints. ```elixir # Create client with API token client = Mailtrap.client("your_api_token_here") # List accounts {:ok, accounts} = Mailtrap.get(client, "accounts") # Delete account access account_id = "123" access_id = "456" {:ok, response} = Mailtrap.delete( client, "accounts/#{account_id}/account_accesses/#{access_id}" ) # Make custom API requests {:ok, data} = Mailtrap.post(client, "custom/endpoint", %{key: "value"}) ``` ### Build Email Message Constructs email messages using a fluent builder pattern. The Email struct supports all standard email fields with chainable functions for composing complex messages including multiple recipients, attachments, custom headers, and tracking variables. ```elixir # Build complete email with all fields email = %Mailtrap.Email{} |> Mailtrap.Email.put_from({"Sender Name", "sender@example.com"}) |> Mailtrap.Email.put_to([ {"Alice", "alice@example.com"}, {"Bob", "bob@example.com"} ]) |> Mailtrap.Email.put_cc({"Support", "support@example.com"}) |> Mailtrap.Email.put_bcc({"Admin", "admin@example.com"}) |> Mailtrap.Email.put_subject("Monthly Report") |> Mailtrap.Email.put_text("Plain text version of the report") |> Mailtrap.Email.put_html("

Report

HTML version

") |> Mailtrap.Email.put_category("reports") |> Mailtrap.Email.put_custom_variables(%{ "user_id" => "12345", "report_type" => "monthly" }) |> Mailtrap.Email.put_headers(%{ "X-Priority" => "1", "X-Custom-Tracking" => "enabled" }) # Simple email with minimal fields simple_email = %Mailtrap.Email{} |> Mailtrap.Email.put_from("no-reply@example.com") |> Mailtrap.Email.put_to("user@example.com") |> Mailtrap.Email.put_subject("Welcome!") |> Mailtrap.Email.put_text("Thanks for signing up!") ``` ### Add Email Attachments Creates email attachments with automatic Base64 encoding and optional metadata. Supports both standard attachments and inline content for embedding images in HTML emails using content IDs. ```elixir # PDF attachment {:ok, pdf_data} = File.read("invoice.pdf") pdf_attachment = Mailtrap.Email.Attachment.build(pdf_data, "invoice.pdf") |> Mailtrap.Email.Attachment.put_type("application/pdf") |> Mailtrap.Email.Attachment.put_disposition("attachment") # Inline image for HTML email {:ok, logo_data} = File.read("logo.png") logo_attachment = Mailtrap.Email.Attachment.build(logo_data, "logo.png") |> Mailtrap.Email.Attachment.put_type("image/png") |> Mailtrap.Email.Attachment.put_disposition("inline") |> Mailtrap.Email.Attachment.put_content_id("logo") # Text file attachment text_attachment = Mailtrap.Email.Attachment.build( "Report data:\n1. Item A\n2. Item B", "report.txt" ) |> Mailtrap.Email.Attachment.put_type("text/plain") # Add attachments to email email = %Mailtrap.Email{} |> Mailtrap.Email.put_from("sender@example.com") |> Mailtrap.Email.put_to("recipient@example.com") |> Mailtrap.Email.put_subject("Invoice with Logo") |> Mailtrap.Email.put_html( "

See attached invoice

" ) |> Mailtrap.Email.put_attachments([ pdf_attachment, logo_attachment, text_attachment ]) ``` ### Send Email to Sandbox for Testing Sends emails to Mailtrap's Sandbox environment for safe testing without delivering to real recipients. Requires a sandbox API token and inbox ID. This is the recommended approach for development and testing environments. ```elixir # Create sandbox client client = Mailtrap.Sandbox.client("sandbox_api_token") # Build test email email = %Mailtrap.Email{} |> Mailtrap.Email.put_from({"Test Sender", "sender@example.com"}) |> Mailtrap.Email.put_to({"Test Recipient", "recipient@example.com"}) |> Mailtrap.Email.put_subject("Test Email") |> Mailtrap.Email.put_text("This is a test message") |> Mailtrap.Email.put_html("

This is a test message

") # Send to sandbox inbox inbox_id = 111 case Mailtrap.Sandbox.send(client, email, inbox_id) do {:ok, response} -> IO.inspect(response) # %{"success" => true, "message_ids" => ["abc123", "def456"]} {:error, %Tesla.Env{status: status, body: body}} -> IO.puts("Error #{status}: #{inspect(body)}") end # Test email with attachments {:ok, attachment_data} = File.read("test-file.pdf") attachment = Mailtrap.Email.Attachment.build(attachment_data, "document.pdf") |> Mailtrap.Email.Attachment.put_type("application/pdf") test_email = %Mailtrap.Email{} |> Mailtrap.Email.put_from("sender@example.com") |> Mailtrap.Email.put_to("recipient@example.com") |> Mailtrap.Email.put_subject("Test with Attachment") |> Mailtrap.Email.put_text("See attached") |> Mailtrap.Email.put_attachments([attachment]) {:ok, _} = Mailtrap.Sandbox.send(client, test_email, inbox_id) ``` ### Send Email via Production Sending API Sends emails to real recipients via Mailtrap's production Sending API. This client is used in production environments for transactional email delivery with real-time tracking and analytics. ```elixir # Create sending client client = Mailtrap.Sending.client("sending_api_token") # Build production email email = %Mailtrap.Email{} |> Mailtrap.Email.put_from({"Company Name", "no-reply@company.com"}) |> Mailtrap.Email.put_to([ {"John Doe", "john@example.com"}, {"Jane Smith", "jane@example.com"} ]) |> Mailtrap.Email.put_subject("Password Reset Request") |> Mailtrap.Email.put_text("Click the link to reset your password") |> Mailtrap.Email.put_html("""

Password Reset

Click the link below to reset your password:

Reset Password """) |> Mailtrap.Email.put_category("authentication") |> Mailtrap.Email.put_custom_variables(%{ "user_id" => "67890", "reset_token" => "xyz123" }) # Send email case Mailtrap.Sending.send(client, email) do {:ok, %{"success" => true, "message_ids" => ids}} -> IO.puts("Sent successfully! Message IDs: #{inspect(ids)}") {:error, %Tesla.Env{status: 401}} -> IO.puts("Authentication failed - check API token") {:error, %Tesla.Env{status: status, body: body}} -> IO.puts("Error #{status}: #{inspect(body)}") end # Transactional email with tracking order_email = %Mailtrap.Email{} |> Mailtrap.Email.put_from({"Shop", "orders@shop.com"}) |> Mailtrap.Email.put_to({"Customer", "customer@example.com"}) |> Mailtrap.Email.put_subject("Order Confirmation #12345") |> Mailtrap.Email.put_html("

Thank you for your order!

") |> Mailtrap.Email.put_category("orders") |> Mailtrap.Email.put_custom_variables(%{ "order_id" => "12345", "amount" => "99.99" }) {:ok, _} = Mailtrap.Sending.send(client, order_email) ``` ### Configure Bamboo Sandbox Adapter Integrates Mailtrap Sandbox with Phoenix applications using the Bamboo email framework. This adapter enables seamless email testing in development and staging environments using standard Bamboo APIs. ```elixir # config/dev.exs config :my_app, MyApp.Mailer, adapter: Bamboo.MailtrapSandboxAdapter, api_token: System.get_env("MAILTRAP_SANDBOX_TOKEN"), inbox_id: System.get_env("MAILTRAP_INBOX_ID") # lib/my_app/mailer.ex defmodule MyApp.Mailer do use Bamboo.Mailer, otp_app: :my_app end # lib/my_app/user_email.ex defmodule MyApp.UserEmail do import Bamboo.Email def welcome_email(user) do new_email( to: {user.name, user.email}, from: {"MyApp Support", "support@myapp.com"}, subject: "Welcome to MyApp!", html_body: "

Welcome, #{user.name}!

", text_body: "Welcome, #{user.name}!" ) end def password_reset(user, reset_token) do new_email( to: user.email, from: "no-reply@myapp.com", subject: "Reset Your Password", html_body: """

Click here to reset: Reset

""", text_body: "Reset link: https://myapp.com/reset/#{reset_token}" ) end end # Usage in application code user = %{name: "Alice", email: "alice@example.com"} MyApp.UserEmail.welcome_email(user) |> MyApp.Mailer.deliver_now() # Async delivery MyApp.UserEmail.password_reset(user, "token123") |> MyApp.Mailer.deliver_later() ``` ### Configure Bamboo Sending Adapter Integrates Mailtrap Sending API with Phoenix applications for production email delivery. Uses the same Bamboo interface as the sandbox adapter, making it easy to switch between testing and production environments. ```elixir # config/prod.exs config :my_app, MyApp.Mailer, adapter: Bamboo.MailtrapSendingAdapter, api_token: System.get_env("MAILTRAP_SENDING_TOKEN") # lib/my_app/mailer.ex defmodule MyApp.Mailer do use Bamboo.Mailer, otp_app: :my_app end # lib/my_app/notification_email.ex defmodule MyApp.NotificationEmail do import Bamboo.Email def order_confirmation(order) do new_email( to: {order.customer.name, order.customer.email}, from: {"Shop", "orders@shop.com"}, subject: "Order Confirmation ##{order.id}", html_body: render_order_html(order), text_body: render_order_text(order) ) |> put_header("X-Order-ID", to_string(order.id)) end def promotional_email(users, campaign) do Enum.map(users, fn user -> new_email( to: user.email, from: {"Marketing", "marketing@shop.com"}, subject: campaign.subject, html_body: campaign.html_content, text_body: campaign.text_content ) |> put_header("X-Campaign-ID", campaign.id) |> put_header("X-User-ID", user.id) end) end defp render_order_html(order) do """

Order ##{order.id}

Total: $#{order.total}

Items: #{Enum.count(order.items)}

""" end defp render_order_text(order) do "Order ##{order.id} - Total: $#{order.total}" end end # Usage in Phoenix controller def create(conn, %{"order" => order_params}) do with {:ok, order} <- Orders.create_order(order_params) do # Send confirmation email MyApp.NotificationEmail.order_confirmation(order) |> MyApp.Mailer.deliver_now() json(conn, %{status: "success", order_id: order.id}) end end # Batch email sending def send_promotional_campaign(campaign_id) do campaign = Campaigns.get_campaign!(campaign_id) users = Users.get_subscribed_users() MyApp.NotificationEmail.promotional_email(users, campaign) |> Enum.each(&MyApp.Mailer.deliver_later/1) end ``` ### Email with Bamboo Attachments Demonstrates how to attach files to emails when using Bamboo adapters. The adapter automatically converts Bamboo attachments to Mailtrap format with proper encoding and metadata preservation. ```elixir # lib/my_app/report_email.ex defmodule MyApp.ReportEmail do import Bamboo.Email def monthly_report(user, report_data) do # Generate PDF report {:ok, pdf_content} = generate_pdf_report(report_data) # Generate CSV data csv_content = generate_csv_report(report_data) new_email( to: {user.name, user.email}, from: {"Reports", "reports@company.com"}, subject: "Monthly Report - #{Date.utc_today()}", html_body: """

Your Monthly Report

Please find your monthly report attached.

""", text_body: "Your monthly report is attached." ) |> put_attachment(Bamboo.Attachment.new( pdf_content, filename: "monthly_report.pdf", content_type: "application/pdf" )) |> put_attachment(Bamboo.Attachment.new( csv_content, filename: "data.csv", content_type: "text/csv" )) end def invoice_email(customer, invoice) do {:ok, pdf} = generate_invoice_pdf(invoice) {:ok, logo} = File.read("priv/static/images/logo.png") new_email( to: customer.email, from: "billing@company.com", subject: "Invoice ##{invoice.number}", html_body: """

Invoice ##{invoice.number}

Amount due: $#{invoice.amount}

""" ) |> put_attachment(Bamboo.Attachment.new( pdf, filename: "invoice_#{invoice.number}.pdf", content_type: "application/pdf" )) |> put_attachment(Bamboo.Attachment.new( logo, filename: "logo.png", content_type: "image/png", content_id: "company_logo" )) end defp generate_pdf_report(data), do: {:ok, "PDF content"} defp generate_csv_report(data), do: "CSV,Content\n1,Data" defp generate_invoice_pdf(invoice), do: {:ok, "Invoice PDF"} end # Usage user = Users.get_user!(123) report_data = Reports.get_monthly_data(user) MyApp.ReportEmail.monthly_report(user, report_data) |> MyApp.Mailer.deliver_now() ``` ## Summary The Mailtrap Elixir client serves three primary use cases: development and testing of email functionality using the Sandbox API, production transactional email delivery via the Sending API, and direct REST API access for advanced account and inbox management. The library excels at safely testing email workflows without affecting real users, making it ideal for development teams that need confidence in their email implementations before deploying to production. With comprehensive attachment support, custom tracking variables, and flexible header management, it handles everything from simple notifications to complex multi-recipient campaigns with analytics. Integration patterns are straightforward and flexible. For direct API usage, developers instantiate clients with API tokens and use fluent builder methods to construct emails before sending. For Phoenix applications, the Bamboo adapters provide drop-in compatibility with existing email infrastructure - simply swap the adapter configuration between sandbox and production environments without changing application code. The library's modular design allows teams to start with the sandbox for testing, use the direct API for custom workflows, and seamlessly transition to Bamboo adapters as applications grow. All integration patterns share the same underlying email construction API, ensuring consistency and reducing the learning curve across different deployment scenarios.