Kyle Seyler
February 23, 2026

Table of contents
The providers we're comparing
SendGrid: the safe bet that handles scale
Postmark: speed as a feature
Mailgun: granular control for complex setups
Amazon SES: raw power, assembly required
Resend: modern DX for the React generation
SMTP: the universal standard
The real question: how do you manage all of this?
Quick reference: provider comparison
The AI agent test: which API would I wire up first?
What we'd pick
Your email provider choice sticks with you longer than most technical decisions. It's baked into your send logic, your templates, your retry handling, your observability stack. Ripping it out later is a real project, not a quick swap.
Courier handles notification infrastructure for thousands of teams so we decided to deep on the documentation, APIs, and developer tooling of the six email providers that show up most in our customers' stacks. This is what we found: real API primitives, actual code snippets from each provider's docs, and an honest read on where the developer experience holds up and where it breaks down.
We evaluated six email providers based on their APIs, SDKs, developer tooling, and documentation quality:
Each of these is available as a first-class integration inside Courier. That matters because the real insight here isn't which single provider is "best." It's that most production teams end up needing more than one, and the real question is how you manage them.
Best for: High-volume senders who need proven reliability and the Twilio ecosystem
SendGrid offers both a REST API (v3) and SMTP relay. Their Node.js SDK is one of the most battle-tested email libraries on npm:
Copied!
// npm install @sendgrid/mailconst sgMail = require('@sendgrid/mail');sgMail.setApiKey(process.env.SENDGRID_API_KEY);const msg = {to: 'user@example.com',from: 'notifications@yourapp.com',subject: 'Your order has shipped',text: 'Track your package at...',html: '<strong>Your order is on the way!</strong>',};sgMail.send(msg);
Clean enough. The SDK handles auth via Bearer token, and the msg object maps directly to SendGrid's v3 /mail/send endpoint. Official libraries exist for Java, PHP, Go, Python, C#, and Ruby.
The raw API is more verbose but transparent:
Copied!
curl --request POST \--url https://api.sendgrid.com/v3/mail/send \--header "Authorization: Bearer $SENDGRID_API_KEY" \--header 'Content-Type: application/json' \--data '{"personalizations": [{"to": [{"email": "user@example.com"}]}],"from": {"email": "notifications@yourapp.com"},"subject": "Your order has shipped","content": [{"type": "text/plain", "value": "Track your package..."}]}'
That personalizations array is a SendGrid-ism you'll get used to. It's how they handle recipient-level customization, but it adds a layer of nesting that other providers skip.
SendGrid's documentation is comprehensive but sprawling. Quickstart guides exist for every major language (C#, Go, Java, Node.js, PHP, Python, Ruby), and each walks you through account setup, API key creation, domain authentication, and sending your first email. The v3 API reference covers every endpoint.
The problem: finding things. The docs have been reorganized multiple times over the years, and search doesn't always surface the right page. If you know what you're looking for, you'll find it. If you're exploring, you might get lost.
Courier's SendGrid integration supports full API key configuration, template imports, and provider-level overrides. You can import existing SendGrid Dynamic Templates directly, so you don't have to rebuild if you're adding an orchestration layer later.
Here's how overrides work when routing through Courier. You still get full access to SendGrid's API surface:
Copied!
{"message": {"template": "ORDER_SHIPPED","to": {"email": "user@example.com"},"providers": {"sendgrid": {"override": {"body": {"subject": "Your order has shipped","attachments": [{"content": "eyJmb28iOiJiYXIifQ==","type": "application/json","filename": "order-details.json"}]}}}}}}
You can override any field supported by SendGrid's /mail/send endpoint. Courier also supports webhook configuration for real-time delivery status updates and email activity tracking via polling.
The documentation sprawl, likely do to being such a standard for all these years. Best deliverability features (dedicated IPs, advanced analytics) are locked behind higher-tier plans. Support quality on the free tier is basically self-service. And the personalizations API design adds complexity for simple use cases.
Free tier: 100 emails/day. Paid plans start at $19.95/month for 50K emails. Dedicated IPs start at $89.95/month.
Best for: Teams where delivery speed is non-negotiable, especially for OTPs and password resets
Postmark's API is focused and opinionated. The Node.js library is minimal by design:
Copied!
// npm install postmarkconst postmark = require("postmark");const client = new postmark.ServerClient("POSTMARK-SERVER-API-TOKEN");client.sendEmail({From: "notifications@yourapp.com",To: "user@example.com",Subject: "Your verification code",TextBody: "Your code is 847291. It expires in 10 minutes."});
Four lines of setup. No configuration objects. No personalizations arrays. The property names (From, To, Subject, TextBody, HtmlBody) map directly to the JSON API:
Copied!
curl "https://api.postmarkapp.com/email" \-X POST \-H "Accept: application/json" \-H "Content-Type: application/json" \-H "X-Postmark-Server-Token: YOUR-SERVER-TOKEN" \-d '{"From": "notifications@yourapp.com","To": "user@example.com","Subject": "Your verification code","TextBody": "Your code is 847291."}'
Notice the authentication: a single X-Postmark-Server-Token header. No Bearer token prefix, no multi-step auth flow. Postmark uses Server API tokens (for sending) and Account API tokens (for management) with clear separation.
Postmark's documentation is the gold standard for developer-friendly email docs. Their official libraries page provides copy-paste examples for Node.js, Ruby, .NET, Python, PHP, Go, Java, and even a CLI tool. The API reference is clean, every endpoint has request/response examples, and the guides are written in plain language.
Their approach to Message Streams deserves special mention. Transactional and broadcast emails run on separate infrastructure, and the docs explain why this matters for deliverability. This is a real architectural advantage that's well-documented rather than hidden in marketing copy.
Batch sending supports up to 500 messages per API call:
Copied!
client.sendEmailBatch([{From: "notifications@yourapp.com",To: "alice@example.com",Subject: "Weekly digest",HtmlBody: "<h1>Your weekly summary</h1>"},{From: "notifications@yourapp.com",To: "bob@example.com",Subject: "Weekly digest",HtmlBody: "<h1>Your weekly summary</h1>"}]);
Courier's Postmark integration supports overrides, Message Streams, attachments, and Postmark's native template system. Here's routing through a specific Message Stream with an attachment:
Copied!
{"message": {"template": "WELCOME_EMAIL","to": {"email": "user@example.com"},"providers": {"postmark": {"override": {"config": {"MessageStream": "onboarding"},"body": {"Attachments": [{"Name": "getting-started.pdf","Content": "dGVzdCBjb250ZW50","ContentType": "application/pdf"}]}}}}}}
You can also map Courier templates to Postmark's native templates by pointing the config to Postmark's /email/withTemplate endpoint and passing a TemplateId and TemplateModel. This gives you the option to design in either tool.
No free tier. You get a 10-day trial and then it's $15/month for 10K emails. The template editor is basic compared to SendGrid's. Subject lines are capped at ~60 characters (encoding reduces this further with emojis). And it's email-only.
$15/month for 10K emails. Scales to $695/month for 300K.
For most product teams: use Postmark as your email provider inside Courier. You get Postmark's sub-2-second delivery speed and Courier's multi-channel orchestration without having to choose between them.
Best for: Developer teams building multi-tenant applications with complex routing needs
Mailgun ships five specialized APIs: sending, validation, templates, events, and analytics. This modularity is its real strength. The sending API uses standard REST:
Copied!
curl -s --user 'api:YOUR_API_KEY' \https://api.mailgun.net/v3/YOUR_DOMAIN/messages \-F from='notifications <notifications@yourapp.com>' \-F to='user@example.com' \-F subject='Password reset' \-F text='Click here to reset your password...'
Mailgun uses HTTP Basic Auth (api:YOUR_API_KEY) instead of Bearer tokens or custom headers. The form-encoded format is unusual but works well for multipart messages with attachments.
SDKs are available for Python, Ruby, Go, Java, PHP, Node.js, and C#. The Node.js library:
Copied!
const Mailgun = require('mailgun.js');const formData = require('form-data');const mg = new Mailgun(formData).client({username: 'api',key: process.env.MAILGUN_API_KEY});mg.messages.create('yourapp.com', {from: "notifications <notifications@yourapp.com>",to: ["user@example.com"],subject: "Password reset",text: "Click here to reset your password...",html: "<a href='https://yourapp.com/reset/abc123'>Reset password</a>"});
Mailgun's documentation is solid and developer-focused. The API reference is organized by the five API modules, making it easy to find what you need. Each endpoint includes request/response examples and parameter descriptions. The routing engine documentation stands out for its depth, with clear examples of pattern-based rules for complex email workflows.
Where it gets less polished: some of the best features are documented across multiple pages without clear cross-references. The validation API, inbox placement testing, and deliverability tools each have their own sections but could benefit from a unified "getting started with deliverability" guide.
EU region support is explicitly documented. If you're using Mailgun's EU infrastructure, you point to api.eu.mailgun.net instead of api.mailgun.net.
Courier's Mailgun integration supports the full feature set. The override system gives you access to Mailgun's Messages API, including tags, EU host config, and attachments:
Copied!
{"message": {"template": "PASSWORD_RESET","to": {"email": "user@example.com"},"providers": {"mailgun": {"override": {"body": {"o:tag": "password-reset"},"config": {"apiKey": "<your API Key>","domain": "<domain>","host": "api.eu.mailgun.net"}}}}}}
Attachments are sent as base64-encoded content:
Copied!
{"providers": {"mailgun": {"override": {"attachments": [{"filename": "invoice.pdf","contentType": "application/pdf","data": "Q29uZ3JhdHVsYXRpb25zLCB5b3UgY2FuIGJhc2U2NCBkZWNvZGUh"}]}}}}
Courier also supports webhook configuration for real-time delivery tracking, replacing the default polling behavior.
Mailgun was acquired by Sinch in 2021, and some developers have reported inconsistencies in deliverability and support quality since then. Default message retention is only 1 day. The validation API ($49+/month add-on), inbox placement testing, and other premium features cost extra. And Mailgun requires IP allowlisting for API access. Since Courier runs on AWS, there's a documented workaround using AWS's AmazonIpSpaceChanged SNS topic, but it's an extra step.
Free for 100 emails/day. Paid plans start at $15/month for 10K emails.
Best for: AWS-native teams with engineering capacity who want to keep costs minimal at volume
Amazon SES gives you two interfaces: a REST API and SMTP relay. The API follows standard AWS conventions, which means authentication uses AWS Signature Version 4 (not a simple API key). Here's the IAM policy you'll need:
Copied!
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": ["ses:SendEmail","ses:SendRawEmail"],"Resource": ["arn:aws:ses:us-east-1:YOUR_ACCOUNT_ID:identity/yourapp.com","arn:aws:ses:us-east-1:YOUR_ACCOUNT_ID:identity/notifications@yourapp.com"]}]}
That's just the permissions. The actual sending code using the AWS SDK for Node.js:
Copied!
const { SESClient, SendEmailCommand } = require("@aws-sdk/client-ses");const client = new SESClient({ region: "us-east-1" });const command = new SendEmailCommand({Source: "notifications@yourapp.com",Destination: {ToAddresses: ["user@example.com"]},Message: {Subject: { Data: "Your verification code" },Body: {Text: { Data: "Your code is 847291." },Html: { Data: "<p>Your code is <strong>847291</strong>.</p>" }}}});await client.send(command);
Compare that to Postmark's four-line setup or Resend's five-line example. SES is powerful, but you pay for that power with verbosity and setup complexity.
AWS documentation is thorough in the way only AWS can be: every edge case is covered, every parameter is documented, and the information is spread across approximately 47 different pages. The SES Developer Guide is comprehensive, covering authentication, sending quotas, deliverability best practices, and service integrations.
Where SES docs excel: the IAM permission examples are precise and copy-paste-ready. The integration with other AWS services (Lambda, SNS, CloudWatch) is well-documented with architecture diagrams.
Where they fall short: there's no quick "send your first email in 5 minutes" path. The sandbox limitations (new accounts can only send to verified addresses) catch developers off guard, and the process to request production access isn't prominently documented in the quickstart.
Courier supports two authentication methods for SES: AWS Access Keys and IAM Role (cross-account trust). The IAM Role approach is more secure for production:
Copied!
{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"AWS": "464962053586"},"Action": "sts:AssumeRole","Condition": {"StringEquals": {"sts:ExternalId": "YOUR_COURIER_WORKSPACE_ID"}}}]}
Once configured, you send through Courier's unified API and SES handles delivery. Courier supports region configuration so you can optimize delivery based on recipient geography. Overrides give you access to SES-specific settings including attachments and custom headers.
No template management UI. No drag-and-drop editor. No built-in design tools. The dashboard and analytics are minimal. Setup is more complex than any other provider on this list. Support requires an AWS Support plan (extra cost). New accounts start in sandbox mode with significant limitations. And error messages can be cryptic (the docs have a dedicated troubleshooting section for SES 554 errors, BCC issues, and timeout problems).
$0.10 per 1,000 emails. Free tier: 62,000 emails/month from EC2.
Best for: JavaScript/React teams who want a clean API and modern developer experience
Resend has the cleanest "hello world" of any provider on this list:
Copied!
// npm install resendimport { Resend } from 'resend';const resend = new Resend('re_xxxxxxxxx');const { data, error } = await resend.emails.send({from: 'Acme <notifications@yourapp.com>',to: ['user@example.com'],subject: 'Hello world',html: '<p>It works!</p>',});
Five lines. Destructured response with typed data and error. No callback hell, no status code checking. The SDK handles errors as return values, not thrown exceptions, which is a deliberate design choice that fits modern async/await patterns.
TypeScript support is first-class. The API follows REST best practices with predictable response shapes. Idempotency keys prevent duplicate sends when retrying:
Copied!
await resend.emails.send({from: 'Acme <notifications@yourapp.com>',to: ['user@example.com'],subject: 'Order confirmation',html: '<p>Your order #1234 is confirmed.</p>',headers: {'Idempotency-Key': 'order-1234-confirmation'}});
The killer feature is React Email integration. Instead of table-based HTML, you write email templates as React components:
Copied!
import { Html, Button } from "@react-email/components";export function WelcomeEmail({ url }) {return (<Html lang="en"><Button href={url}>Get Started</Button></Html>);}
Resend compiles this to cross-client-compatible HTML. Your email templates share components with your application. Same design system. Same tooling. Same language.
Resend's documentation is concise and well-organized. The API reference covers every endpoint with request/response examples. The SDK examples are available for Node.js, Python, Ruby, Go, and Java. Each endpoint documents every parameter clearly, including constraints (like tag names limited to 256 ASCII characters, or max 50 recipients per send).
Test email addresses are well-documented: send to delivered@resend.dev to simulate delivery, bounced@resend.dev for bounces, and complained@resend.dev for spam complaints. This makes testing webhook handlers straightforward without risking real deliverability.
The docs also handle templates cleanly. You can pass a template_id and variables instead of raw HTML, and the API validates that all required variables are provided before sending.
Courier's Resend integration walks through the full setup: getting your Resend API key, configuring the From address, creating a notification template, and sending your first message. The integration guide includes both JSON and URL-encoded cURL examples.
Copied!
{"message": {"template": "WELCOME_SEQUENCE","to": {"email": "user@example.com"},"data": {"name": "Alex"},"providers": {"resend": {"override": {"body": {"from": "Acme <welcome@yourapp.com>","reply_to": "support@yourapp.com"}}}}}}
Attachments work through the standard Courier attachment format with base64-encoded content.
Resend is younger than the other providers, which means a smaller track record at extreme scale. No email validation API or inbox placement testing yet. Dedicated IPs are an add-on. The free tier caps you at 100 emails/day (3,000/month), which is tight for testing. And while the React Email approach is great for React teams, it's less compelling if your stack is Python, Go, or Java.
Free: 100 emails/day (3,000/month). Pro: $20/month for 50K emails. Scale: $90/month for 100K.
Best for: Legacy systems, provider migration, and maximum portability
SMTP isn't a provider. It's a 40-year-old protocol. And sometimes that's exactly what you need.
Courier's SMTP integration lets you connect to any SMTP server. The setup is straightforward: host, port, username, password, from address. No provider-specific SDK required. Any language with an SMTP library (which is every language) can send through it.
Copied!
import smtplibfrom email.mime.text import MIMETextmsg = MIMEText("Your password has been reset.")msg['Subject'] = 'Password reset confirmation'msg['From'] = 'notifications@yourapp.com'msg['To'] = 'user@example.com'with smtplib.SMTP('smtp.yourprovider.com', 587) as server:server.starttls()server.login('username', 'password')server.send_message(msg)
SMTP makes sense when you're migrating between providers and need a bridge, when you're working with legacy systems, or when your email infrastructure is self-hosted. It's also a reasonable failover option. If your primary provider goes down, having an SMTP-based backup through a different provider gives you redundancy without writing new integration code.
No rich event data, webhook support, or analytics. You're trading visibility for universality. Debugging delivery issues is harder without provider-level logging.
If you've read this far, you've probably noticed a pattern. Each provider has genuine strengths, but none of them does everything well. The most common production setup we see looks something like this:
Managing multiple email providers means multiple APIs, multiple dashboards, multiple sets of delivery logs, and routing logic scattered across your codebase. Then multiply that by every other channel your product needs: SMS, push, Slack, Teams, in-app inbox.
This is the problem Courier solves. Courier sits above your email providers and handles the orchestration layer. One API call, regardless of how many providers or channels you're using:
Copied!
curl --request POST \--url https://api.courier.com/send \--header 'Authorization: Bearer YOUR_COURIER_API_KEY' \--header 'Content-Type: application/json' \--data '{"message": {"to": { "email": "user@example.com" },"template": "PASSWORD_RESET","data": { "reset_link": "https://app.example.com/reset/abc123" }}}'
That single call handles routing to the right provider, templating, delivery, retries, and logging. If your primary email provider goes down, Courier fails over to your backup automatically. If product decides next quarter that password resets should also send a push notification, you update the workflow in Courier's visual builder. No code changes. No redeployment.
You can swap SendGrid for Postmark without changing a line of application code. You can route time-sensitive emails through Postmark and bulk notifications through SES based on notification type. You can add SMS, Slack, Teams, and an in-app notification center without touching your email integration.
The provider-level overrides we showed in each section above? That's the escape hatch. Courier gives you a unified API without taking away the provider-specific features you need. You're not locked into a lowest-common-denominator abstraction.
| SendGrid | Postmark | Mailgun | Amazon SES | Resend | |
|---|---|---|---|---|---|
| Best for | Scale + Twilio ecosystem | Delivery speed | Complex routing | Cost at volume | Modern DX |
| API style | REST + SMTP | REST | REST (5 APIs) | REST + SMTP | REST + SMTP |
| SDK languages | Java, PHP, Go, Python, C#, Ruby, Node | Ruby, Python, JS, PHP, Go, Java, .NET | Python, Ruby, Go, Java, PHP, Node, C# | All AWS SDKs | Node, Python, Ruby, Go, Java |
| Template system | Dynamic Templates (Handlebars) | Mustachio | Handlebars | Basic HTML | React Email (JSX) |
| Delivery speed | Not published | <2 sec avg (published) | Not published | Variable | Not published |
| Auth method | Bearer token | Server API token header | HTTP Basic Auth | AWS Sig V4 / IAM | API key (Bearer) |
| Free tier | 100/day | None (trial only) | 100/day | 62K/mo from EC2 | 100/day (3K/mo) |
| Starting price | $19.95/mo (50K) | $15/mo (10K) | $15/mo (10K) | $0.10/1K emails | $20/mo (50K) |
| Docs quality | Comprehensive but sprawling | Clean and focused | Solid, modular | Thorough, verbose | Concise and modern |
| Courier integration | Templates, webhooks, overrides | Message Streams, templates, overrides | EU region, tags, attachments, webhooks | IAM Role, region config, overrides | Overrides, attachments |
We tried something different for this guide. We asked Claude, Anthropic's AI coding agent, to review the documentation, API design, and SDK patterns of every provider on this list, then tell us which one it would choose if it had to build an email integration from scratch. No brand loyalty. No business relationship. Just: which API is the least friction to implement correctly?
Why this matters: AI agents are now building notification infrastructure alongside developers. The API surface an agent encounters determines the quality of the code it produces. Read more: How To Build Notifications with AI + Courier MCP · Notifications Now Have Two Audiences: Humans and AI Agents
Here's what it said:
If I had to wire up one email provider right now, I'd pick Resend.
Not because it's the most feature-rich. It's not. But as a coding agent, I care about three things: how quickly I can go from zero to a working integration, how predictable the API responses are, and how likely I am to hit an undocumented edge case that wastes time.
Resend wins on all three.
The send call is five lines. The response is a single { id } object. Errors come back as structured { error } objects I can destructure alongside the data, not thrown exceptions I have to wrap in try/catch. That's a design decision that matters when you're writing code at speed. I don't have to guess at the error shape.
Copied!
const { data, error } = await resend.emails.send({from: 'App <notify@yourapp.com>',to: ['user@example.com'],subject: 'Your code is 847291',html: '<p>Expires in 10 minutes.</p>',});if (error) {// error is typed, structured, predictableconsole.error(error.name, error.message);}
Compare that to SendGrid, where I have to understand the personalizations array abstraction before I can send a basic email. The personalizations model is powerful for batch customization, but it's unnecessary complexity for the 90% case. And SendGrid's docs, while comprehensive, are spread across so many pages that finding the right example takes real navigation effort. As an agent scanning documentation, SendGrid's sheer volume of pages with overlapping content (v3 code examples, quickstart guides, API reference, framework-specific guides) creates ambiguity about which is the canonical source.
Copied!
// SendGrid: more setup, more abstractionconst sgMail = require('@sendgrid/mail');sgMail.setApiKey(process.env.SENDGRID_API_KEY);sgMail.send({to: 'user@example.com',from: 'notify@yourapp.com',subject: 'Your code is 847291',html: '<p>Expires in 10 minutes.</p>',}).then(() => {}, error => {// error.response.body? error.message? depends on the error typeconsole.error(error);if (error.response) console.error(error.response.body);});
Postmark is a close second. The API is clean, the auth is dead simple (one header, one token), and the docs are the best-organized of the bunch. I'd actually prefer Postmark's documentation structure over Resend's. Everything is where you'd expect it to be, the API reference is tidy, and the Message Streams concept is well-explained. Postmark also has an explicit "AI Prompts" section in their developer docs, which tells me they're thinking about how agents consume their API. That's forward-thinking.
Copied!
// Postmark: clean, predictable, zero surprisesconst client = new postmark.ServerClient("YOUR-TOKEN");client.sendEmail({From: "notify@yourapp.com",To: "user@example.com",Subject: "Your code is 847291",TextBody: "Expires in 10 minutes."});
Where Postmark loses a point: the PascalCase property names (From, To, Subject, TextBody). Every other API on this list uses camelCase or snake_case. PascalCase in a JSON body is a small friction that adds up when you're writing code quickly and your muscle memory expects lowercase.
Amazon SES I'd avoid unless the project was already on AWS and cost was the primary constraint. The IAM permission model, Signature Version 4 auth, sandbox limitations, and verbose SDK add up to the slowest time-to-first-email of any provider here. The SendEmailCommand pattern with nested Destination, Message, Subject, and Body objects is the most deeply nested API shape I reviewed. For an agent optimizing for speed and correctness, that nesting creates more surface area for mistakes.
Mailgun is solid middle ground. The five-API architecture is well-organized, and the docs are developer-focused. But the HTTP Basic Auth with form-encoded payloads is unusual enough that it'd slow me down on a first implementation compared to standard Bearer + JSON patterns.
My actual recommendation though? None of them alone.
If I were architecting a notification system, I'd wire up Courier's API and configure Postmark as the email provider behind it. One API call handles email today, and when the requirements expand to SMS, push, Slack, or in-app (and they will), I don't have to rearchitect anything. Courier's send endpoint is the simplest of all:
Copied!
curl -X POST https://api.courier.com/send \-H "Authorization: Bearer $COURIER_API_KEY" \-H "Content-Type: application/json" \-d '{"message":{"to":{"email":"user@example.com"},"template":"VERIFY","data":{"code":"847291"}}}'
One endpoint. One auth header. Template logic, channel routing, provider failover, and delivery tracking all handled by the platform. From an agent's perspective, that's the least code to maintain and the fewest decisions to make at the application layer.
For most product teams: Courier with Postmark as your primary email provider. You get Postmark's delivery speed, Courier's multi-channel orchestration, and you're set up for whatever comes next without rearchitecting.
For cost-sensitive, high-volume senders: Courier with Amazon SES for bulk and Postmark for time-critical messages. Route based on notification type and let Courier handle the split.
For React/Next.js teams: Courier with Resend. Use React Email for your templates, Courier for routing and orchestration.
For teams already deep in Twilio: Courier with SendGrid. The Segment integration creates event-driven workflows, and Courier adds the multi-channel layer that SendGrid alone can't provide.
The point isn't that any single email provider is wrong. It's that email infrastructure is rarely just email for long. Start with the architecture that doesn't force you to rearchitect when the next channel requirement shows up.

I Built an AI Board Member in Cursor. Here's How.
Every month I send a board update—and every month I wish someone would tell me what’s wrong before it goes out. Investors are busy, feedback comes late, and most people soften the punch. So I built an AI board member using Cursor Rules: three markdown files, a basic project layout, and no plugins. Drop in your board deck, get an immediate review, and walk into the meeting with fewer surprises.
By Thomas Schiavone
February 20, 2026

The Courier MCP Server Is Open Source. Here's How It Actually Works.
Courier's MCP server is open source at github.com/trycourier/courier-mcp. It connects AI coding tools like Cursor and Claude Code to your Courier account so they can send messages, manage users, and install SDKs without hallucinating API details. This post walks through the actual codebase: how 16 tool classes are registered (and how a config allowlist gates most of them), why we pull installation guides from GitHub at runtime instead of bundling them, how the DocsTools class generates live JWTs alongside setup instructions, and what the SdkContextTools class does in the repo to prevent v7/v8 SDK conflicts (even though it isn't wired into the server yet).
By Mike Miller
February 06, 2026
© 2026 Courier. All rights reserved.