AgentiSend API docs
AgentiSend is a transactional email API for applications and AI agents: Resend-compatible requests, a send budget on every key, a kill switch, and refusals that name the fix. 252 operations, 122 error codes and 51 event types, generated from the API itself at build. Version 0.1.0.
Guides
Start here
- Quickstart — Verify a domain, create a key, send the first email — in Node, Python or curl.
- Agents — MCP and the CLI — Connect Claude Code, Cursor, Windsurf, VS Code or any remote-MCP client to the same API your code uses.
- SDKs — Install the Node, Python, PHP or Go client, or the MCP server and the CLI, and send one email.
- API conventions — Auth, the error envelope, idempotency, rate limits, pagination and request ids, with the numbers the API enforces.
- Billing — What counts as an email, monthly, yearly and lifetime plans, plan changes, overage, failed payments, cancellation and closing.
- Support — Open a request from the console, attach files, follow the thread there and by email, and reopen or rate it once resolved.
Control plane
- Budgets and the kill switch — Per-key spend ceilings, what happens when one is reached, and the one request that stops everything.
- Approvals — When a send waits for a person, how the queue behaves, and what an agent sees while it waits.
- Deliverability — The published thresholds, what happens at each one, and how to read the reputation panel.
- Trust and enforcement — The enforcement ladder, what each rung does, how to appeal, and what we will not do.
Integrating
- Webhooks — Signing, verification, the retry schedule, replay, and what happens to a dead letter.
- Domains and DNS — The records to publish, what verification checks, the US / EU region choice, TLS mode, and the customer return-path host.
- Templates — Storing a template, rendering it, versioning, and why the variables are declared.
- Migrating from Resend — What stays the same, how error names map, and what differs. Two things behave differently on purpose: the region default and enforced key budgets.
- Audience — Contacts, segments and topics in the console, and what an unsubscribe is allowed to undo.
- Broadcasts — One message to one segment, drafted, optionally scheduled, snapshotted at send, with a delivery state for every member.
- Automations — A trigger and ordered steps, or a graph with delays, waits and conditions; a version saved on enable, and every run recorded step by step.
- Receiving and replying — Read received mail and thread your replies. A reply to mail that arrived somewhere else threads too, with headers copied from it.
- Test addresses — Every address at simulator.agentisend.com, the events each one produces, what gets suppressed, and the Resend test addresses they replace.
- AgentiSend MCP server — send email from Claude, Cursor and any MCP client — Every tool with the scopes it needs, the rate-limit table, the JSON-RPC error codes, and what an agent cannot do.
- Migrating from Postmark — How a Postmark payload and webhook map onto this API, and what is refused on day one.
- Migrating from SendGrid — How a SendGrid mail-send payload maps onto this API, and what is refused on day one.
- Migrating from Mailgun — How a Mailgun HTTP send maps onto this API, and what is refused on day one.
- Migrating from Amazon SES — How an Amazon SES SendEmail call maps onto this API, and what is refused on day one.
- Send email from n8n — The AgentiSend node and trigger for n8n: send and check email from a workflow or an AI Agent, and start workflows on delivery, bounce, open and click.
Frameworks and agents
- Send email from Next.js — A route handler and a Server Action that send through AgentiSend, with the key on the server and an idempotency key on every send.
- Send email from Supabase — Supabase's Send Email Hook, so sign-up, sign-in-link and password-recovery mail leaves through your own verified domain.
- Send email from Better Auth — The sendVerificationEmail and sendResetPassword callbacks, sending through AgentiSend with an idempotency key built from the token.
- Send email from Auth.js — A custom sendVerificationRequest so the sign-in link goes out over HTTPS instead of an SMTP connection your host may not allow.
- Send email from Hono — One POST route that sends a transactional email, the same file on Cloudflare Workers, Deno, Bun and Node.
- Send email from Express — A POST route on an app you can mount anywhere, returning the message id or the code and fix of a refusal.
- Send email from SvelteKit — A contact form whose action runs on the server, so the key stays there and the form works without JavaScript.
- An AI agent with a budget and a loop guard — A key scoped to sending, a ceiling, and the loop guard refusing the fourth identical send and holding it for a person.
- Send email from Python — The same three calls from Python with nothing installed: a key scoped to sending, a ceiling, and the loop guard refusing a repeat.
- Send email from a Vercel AI SDK agent — A sendEmail tool for the AI SDK that sends through the agent's own budgeted key and hands a refusal back to the model as code and fix.
- Send email from a LangChain.js agent — A send_email tool built with tool() from @langchain/core/tools that sends through the agent's own budgeted key and hands a refusal back to the model as code and fix.
- Send email from Fastify — A Fastify POST route whose JSON schema refuses a bad address before the handler runs, sending one invoice notice per invoice with an idempotency key.
- Send email from Astro — An Astro API route that confirms a waitlist sign-up from a plain form post, refusing a malformed address before the API is called.
- Send email from Nuxt — A Nitro server route under server/api that sends one booking confirmation per booking, refusing a malformed address before the API is called.
- Send email from React Router — A React Router action, formerly Remix, that emails a download link to the person who asked for it and refuses a malformed address before the API is called.
- Send email from NestJS — A NestJS controller and service sending one order confirmation per order, refusing a malformed address first and answering a refusal with its code and fix.
- Send email from FastAPI — A FastAPI POST route that checks the address, sends with an idempotency key, and returns the message id or the code and fix of a refusal.
- Send email from Flask — A Flask POST route that checks the address, sends one receipt per order with an idempotency key, and returns the message id or the code and fix of a refusal.
- Send email from Django — A Django view that checks the address, sends one shipping notice per order with an idempotency key, and returns the message id or the code and fix of a refusal.
- Send email from Node.js — A node:http POST route that checks the address, sends one receipt with an idempotency key, and returns the id or the code and fix.
- Send email from Go — A Go program that posts one invoice with net/http, an idempotency key, and the code and fix of a refusal.
- Send email from PHP — A PHP function that posts one receipt with streams, an idempotency key, and the code and fix of a refusal.
- Send email from Laravel — A Laravel controller method that posts one shipping notice with PHP streams, an idempotency key, and the refusal's code and fix.
- Send email from Rails — A Rails controller method that posts one receipt with Net::HTTP, an idempotency key, and the refusal's code and fix.
- Send email from Remix — A Remix action that emails one receipt from a form post, with an idempotency key, and returns the id or the code and fix.
- Send email from Bun — A Bun request handler that posts one receipt with fetch, an idempotency key, and the code and fix of a refusal.
- Send email from Deno — A Deno request handler that posts one deploy notice with fetch, an idempotency key, and the code and fix of a refusal.
- Send email from the Claude Agent SDK — AgentiSend mail from the Claude Agent SDK goes through one send_email tool on toolRunner, and a refusal comes back as code and fix.
- Send email from the OpenAI Agents SDK — AgentiSend mail from the OpenAI Agents SDK goes through one function_tool invoked with on_invoke_tool, and a refusal comes back as code and fix.
- Send email from CrewAI — AgentiSend mail from CrewAI goes through one tool called with run, and a refusal comes back as code and fix for the crew to stop on.
- Send email from Mastra — AgentiSend mail from Mastra goes through one createTool on an Agent, and execute returns a refusal as code and fix instead of throwing.
- Send email from LangChain for Python — AgentiSend mail from LangChain for Python goes through one @tool invoked twice, and the second call returns a refusal as code and fix.
- Send email with Vercel Functions — A Vercel POST function that sends with the Node SDK and replays a retried call for the same recipient.
- Send email with Cloudflare Workers — A Cloudflare Workers fetch handler that sends with the Node SDK, reading the key from the binding.
- Send email with AWS Lambda — An AWS Lambda handler that sends with the Node SDK and returns the message id from an API Gateway event.
- Send email with Ruby — A Ruby script that posts one statement with Net::HTTP, an idempotency key, and the refusal code and fix.
- Send email with Rust — A Rust binary that posts one shipment notice with ureq, an idempotency key, and the refusal code and fix.
- Send email with Java — A Java program that posts one ticket with java.net.http, an idempotency key, and the refusal code and fix.
- Send email with .NET — A .NET program that posts one booking with HttpClient, an idempotency key, and the refusal code and fix.
- Send email with Elixir — An Elixir script that posts one signup with :httpc, an idempotency key, and the refusal code and fix.
- Send email with TanStack Start — A TanStack Start server function that sends one form receipt with the Node SDK and replays a retried submit.
- Send email with RedwoodJS — A RedwoodJS service function that sends one note with the Node SDK and returns the message id or the refusal.
- Send email with Railway — A Node server you deploy on Railway, with the key in a service variable and one POST /send route.
- Send email with Encore (TypeScript) — An Encore.ts endpoint that sends one workspace notice with the Node SDK and an idempotency key.
- Send email with Encore (Go) — An Encore Go API function that posts one welcome note to POST /emails with net/http.
- Send email with Supabase Edge Functions — A Supabase Edge Function that posts one invite with fetch. This is not the Send Email Hook.
- Send email with Deno Deploy — A Deno Deploy app whose Deno.serve handler posts one preview notice. Separate from the Deno runtime guide.
- Send email with Symfony — A Symfony controller action that posts one invoice notice to POST /emails with PHP streams.
- Send email with Sinatra — A Sinatra POST block that sends one booking by calling a method which posts with Net::HTTP.
- Send email with Axum — An Axum POST handler that posts one release note to POST /emails. The binary uses ureq for HTTP and TLS.
- Send email with Phoenix — A Phoenix controller action that posts one booking notice through :httpc, which ships with Erlang.
- Send email with Auth0 — An Auth0 custom email provider Action that posts the notification to POST /emails and returns code and fix.
Console
- API keys — Create, rotate and delete keys on the API keys screen. A viewer can read the list. Creating one needs an admin or an owner.
- Team — Invite people, change a role and remove a member from Settings, Team. An API key cannot make those changes. A signed-in person does.
- Security — Turn on a second factor, copy the recovery codes once, and sign out other sessions. These calls are not in the published API reference.
- Billing and overage — See the plan, start checkout, open the billing portal, and set an overage ceiling. Changing any of those needs the owner, signed in.
- Notifications — Choose which conditions ring the bell and which send mail. The bell lists open conditions. Marking one read does not end it.
- Agents — Pause every key, resume a fleet pause, decide a held send, and edit a budget. Resume and approvals need a signed-in person.
- Logs — Read this account's API requests: method, route, status, duration and the refusal code. Request and response bodies are not stored.
- Metrics — Counts and rates for 24 hours, 7 days, 30 days or 90 days, by domain and by key. Rate tiles stay hidden when the window is small.
Questions
- Why was my email delayed?
- Why did my email bounce?
- What does domain_not_verified mean?
- Does AgentiSend have a free plan?
- How do I test email sending without delivering anything?
- How do I send email from a Cloudflare Worker?
- How do I send email from AWS Lambda?
- How do I stop an AI agent from sending too many emails?
- How do I verify a sending domain on Cloudflare?
- How do I verify a sending domain on Namecheap?
- How do I verify a sending domain on GoDaddy?
- How do I verify a sending domain on Route 53?
- How do I verify a sending domain on Google Domains?
- How do I verify a sending domain on Porkbun?
- How do I verify a sending domain on Hostinger?
- How do I schedule an email to send later?
- How do I cancel a scheduled email?
- How do I send many emails in one request?
- How do I send an email with an attachment?
- How do I set reply-to, cc and bcc on an email?
- How do I stop my code from sending the same email twice?
- How do I know if my email was delivered?
- How do I handle rate limits?
- How do I send an email from a template?
- How do I tag emails and find them later?
- How do I verify a webhook signature?
- Why did my webhook stop receiving events?
- How do I replay webhook events?
- How do I remove an address from the suppression list?
- How do I add an unsubscribe link to my emails?
- How do I export my email data?
- How do I rotate an API key without downtime?
- How long does AgentiSend keep my emails?
- Can I keep my email data in the EU?
- How do I send email from Node.js?
- Why are my emails going to spam?
- Why does my email say delivered but the recipient did not get it?
- Should I send email from a subdomain or the root domain?
- What does account_sandboxed mean?
- How do I set up DMARC for my sending domain?
- Can I have two SPF records on one domain?
- How do I put a spending limit on an AI agent that sends email?
- How do I require human approval before an AI agent sends email?
- How do I see everything my AI agent sent?
- How do I stop prompt injection in email my agent reads?
- How do I pause an AI agent that is sending email?
- Which API key permission should an AI agent have?
- How do I restrict an API key to one domain?
- How many recipients can one email have?
- How do I revoke an AI assistant connection?
- How do I find out why an email was not sent?
- How do I check my sending reputation?
- What does partially_verified mean for a domain?
- Why did my domain verification fail?
- How long does domain verification take?
- How do I wait for a domain to verify from a script?
- What is the return-path record for?
- What does a spam complaint do to my account?
- How do I get notified when domain verification breaks?
- What does approval_required mean?
- What does kill_switch_active mean?
- What does agent_budget_exceeded mean?
- What does rate_limit_exceeded mean?
- What does suppressed_recipient mean?
- What does plan_limit_reached mean?
- What does restricted_api_key mean?
- What does idempotency_payload_mismatch mean?
- How do I invite a teammate and set their role?
- What does dkim_key_mismatch mean?
- How do I control account notifications?
- What does spf_conflict mean?
- How do I close my account?
- What does dns_unreachable mean?
- What does domain_check_window_expired mean?
- What happens when I hit my plan limit?
- How do I see my usage?
- What does rate_ceiling_exceeded mean?
- How do I let an AI agent send email?
- How do I send an email when a custom event happens?
- How do I create a segment of contacts?
- Which email APIs have a hosted MCP server?
- Send email from Claude
- Send email from Zed
- Send email from OpenCode
- Send email from Cline
- Can an AI agent receive email?
- How do I limit who can email my AI agent?
- Is AgentiSend safe to use in production?
- How do I get email events without a public webhook URL?
- How do I verify a sending domain on Squarespace?
- How do I verify a sending domain on Wix?
- How do I verify a sending domain on IONOS?
- How do I verify a sending domain on OVHcloud?
- How do I verify a sending domain on Gandi?
- How do I verify a sending domain on DigitalOcean?
- How do I verify a sending domain on Vercel?
- How do I verify a sending domain on Netlify?
- Can an AI agent sign up for AgentiSend by itself?
- How do I receive email at my own domain?
- How do I read a reply without the quoted history?
- How do I get the text of an email attachment?
- How do I hold suspicious email until a person reviews it?
- What does inbound_verdict review mean?
- How do I reply to an email my agent received?
- How does an AI agent read a one-time code from email?
- How do I give each AI agent its own email address?
- How do I hand DNS setup to the person who owns the domain?
- What does agent_unconfirmed mean?
- What does recipient_ramp mean?
- How do I block a sender from emailing my agent?
- Email API with spending limits for AI agents
- Resend alternative pricing: AgentiSend plan by plan
- Stop an AI agent sending emails in a loop
- Resend-compatible email API: switch with one import
- Transactional email API for AI agents
Every endpoint
Each row carries the anchor the product links to. An error whose fix names an endpoint sends the reader to that anchor here.
accounts
- GET /accountThis account: lifecycle status, the reason it is in that state, and when it was created.
- PATCH /accountChange account settings.
- DELETE /accountClose this account: keys stop now.
- GET /account/exportA zip of this account's data, with a row count for every file in manifest.json.
- PATCH /account/onboardingConsole: the onboarding answers — your name, the company (which becomes the account name), the website, what you will send and roughly how much.
agent-actions
agents
api-keys
appsumo
automations
- GET /automationsEvery automation on the account, oldest first.
- POST /automationsCreate an automation: a trigger plus ordered steps (email, webhook, A/B split), or Resend’s graph of steps and connections (delay, wait for event, condition,…
- GET /automations/{id}One automation, with its steps and connections.
- PATCH /automations/{id}Rename, enable or disable an automation, or replace its definition.
- DELETE /automations/{id}Delete an automation, its versions and its run history.
- POST /automations/{id}/disableStop firing.
- POST /automations/{id}/duplicateCopy an automation, disabled, with " (copy)" after its name.
- POST /automations/{id}/enableSnapshot trigger+steps as an immutable version and start firing.
- GET /automations/{id}/runsEvery time this automation fired, newest first — the answer to "did it run?", which the engine used to throw away.
- GET /automations/{id}/runs/{run_id}One run with every step: what it did, what it returned, and the sentence for the ones that failed.
- POST /automations/{id}/stopStop an automation: no new runs start.
- GET /automations/{id}/versionsEvery immutable version, oldest first.
- GET /eventsEvery custom event this account has declared, with its typed schema and when it was last seen.
- POST /eventsIngest a custom event, or declare one.
- POST /events/sendSend a custom event for one contact, by contact_id or email.
- GET /events/{id}One event definition.
- PATCH /events/{id}Declare or re-declare an event’s fields.
- DELETE /events/{id}Forget an event definition.
billing
- POST /billing/checkoutConsole: start a Stripe Checkout for a tier, term and volume.
- POST /billing/checkout/lifetimeConsole: start a one-time Stripe Checkout for a lifetime plan, or an upgrade to a larger one for the difference.
- GET /billing/invoicesInvoices and one-time receipts for this account, newest first.
- GET /billing/invoices/openUnpaid invoices for this account, oldest first, and the total still due.
- POST /billing/invoices/{id}/openedRecord that this account opened an invoice or its PDF.
- PUT /billing/overageConsole: turn opt-in overage on (with a ceiling of extra emails per period) or off.
- GET /billing/planThe plan in force (Free until one is bought), the plans, volumes and terms on offer, and what the signed-in person may buy.
- POST /billing/planConsole: choose Free on the plan step.
- POST /billing/portalConsole: open the Stripe customer portal — its home (card, invoices), or straight on the confirm page of one plan change.
- GET /billing/subscriptionConsole: the signed-in account’s plan and subscription state.
- POST /webhooks/stripeStripe → AgentiSend: signature-verified, deduplicated by event id.
broadcasts
- GET /broadcastsEvery broadcast, newest first — archived included.
- POST /broadcastsDraft a broadcast to a segment.
- GET /broadcasts/{id}One broadcast.
- PATCH /broadcasts/{id}Edit an unsent broadcast, or rename ANY one.
- DELETE /broadcasts/{id}Delete a draft broadcast.
- POST /broadcasts/{id}/archiveArchive — reversible, any time, sent or draft.
- POST /broadcasts/{id}/cancelCancel a scheduled broadcast, or stop one that is still sending.
- GET /broadcasts/{id}/clicked-linksEvery link clicked in a broadcast, most clicked first, with total and unique clicks.
- POST /broadcasts/{id}/duplicateCopy a broadcast into a new draft: From, subject, content or template, segment, reply_to, preview_text and topic_id.
- GET /broadcasts/{id}/messagesPer-member delivery state for this broadcast.
- GET /broadcasts/{id}/previewRender this broadcast the way a recipient would see it.
- GET /broadcasts/{id}/recipientsThe recipients of a broadcast for one event type: sent, delivered, opened, clicked, bounced, complained, unsubscribed or suppressed.
- POST /broadcasts/{id}/sendSend now, or schedule it with scheduled_at/scheduledAt — the same time grammar as PATCH /broadcasts/:id, refused if it is in the past.
- GET /broadcasts/{id}/statsSent, delivered, opened, clicked, bounced, complained and unsubscribed totals for one broadcast.
contacts
- GET /audiences/{audienceId}/contactsContacts in this audience, the same list as GET /segments/{id}/contacts.
- POST /audiences/{audienceId}/contactsCreate or update a contact and add them to this audience.
- GET /audiences/{audienceId}/contacts/{id}One contact in this audience.
- PATCH /audiences/{audienceId}/contacts/{id}Edit one contact in this audience.
- DELETE /audiences/{audienceId}/contacts/{id}Remove a contact from this audience and leave the contact on the account.
- GET /contact-propertiesProperties declared with POST /contact-properties, and the property names contacts already hold.
- POST /contact-propertiesDeclare a contact property: its key, its type (string or number) and an optional fallback_value that a broadcast uses for a contact with no value of its own.
- GET /contact-properties/{id}One contact property by id, with its fallback_value.
- PATCH /contact-properties/{id}Change a property’s fallback_value.
- DELETE /contact-properties/{id}Remove a declared property.
- GET /contactsList contacts, newest first.
- POST /contactsCreate or update a contact by email.
- POST /contacts/batchUpdate up to 1,000 contacts that already exist.
- GET /contacts/importsList contact imports, newest first.
- POST /contacts/importsCreate and update contacts from a CSV, sent as a multipart file or as JSON text.
- GET /contacts/imports/{id}One contact import: its status and how many rows were created, updated, skipped and failed.
- GET /contacts/{id}One contact with its properties.
- PATCH /contacts/{id}Edit one contact by id or email.
- DELETE /contacts/{id}Delete one contact and its properties.
- POST /contacts/{id}/resubscribeMark a contact active again after they opt back in.
- GET /contacts/{id}/segmentsSegments this contact is in: those whose rules match it and those it was added to.
- POST /contacts/{id}/segments/{segment_id}Add a contact to a segment.
- DELETE /contacts/{id}/segments/{segment_id}Remove a contact you added to a segment.
- GET /contacts/{id}/topicsWhat this contact has said about every topic.
- PATCH /contacts/{id}/topicsRecord this contact’s answer for one or more topics.
- GET /segments/{id}/contactsContacts in this segment: those its rules match and those added to it.
dedicated-ips
- GET /dedicated-ipsThis account dedicated IPs with live warmup percentages.
- POST /dedicated-ipsRefused: a dedicated IP is assigned by us from the addresses we send from — ask support.
- GET /dedicated-ips/rampThe PUBLISHED warmup curve — exactly how volume moves and when.
- GET /dedicated-ips/route-decision/{messageId}Which route this message would take RIGHT NOW — reproducible, the same math the send path uses.
- DELETE /dedicated-ips/{id}Release a dedicated IP.
deliverability
- GET /deliverability/dmarcAuthentication reports for verified domains.
- GET /deliverability/domainsEvery sending domain with its standing over the window, worst first — the failing domain is the first row, not one you have to find.
- GET /deliverability/domains/{id}Per-domain reputation: live rates over the rolling window, daily snapshots, the thresholds those rates are judged against, the bounce breakdown by class with…
- POST /deliverability/domains/{id}/snapshotPersist today rates as a snapshot row.
domains
- GET /domainsList domains.
- POST /domainsRegister a sending domain.
- GET /domains/checkWhether POST /domains would accept this name, and the refusal it would give if not.
- POST /domains/claimStart a claim for a domain another account has verified.
- GET /domains/setup/{token}The DNS sheet for one setup link, with each record’s current status.
- GET /domains/{id}One domain, with the DNS to publish and what each record last resolved to.
- PATCH /domains/{id}Turn click or open tracking on, change the tracking subdomain, turn sending and receiving on or off, or choose whether suspect received mail is labeled or held.
- DELETE /domains/{id}Remove a domain and its records.
- GET /domains/{id}/claimThe latest claim for the placeholder domain a claim created.
- POST /domains/{id}/claim/verifyCheck the claim’s TXT record and, when it is there, run the ownership checks and move the domain.
- GET /domains/{id}/connectAlias of GET /domains/:id/setup.
- GET /domains/{id}/eventsNewest-first timeline for one domain.
- GET /domains/{id}/inbound-rulesSender rules for mail received at this domain.
- POST /domains/{id}/inbound-rulesAdd one sender rule.
- POST /domains/{id}/inbound-rules/batch/addAdd up to 500 sender rules.
- POST /domains/{id}/inbound-rules/batch/removeRemove up to 500 sender rules by pattern or id.
- DELETE /domains/{id}/inbound-rules/{rule_id}Remove one sender rule.
- GET /domains/{id}/setupOne-shot DNS setup: zone file, copy-paste commands, provider detection, and every record with host, zone, value_strings.
- POST /domains/{id}/setup-linkA page the person who owns DNS can open without signing in.
- DELETE /domains/{id}/setup-linkWithdraw the live setup link for this domain.
- POST /domains/{id}/verifyRe-check every record and update the domain’s status.
- GET /domains/{id}/waitLong-poll a domain until it is verified or failed, or until timeout (0–25 seconds).
emails
- GET /emailsList messages.
- POST /emailsSend an email.
- POST /emails/batchSend up to 500 emails.
- POST /emails/bulk-cancelCancel many emails at once: by explicit ids or every scheduled/queued email before a time.
- GET /emails/export.csvThe message log as CSV — yours, take it with you.
- POST /emails/lintDeliverability lint without sending: a 0-100 placement score plus every finding with its fix.
- POST /emails/preflightRun EVERY send gate without sending: domain, sandbox, trust, suppression, budget, loop, content, verifier.
- GET /emails/receivingMail received at this account’s domains, newest first.
- GET /emails/receiving/refusalsHow many messages each domain refused because of a sender rule, counted from the refusal event.
- GET /emails/receiving/threadsReceived mail grouped into threads by Message-ID / In-Reply-To / References, newest thread first.
- GET /emails/receiving/{id}One received email: headers, text and HTML bodies as data, and the attachments it carried.
- DELETE /emails/receiving/{id}Deletes one received email stored on this account, for good.
- GET /emails/receiving/{id}/attachmentsWhat this received email carried, each with a download link that needs no API key and works for an hour.
- GET /emails/receiving/{id}/attachments/{aid}One received attachment.
- GET /emails/receiving/{id}/rawThe stored RFC 5322 source, byte for byte.
- POST /emails/receiving/{id}/releaseRelease a held received message.
- POST /emails/receiving/{id}/replyReply to a received email.
- GET /emails/{id}Fetch one message with its current status and last event.
- PATCH /emails/{id}Move a scheduled email to a new time — the same act as POST /emails/:id/reschedule, under the verb a Resend integration already uses.
- DELETE /emails/{id}Delete one email you sent.
- GET /emails/{id}/attachmentsWhat this email carried, each with a download link that needs no API key and works for an hour.
- GET /emails/{id}/attachments/{aid}One attachment: the bytes exactly as they were sent, as an inert download, or its JSON view with a download link when the request asks for JSON.
- POST /emails/{id}/cancelCancel a scheduled or queued email.
- GET /emails/{id}/emlDownload this email as.eml.
- GET /emails/{id}/eventsEvery event recorded for one message, oldest first, with the provider detail.
- GET /emails/{id}/explainWhat happened to this email, the evidence, and the exact calls that fix it — machine-readable remediation.
- GET /emails/{id}/mimeThe exact RFC 5322 source of this email — what Resend never shows you.
- POST /emails/{id}/rescheduleMove an email to a new time.
limits
- GET /limits/keysThe fleet: every key with its budget, ceiling, consumption, identity and current loop state.
- GET /limits/keys/{id}Budget, ceiling and current consumption for one key.
- PATCH /limits/keys/{id}Set or clear this key’s period budget and per-minute ceiling.
- POST /limits/keys/{id}/killStop this key from sending, immediately.
- POST /limits/keys/{id}/resumeUndo the kill switch.
- POST /limits/kill-allPause every key on this account at once.
- POST /limits/resume-allUndo the global kill switch.
logs
meta
- GET /healthLiveness probe.
- GET /openapi.jsonOpenAPI 3.1 document generated from the same schemas that validate.
- GET /statusPublic per-component health.
- GET /status/historyDaily uptime per component for 90 days, in minutes.
- GET /tools/dns/{domain}The DNS records a sending domain needs, and the exact records to publish.
- GET /tools/spf/{domain}Count the DNS lookups in an SPF record against the limit of 10.
metrics
notifications
- GET /notificationsConditions this account should know about.
- GET /notifications/preferencesWhich channels each notification type uses.
- PATCH /notifications/preferencesTurn a notification type on or off per channel.
- POST /notifications/readMark notifications read.
- POST /notifications/{id}/readMark one notification read.
oauth
segments
- GET /audiencesList audiences: every segment on the account, under the older Resend name.
- POST /audiencesCreate an audience, the older Resend name for a segment.
- GET /audiences/{id}Retrieve one audience, the older Resend name for a segment.
- DELETE /audiences/{id}Remove an audience, the older Resend name for a segment.
- GET /segmentsEvery segment on the account.
- POST /segmentsCreate a dynamic segment.
- GET /segments/{id}One segment.
- PATCH /segments/{id}Rename or change the rules.
- DELETE /segments/{id}Delete a segment.
- GET /segments/{id}/membersThe segment evaluated RIGHT NOW — live member ids, never a snapshot.
support
- GET /supportSupport requests on this account, newest activity first.
- POST /supportOpen a support request.
- GET /support/answersPublished answers, newest first.
- GET /support/answers/{slug}One published answer.
- POST /support/answers/{slug}/helpfulSay whether a published answer helped.
- GET /support/attachments/{id}/downloadDownload an attachment on a request this account owns.
- GET /support/configTopics, hours, attachment limits and any current support notice, for opening a support request.
- GET /support/known-issuesKnown issues we are working on or watching, newest first, and whether you follow each.
- POST /support/known-issues/{id}/subscribeGet one email when a known issue is resolved.
- GET /support/searchSearch the docs, published answers and open known issues before opening a request.
- POST /support/uploadsStage files to attach to a support message.
- GET /support/{ref}One support request and its public thread.
- POST /support/{ref}/csatRate a resolved support request, 1 to 5.
- POST /support/{ref}/messagesReply on a support request.
- POST /support/{ref}/reopenReopen a resolved request within 14 days.
- POST /support/{ref}/resolveMark a support request resolved.
suppressions
- GET /suppressionsSuppressions recorded on this account, with a count of platform-wide rows and none of their addresses.
- POST /suppressionsSuppress an address or a whole domain (send "@example.com").
- POST /suppressions/batch/addSuppress up to 500 addresses in one call.
- POST /suppressions/batch/removeLift up to 500 suppressions by address.
- GET /suppressions/{id}One suppression, by its id or by the address.
- DELETE /suppressions/{id}Remove one suppression row.
team
- POST /invite/{token}/acceptAccept an invitation.
- GET /team/invitesInvitations that have not been accepted, cancelled or expired.
- POST /team/invitesInvite an address at a role.
- DELETE /team/invites/{id}Cancel a pending invitation.
- GET /team/meYour membership on this account: your role, and the seats the plan allows.
- GET /team/membersEveryone on this account and the role each one holds.
- POST /team/membersAdd someone to this account.
- PATCH /team/members/{id}Change a member’s role.
- DELETE /team/members/{id}Remove a member.
templates
- GET /templatesList this account templates, newest first.
- POST /templatesCreate a template draft.
- GET /templates/{id}One template.
- PATCH /templates/{id}Edit a template.
- DELETE /templates/{id}Delete a template and its versions.
- GET /templates/{id}/diffStructured diff between two versions, or between a version and the draft.
- POST /templates/{id}/duplicateCopy a template into a new editable draft.
- POST /templates/{id}/publishSnapshot the draft as an immutable published version.
- POST /templates/{id}/renderRender a version with variables (defaults to the current published one; pass "draft" for the working copy).
- POST /templates/{id}/rollbackStart a new draft from an older version.
- GET /templates/{id}/versionsEvery immutable version, oldest first.
- GET /templates/{id}/versions/{n}One version.
topics
trust
- POST /trust/appealFile an appeal against the current standing.
- GET /trust/remediationThe remediation checklist ticks for this account.
- POST /trust/remediationTick or untick one remediation item.
- GET /trust/standingThis account’s standing, machine-readable.
- GET /trust/thresholdsThe published enforcement thresholds and the ladder they drive.
usage
webhooks
- GET /webhooksList endpoints.
- POST /webhooksRegister an endpoint.
- GET /webhooks/{id}Fetch one endpoint.
- PATCH /webhooks/{id}Update url, subscribed events, or the disabled flag.
- DELETE /webhooks/{id}Delete an endpoint and its queued deliveries.
- GET /webhooks/{id}/dead-lettersDeliveries this endpoint exhausted every retry on, with the payload to inspect.
- GET /webhooks/{id}/deliveriesEvery delivery to this endpoint, with each attempt and what the receiver answered.
- GET /webhooks/{id}/eventsEvents sent to this endpoint, newest first.
- GET /webhooks/{id}/events/{event_id}One event sent to this endpoint, with its payload and when the next attempt is due.
- GET /webhooks/{id}/events/{event_id}/attemptsEvery attempt to deliver one event, with the status code and body the receiver answered.
- POST /webhooks/{id}/events/{event_id}/replaySend one event to this endpoint again.
- POST /webhooks/{id}/replayRe-send past events to this endpoint, by time range and/or a single event id.
- POST /webhooks/{id}/rotate-secretMint a new signing secret.
- POST /webhooks/{id}/signing-secret/rotateMint a new signing secret.
Bounce classes
The four classes every bounce lands in, and the one action that changes each number. The Deliverability screen links a bounce row straight to these ids.
- hard
- The receiving server says the address does not exist. It never will. These addresses are already suppressed. Remove them at the source so the same list stops producing them — GET /suppressions lists every address we are holding back.
- soft
- A temporary refusal — mailbox full, greylisting, or the receiver was briefly unavailable. Nothing to clean. We retry these; a soft bounce only becomes your problem if the same address keeps soft-bouncing for days, at which point it is treated as hard.
- block
- The receiver refused the message on reputation or content, not on the address. This is the class that ends in a blocklist. Check the blocklists panel below, then cut volume on this domain until the rate falls. Recipients who never asked for the mail are the usual cause.
- policy
- The address is real and the receiver would take mail from you, but not this message — size, attachment type, or our own suppression list. Shrink the message or drop the attachment and send again. If the reason is suppression, the address is on a list you can inspect with GET /suppressions.
Catalogues
- Error catalogue — 122 codes, each with a fix.
- Event catalogue — 51 types.
- openapi.json — the document these pages are generated from.