One request, or the mailer you already have.
A REST API with idempotency keys and honest rate limits, plus an SMTP relay that accepts whatever you are already using. Both take the same path and leave the same evidence.
REST API, SMTP relay, scheduling, two streams.
OutSend's REST API and SMTP relay: fields, idempotency, rate limits, streams, and scheduling.
A REST API that fits on one page
POST to one endpoint with from, to, subject, and a body. Optional cc, bcc, replyTo, custom headers, and scheduling. The response gives you an id, which is how you pull the trace back later.
- Idempotency that actually helps · Send an Idempotency-Key header and the result is cached for 24 hours. Your retry logic can be as aggressive as your network is unreliable without ever duplicating a message.
# Send a transactional email
curl -X POST https://app.getoutsend.com/api/v1/emails \
-H "Authorization: Bearer $OUTSEND_API_KEY" \
-H "Idempotency-Key: order-8421" \
-d '{
"from": "Acme <hello@mail.acme.com>",
"to": ["maya@example.com"],
"reply_to": "support@acme.com",
"subject": "Your order is on its way",
"html": "<p>Hi Maya, it shipped!</p>"
}'await fetch('https://app.getoutsend.com/api/v1/emails', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.OUTSEND_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'order-8421',
},
body: JSON.stringify({
from: 'Acme <hello@mail.acme.com>',
to: ['maya@example.com'],
subject: 'Your order is on its way',
html: '<p>Hi Maya, it shipped!</p>',
}),
});# Any SMTP client or framework mailer
Host smtp.getoutsend.com
Port 2587
Security STARTTLS
Password your OutSend API key
# Keys can be limited to a single sending domainAn SMTP relay for what you already have
Host, port 2587, STARTTLS, username outsend, password your API key. Nodemailer, ActionMailer, Django, or anything else that speaks SMTP works unchanged — and produces exactly the same events as the API.
- Rate limits you can read · 60 requests a minute and 1,000 an hour per key, returned as a 429 with a sentence explaining it. We would rather refuse loudly than accept a message and quietly drop it.
Two streams, two suppression lists
Transactional and broadcast are kept apart, each with its own suppression list. Someone unsubscribing from your newsletter never stops their password reset from arriving.
- Scheduling · Pass
scheduled_aton a send, orsend_aton a campaign. Scheduled mail sits in the queue where you can see it, and can be cancelled before it goes.
Go and check.
Documentation
- The exact request that produced a message, including the idempotency key.
- Whether a message came in over the API or SMTP — source is recorded on every send.
- Scheduled mail sitting in the queue before it goes out.
- The provider's response to every delivery attempt.
- API reference
- SMTP relay
- Quickstart
We would rather refuse loudly than accept a message and quietly drop it.
The rest of the platform
Observability
Every event, every payload, queryable.
Learn moreCampaigns
Segments, templates, warm-up ramps.
Learn moreContacts
Import, segment, and clean your list.
Learn moreDomains
DKIM, SPF, DMARC, and reputation isolation.
Learn moreAgents
API, CLI, and MCP — evidence in every response.
Learn moreStart sending
Verify a domain, send your first message, and read the trace it leaves behind — in about ten minutes.
Start sending
Send one message.
The quickstart ends by having you read a real trace, which is the only part of this that needs explaining.
Open core · never venture-backed · operated by Martin Business Consultants