Mailgun email provider
Mailgun provider implementing email.ProviderPort against Mailgun's REST API.
Overview
Mailgun is a developer-focused email service provider. The adapter sends outbound mail through Mailgun's HTTP REST API, not the SMTP gateway. It covers single send, bulk send, attachments, and inline images keyed by Content-ID. Per-message tags and open or click tracking pass through as provider options. Both the U.S. and EU regions are reachable by choosing the matching API hostname.
The adapter implements email.ProviderPort, so the same EmailBuilder and templated-email API work regardless of which provider you register. The adapter rate-limits itself. A token bucket caps sends at 50 calls per second with a burst of 100, so the provider self-throttles against Mailgun without any limiter code on your side.
The adapter emits OpenTelemetry metrics for send count and duration, labelled by status and by single or bulk send. All methods are safe for concurrent use. The adapter sends only. Mailgun's inbound routing, parsing, and forwarding are not part of this integration.
Requirements
- A Mailgun account with API access. Generate a private API key in the Mailgun dashboard (Settings, then API Security).
- A verified sending domain (for example
mg.example.com) with the matching DNS records (SPF, DKIM). - Network egress to
api.mailgun.net(U.S. region) orapi.eu.mailgun.net(EU region). Select the EU region with theAPIBasefield onMailgunProviderArgs.
Configuration
import (
"context"
"os"
"piko.sh/piko/wdk/email/email_provider_mailgun"
)
provider, err := email_provider_mailgun.NewMailgunProvider(ctx, email_provider_mailgun.MailgunProviderArgs{
Domain: "mg.example.com", // required, the verified sending domain
APIKey: os.Getenv("MAILGUN_API_KEY"), // required
FromEmail: "[email protected]", // required, default From address
APIBase: "https://api.eu.mailgun.net", // optional, omit for the U.S. region
})
if err != nil {
return err
}
NewMailgunProvider returns an email.ProviderPort. The fourth field, APIBase, overrides the API base URL. Leave it empty for the U.S. endpoint, or set it to https://api.eu.mailgun.net for the EU region. The constructor returns an error when Domain, APIKey, or FromEmail is empty, so a misconfigured provider fails at startup, not at first send.
Per-message options
Set Mailgun-specific behaviour per message through the EmailBuilder.ProviderOption method. The adapter reads these keys:
tag. A string label for Mailgun analytics.tracking. A bool that turns message tracking on or off.tracking_clicks. A bool for click tracking.tracking_opens. A bool for open tracking.require_tls. A bool that requires TLS for delivery.skip_verification. A bool that skips certificate verification.
err := builder.
To("[email protected]").
Subject("Welcome").
BodyHTML("<p>Hello</p>").
ProviderOption("tag", "onboarding").
ProviderOption("tracking_opens", true).
Do(ctx)
The adapter drops unrecognised keys. The adapter never returns delivery events or per-message tracking IDs back through piko. The only telemetry it surfaces is the OpenTelemetry send count and duration.
Bulk sending
SupportsBulkSending returns false. SendBulk fans out to one Send call per message, and each call passes through the same rate limiter. Failures aggregate into an email.MultiError, so a partial failure reports which messages did not send and leaves the rest delivered.
Bootstrap
ssr := piko.New(
piko.WithEmailProvider("mailgun", provider),
piko.WithDefaultEmailProvider("mailgun"),
)
See also
Other email providers:
- SendGrid, combined transactional and marketing.
- Postmark, transactional-only, sub-second delivery.
- SES, cheapest at scale if already on AWS.
- Mailchimp Transactional, the former Mandrill.
- SMTP, generic backend for self-hosted or vendor-neutral relays.
- Gmail, Gmail SMTP with app passwords (dev / low-volume).
Framework docs:
- Email API reference, every type and method on the email service.
External:
- Mailgun API documentation, authoritative reference.
- EU vs U.S. regions, endpoint and data-residency selection.