Mailchimp Transactional email provider

Mailchimp Transactional (formerly Mandrill) provider implementing email.ProviderPort against the Mailchimp Transactional API.

Overview

Mailchimp Transactional is the rebranded Mandrill, Mailchimp's transactional sending product. Mailchimp gates it behind an active paid Marketing plan, so you cannot subscribe to Transactional on its own.

The provider is a drop-in email.ProviderPort. You write the constructor call and two bootstrap options. The rest of the email service, builders, dispatcher, retries, and metrics, then works against Mailchimp Transactional unchanged.

Send attempts and durations flow through the same OpenTelemetry stack as the rest of the application. The provider records email.provider.mailchimp_transactional.send.total and email.provider.mailchimp_transactional.send.duration, both labelled status (success or error) and send_type (single or bulk). All public methods are safe for concurrent use.

The provider uses only net/http and the Go standard library. It needs no build tags, no cgo, and no system libraries, so it runs in compiled builds and in the interpreted dev mode.

Requirements

  • An active Mailchimp Marketing account on a paid monthly plan, with Transactional enabled and API access.
  • A verified sending domain matching FromEmail.
  • Network egress to the API base URL mandrillapp.com. This is the legacy Mandrill hostname.

Configuration

import (
    "context"
    "os"

    "piko.sh/piko/wdk/email/email_provider_mailchimp_transactional"
)

provider, err := email_provider_mailchimp_transactional.NewMailchimpTransactionalProvider(
    ctx,
    email_provider_mailchimp_transactional.MailchimpTransactionalProviderArgs{
        APIKey:    os.Getenv("MAILCHIMP_TRANSACTIONAL_API_KEY"), // required
        FromEmail: "[email protected]",                         // required; verified sender
    },
)
if err != nil {
    return err
}

The constructor installs a default rate limiter of 10 calls per second with a burst of 20. Every Send waits on this limiter before it calls the API, which keeps a batch within the 10 concurrent connections Mailchimp Transactional allows per key. The limiter is not configurable through the public API today. The provider also caps the response body at 4 MiB and returns an error past that size, which guards against a hostile or runaway reply.

Bootstrap

ssr := piko.New(
    piko.WithEmailProvider("mailchimp-transactional", provider),
    piko.WithDefaultEmailProvider("mailchimp-transactional"),
)

Sending behaviour

The default sender comes from FromEmail. A message can override it per send by setting the From field on the send parameters.

Mailchimp Transactional has no separate bulk endpoint, so SupportsBulkSending returns false. A bulk send fans out to individual Send calls and aggregates any failures into a MultiError, so the dispatcher still gets per-email error reporting.

Mailchimp-specific features are reachable through the email builder's ProviderOption(key, value) method, without leaving piko. The provider maps these keys onto the Mandrill message or request:

  • tags. A []string of message tags used for filtering and reporting.
  • track_opens. A bool that enables or disables open tracking.
  • track_clicks. A bool that enables or disables click tracking.
  • metadata. A map[string]string of key-value pairs attached to the message.
  • important. A bool that marks the message as important.
  • auto_text. A bool that generates a plain-text part from the HTML body.
  • inline_css. A bool that inlines CSS styles into the HTML body.
  • headers. A map[string]string of custom email headers.
  • async. A bool that requests asynchronous delivery.

See also

Other email providers:

  • SendGrid, combined transactional and marketing without the Mailchimp prerequisite.
  • Postmark, transactional-only, sub-second delivery.
  • SES, cheapest at scale if already on AWS.
  • Mailgun, strong EU presence, flexible routing rules.
  • SMTP, generic backend for self-hosted or vendor-neutral relays.
  • Gmail, Gmail SMTP with app passwords (dev / low-volume).

Framework docs:

External: