Eight provider packages implement IEmailProvider. Each accepts an options object with the
credentials and transport settings it needs. Register any of them with UseProvider (or a
factory) in AddMailForge.
services.AddMailForge(builder => builder
.UseDefaultFrom("noreply@example.com")
.UseProvider(new ResendEmailProvider(new ResendOptions { ApiKey = "re_..." })));
| Provider | Package | Attachments | Inline images | Headers | Tags |
|---|---|---|---|---|---|
| SMTP | MailForge.Smtp | ✓ | ✓ | ✓ | ✓ |
| Amazon SES | MailForge.AmazonSES | ✓ | ✓ | ✓ | ✓ |
| Postmark | MailForge.Postmark | ✓ | ✓ | ✓ | ✓ |
| Mailgun | MailForge.Mailgun | ✓ | ✓ | ✓ | ✓ |
| Brevo | MailForge.Brevo | ✓ | ✓ | ✓ | ✓ |
| Resend | MailForge.Resend | ✓ | ❌ | ✓ | ✓ |
| ZeptoMail | MailForge.ZeptoMail | ✓ | ✓ | ❌ | ❌ |
| Azure Communication Services | MailForge.AzureCS | ✓ | ✓¹ | ✓ | ❌ |
¹ Azure CS has no cid: attachment mechanism; inline images are rewritten as data: URIs
in the HTML body.
MailForge.Smtp)var provider = new SmtpEmailProvider(new SmtpOptions
{
Host = "smtp.example.com",
Port = 587,
SecureSocketOptions = SecureSocketOptions.StartTls,
Username = "user",
Password = "secret",
LocalDomain = "local",
TimeoutMilliseconds = 30000
});
Built on MailKit. Validation is deferred to the SMTP server, so invalid recipients surface as delivery failures rather than validation errors.
MailForge.AmazonSES)var provider = new AmazonSesEmailProvider(new AmazonSesOptions
{
Region = "us-east-1",
AccessKey = "...", // optional; the SDK default credential chain is used when absent
SecretKey = "...",
ConfigurationSetName = null,
MaxErrorRetry = 3
});
Messages are sent through the raw-message API. Credentials fall back to the standard AWS
credential chain (AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, profiles, IAM roles).
MailForge.Postmark)var provider = new PostmarkEmailProvider(new PostmarkOptions
{
ServerToken = "server-token",
MessageStream = "outbound" // default
});
BaseUri and Timeout are configurable. Attachments use Postmark’s inline attachment
format, so inline images work out of the box.
MailForge.Mailgun)var provider = new MailgunEmailProvider(new MailgunOptions
{
ApiKey = "key-...",
Domain = "mg.example.com" // required
});
The domain must be verified with Mailgun. BaseUri and Timeout are configurable.
MailForge.Brevo)var provider = new BrevoEmailProvider(new BrevoOptions { ApiKey = "xkeysib-..." });
BaseUri and Timeout are configurable.
MailForge.Resend)var provider = new ResendEmailProvider(new ResendOptions { ApiKey = "re_..." });
Resend does not support inline images; mark the capabilities accordingly (see the matrix).
BaseUri and Timeout are configurable.
MailForge.ZeptoMail)var provider = new ZeptoMailEmailProvider(new ZeptoMailOptions { SendApiKey = "..." });
Headers and tags are not supported by the ZeptoMail API; any Headers/Tags on a message
are dropped. BaseUri and Timeout are configurable.
MailForge.AzureCS)var provider = new AzureCSEmailProvider(new AzureCSOptions
{
Endpoint = "https://my-resource.communication.azure.com",
AccessKey = "base64-access-key", // as it appears in the connection string
SenderAddress = "noreply@verified-domain.com"
});
AccessKey is Base64-decoded before signing.Providers are plain objects; register them yourself and supply a factory:
services.AddSingleton(new ResendEmailProvider(new ResendOptions { ApiKey = Config.Resend }));
services.AddMailForge(builder => builder
.UseDefaultFrom("noreply@example.com")
.UseProvider(sp => sp.GetRequiredService<ResendEmailProvider>()));
See Failover to route across multiple providers.