Resend ships one of the tightest developer stories in the ESP market: a single JSON REST base at api.resend.com, 10 first-party SDKs kept on the same release cadence, and a first-party remote MCP server at mcp.resend.com/mcp that installs into Claude, Cursor, Codex and GitHub Copilot in one click. If your evaluation shortlist includes Postmark, Mailgun or Amazon SES, Resend is the option that treats the API and the AI-agent surface as the primary product rather than a bolt-on.
This tab is the API and MCP reference for buyers, platform engineers and AI-agent integrators. It covers the authentication model (Bearer plus OAuth 2.1 with PKCE), the 10 requests/second per-team rate limit, the 19 documented endpoint groups, the official SDK matrix, canonical Python and Node snippets, five gotchas Resend teams hit in production, and the recent changelog events that actually change how you integrate.
Resend is one of the very few transactional ESPs that treats Model Context Protocol as a first-party surface rather than a community experiment. The hosted server exposes almost the entire REST API to any MCP client, and the same code ships as an open-source npm package for teams that need to run it inside their own VPC.
Resend hosts a first-party remote MCP server at https://mcp.resend.com/mcp. Since August 6, 2026 the endpoint supports the stateless MCP protocol, and since August 13, 2026 Resend implements the Agent Plugins Standard for one-click install. Authentication uses OAuth 2.1 with PKCE or a raw re_ API key. Compare to Amazon SES and Mailgun, which still have no first-party MCP server as of August 2026.
Two official surfaces (hosted and self-run), one containerized distribution in the Docker MCP Catalog, and a small community layer.
Resend’s own hosted remote MCP server. OAuth 2.1 + PKCE or API-key auth. Exposes emails, contacts, broadcasts, domains, segments, topics, contact properties, API keys and webhooks.
Same open-source code as the hosted server. Run locally with stdio or HTTP transport via npx -y resend-mcp for VPC-scoped or air-gapped deployments.
Containerized distribution of the official Resend MCP server, published to the Docker MCP Catalog for orchestrated deployments.
Community MCP server that wraps the Resend email API. Predates the official server; useful as a reference implementation.
Performance-oriented community MCP server for Resend. Prefer the official server unless you have a specific latency reason to fork.
Why buyers should care. Two things stand out. First, the Resend MCP surface exposes almost the same resources as the REST API, so any AI agent can compose a broadcast, verify a domain or read webhooks without a custom wrapper. Second, OAuth 2.1 with PKCE and Agent Plugins Standard support mean you can grant scoped access to a Claude or Cursor session without minting long-lived re_ keys, a real security posture upgrade over API-key-only providers.
The Resend REST API is a single, unversioned surface today. Every path lives under one base URL, every response is JSON, and Resend has publicly committed to calendar-based header versioning rather than URL path bumps, so integration code written today should not break at the next major release.
| Base URL | https://api.resend.com |
| Response format | JSON only; no XML or form-encoded surface |
| Versioning | Unversioned URL today. Calendar-based header versioning planned |
| Authentication | Bearer re_ API key, or OAuth 2.1 + PKCE |
| Pagination | Cursor-based on list endpoints: limit + after / before |
| Batch send | Up to 100 emails per POST /emails/batch call |
| Message size cap | 40 MB total, including Base64-encoded attachments |
| Recipients per email | Up to 50 addresses in the to field |
| OpenAPI spec | Published at resend.com/docs/api-reference |
The API is organized around 19 resource groups covering transactional email, batch send, inbound routing, broadcasts, contacts, segments, topics, templates, domain verification, API keys, suppressions, webhooks, request logs and OAuth. That coverage is comparable to Postmark‘s server-oriented surface while pulling in marketing primitives (segments, topics, broadcasts) that are typically split between two products at legacy vendors.
Resend offers two authentication modes. Bearer tokens are the default for server-to-server integrations; OAuth 2.1 with PKCE is the newer flow purpose-built for third-party apps and AI agents that must not hold static credentials.
Every API request must carry an Authorization: Bearer re_xxxxxxxxx header. API keys are created under Settings › API Keys, are scoped to a single team, and support two permission tiers: Full access and Sending access (send-only, no key/domain management). Keys are shown once at creation and never again, store them in a secret manager immediately.
curl https://api.resend.com/emails
-H "Authorization: Bearer re_xxxxxxxxx"
-H "Content-Type: application/json"
-d '{
"from": "Acme <onboarding@resend.dev>",
"to": ["delivered@resend.dev"],
"subject": "Hello from Resend",
"html": "<strong>It works</strong>"
}'Since July 13, 2026 Resend supports OAuth 2.1 + PKCE with dynamic client registration, exposed under /oauth/*. This is the recommended path when a third-party app, an AI agent, or a Claude MCP connector needs delegated access to a Resend team without long-lived API keys. The flow follows the standard: register a client, redirect the user to Resend for consent, exchange the code + PKCE verifier for a scoped access token, and refresh silently.
Scope caveat. OAuth scopes are coarser than API-key permission tiers today, expect the granularity to expand through 2026. If you need tight resource-level scoping (send-only, domain-read-only, etc.), issue a scoped Sending access API key from your own backend rather than passing the OAuth token straight through to a client.
Resend publishes a single per-team default with headroom available on request. The cap is enforced at the team level, not per API key, which is a common surprise for teams that assume sharding keys will multiply throughput.
| Limit | Default | Notes |
|---|---|---|
| API requests per team | 10 req/sec (600 rpm) | Shared across every API key on the team; higher limits on request |
| Batch send size | 100 emails per call | Via POST /emails/batch |
| Recipients per email | 50 addresses | In the to field per single email |
| Message payload | 40 MB | Total request size, including Base64-encoded attachments |
| Deliverability floors | Bounce < 4%, spam < 0.08% | Exceeding either triggers throttling and account review |
| Free plan quota | 100/day, 3,000/month | Both caps enforced in parallel |
| Paid overage cap | 5x monthly quota | Hard ceiling on soft overage |
Workaround pattern. Every response carries ratelimit-remaining and retry-after headers. The standard shape is a client-side queue (Cloudflare Queues, Upstash QStash, Trigger.dev, Inngest) that dispatches sends at a steady 8-9 req/sec, catches 429s and backs off with jitter. Batch sends via /emails/batch collapse 100 sends into a single request and are the fastest way to stay under the ceiling for bulk workloads. If you need a per-hour ceiling higher than 36,000 theoretical calls, open a support request. Resend does raise the cap for verified teams.
Resend maintains 10 first-party SDKs under the github.com/resend org, all versioned in lock-step with the REST API. The Node.js SDK is the primary reference; Laravel and the Vercel AI Chat SDK adapter deserve special mention because they wire Resend into the framework’s own abstractions (mail transport and streaming chat, respectively) rather than exposing a raw client.
| Language | Package | Install | Repository |
|---|---|---|---|
| Node.js / TypeScript | resend | npm install resend | resend/resend-node |
| Python | resend | pip install resend | resend/resend-python |
| PHP | resend/resend-php | composer require resend/resend-php | resend/resend-php |
| Laravel | resend/resend-laravel | composer require resend/resend-laravel | resend/resend-laravel |
| Ruby | resend | gem install resend | resend/resend-ruby |
| Go | github.com/resend/resend-go/v2 | go get github.com/resend/resend-go/v2 | resend/resend-go |
| Java | com.resend:resend-java | Add to Maven / Gradle | resend/resend-java |
| Rust | resend-rs | cargo add resend-rs | resend/resend-rust |
| .NET / C# | Resend | dotnet add package Resend | resend/resend-dotnet |
| Chat SDK adapter | resend-chat-sdk | npm install resend-chat-sdk | resend/resend-chat-sdk |
React Email pairing. Resend’s sister project React Email is the reason many teams pick Resend in the first place: author templates as React components, preview locally, and pass them straight into resend.emails.send({ react: <Welcome /> }). No JSON-in-a-string template DSL, no separate template repository to keep in sync. It is the closest thing to a modern, framework-native templating story any transactional ESP ships today.
Because Resend publishes a machine-readable OpenAPI spec, community SDKs auto-generate cleanly. Search for resend- on npm, PyPI and crates.io. Notable third-party wrappers include Deno-first HTTP clients, Elixir libraries, and Cloudflare Workers helpers. When picking a community SDK, verify the last commit is within 90 days and that it tracks the current OpenAPI hash, stale wrappers often miss the newer /broadcasts, /segments, /topics and /contact-properties resources.
The full REST surface exposes 19 resource groups. Reference paths are relative to the base URL https://api.resend.com. The canonical documentation lives at resend.com/docs/api-reference.
| Resource | Methods | Description |
|---|---|---|
| Emails /emails | POST, GET | Send a transactional email or list previously sent emails. |
| Emails (single) /emails/{id} | GET, PATCH, DELETE | Retrieve, reschedule, or cancel a specific email. |
| Batch emails /emails/batch | POST | Send up to 100 emails in a single request. |
| Email attachments /emails/{id}/attachments | GET | List or fetch attachments for a previously sent email. |
| Email metrics /emails/metrics | GET | Account-level delivery, bounce, complaint and engagement metrics. |
| Received emails /emails/received | GET | List and fetch inbound emails and their attachments. |
| Broadcasts /broadcasts | POST, GET | Create and list broadcast campaigns. |
| Broadcasts (single) /broadcasts/{id} | GET, PATCH, DELETE | Read, update or delete a broadcast; sub-resources for send, cancel, recipients and links. |
| Templates /templates | POST, GET | Create and list reusable email templates. |
| Contacts /contacts | POST, GET | Manage contacts within an audience. |
| Contact properties /contact-properties | POST, GET | Define custom contact properties for personalization tokens. |
| Segments /segments | POST, GET, DELETE | Create and manage dynamic audience segments. |
| Topics /topics | POST, GET | Manage subscription topics and recipient preferences. |
| Domains /domains | POST, GET | Add, verify and manage sending domains. |
| API keys /api-keys | POST, GET, DELETE | Create and revoke API keys programmatically. |
| Suppressions /suppressions | POST, GET, DELETE | Manage suppressed addresses (single or batch). |
| Webhooks /webhooks | POST, GET, PATCH, DELETE | Configure webhook endpoints and inspect delivered events. |
| Logs /logs | GET | Inspect API request logs, payloads and latency for debugging. |
| OAuth /oauth/* | POST, GET | OAuth 2.1 + PKCE flow for third-party Resend apps and agents. |
Two canonical snippets: send a transactional email and add a contact to an audience. Both patterns transfer directly to the other 10 official SDKs; only the client instantiation differs.
# pip install resend
import os
import resend
resend.api_key = os.environ["RESEND_API_KEY"]
# 1) Send a transactional email
params: resend.Emails.SendParams = {
"from": "Acme <onboarding@resend.dev>",
"to": ["delivered@resend.dev"],
"subject": "Hello from Resend",
"html": "<strong>It works</strong>",
}
email = resend.Emails.send(params)
print("sent:", email["id"])
# 2) Add a contact to an audience
contact = resend.Contacts.create({
"audience_id": "aud_xxxxxxxx",
"email": "reader@example.com",
"first_name": "Alaa",
"unsubscribed": False,
})
print("contact:", contact["id"])
// npm install resend
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
async function main() {
// 1) Send an email
const { data, error } = await resend.emails.send({
from: 'Acme <onboarding@resend.dev>',
to: ['delivered@resend.dev'],
subject: 'Hello from Resend',
html: '<strong>It works</strong>',
});
if (error) return console.error(error);
console.log('sent id:', data.id);
// 2) Create a contact
const contact = await resend.contacts.create({
audienceId: 'aud_xxxxxxxx',
email: 'reader@example.com',
firstName: 'Alaa',
unsubscribed: false,
});
console.log('contact id:', contact.data?.id);
}
main();
resendUnlike most providers, the SMTP username is not your email or account ID, it is the fixed string resend. The password is your API key (re_...). New users often paste their email into the username field and get authentication failures that read as bad credentials rather than as a misconfiguration.
The 10 req/sec cap is applied at the team level and shared across every API key. Splitting keys will not raise your ceiling, you need to open a support request. Integrate the ratelimit-remaining and retry-after headers and queue with exponential backoff. Cloudflare Queues, Upstash QStash, Trigger.dev and Inngest are all common patterns.
Both quotas run in parallel on the free tier, sending 100 emails/day for 30 days will still trip the 3,000/month ceiling. The free plan also limits you to 1 verified domain, so multi-tenant setups need the $20 Pro plan (10 domains) at minimum. Compare to Mailgun‘s and SendGrid‘s pay-as-you-go pricing.
Resend enforces deliverability floors: bounce rate must stay under 4% and complaint (spam) rate under 0.08%. Because Resend rides on Amazon SES infrastructure, exceeding either metric triggers throttling and can lead to account review or suspension, clean lists and double opt-in are not optional at scale. See our Amazon SES guide for the underlying reputation model.
The 40 MB size limit is measured AFTER Base64 encoding, which inflates raw bytes by ~33%. Effective safe payload is roughly 28-30 MB of raw attachment content. For larger files, host the asset and send a signed URL instead of embedding it.
Resend maintains a public, dated changelog. The events below materially change how you integrate as of August 2026.
cancel endpoint. Scheduled or queued broadcasts can now be cancelled directly via the API instead of only through the dashboard.mcp.resend.com/mcp now supports the stateless MCP protocol.re_ API keys committed to GitHub are detected, revoked and reported to the owning team.Full history at resend.com/changelog.
The base URL is https://api.resend.com. Authenticate with a Bearer token: Authorization: Bearer re_xxxxxxxxx. For third-party apps, Resend also supports OAuth 2.1 with PKCE and dynamic client registration since July 2026.
Resend ships 10 first-party SDKs: Node.js/TypeScript, Python, PHP, a Laravel mail transport, Ruby, Go (v2), Java, Rust (resend-rs), .NET/C#, and a Vercel AI Chat SDK adapter. All are hosted under the github.com/resend org and are actively maintained.
POST /emails/batch accepts up to 100 emails per call. Each item in the array is a full email payload (from, to, subject, html or react). The endpoint returns per-email IDs and does not fail the whole batch if a single item errors.
Use /contacts to add or update contacts, /contact-properties to define custom fields for personalization, /segments to build dynamic audiences, and /topics to give recipients granular subscription preferences. All four resources plug into the Broadcasts API for campaign sends.
Yes. Resend hosts a first-party remote MCP server at https://mcp.resend.com/mcp (OAuth 2.1 + PKCE and API-key auth) and publishes the same code as resend-mcp on npm. It exposes emails, contacts, broadcasts, domains, segments, topics, contact properties, API keys and webhooks; one-click install is available for Claude, Cursor, Codex, Devin and GitHub Copilot.
/webhooks lets you register signed HTTPS endpoints for delivery, bounce, complaint, open, click and inbound events. Every API call is captured under /logs with the request payload, response, latency and rate-limit headers, useful for debugging integrations without redeploying instrumentation.
This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.