SDKs#
Use a Resend SDK#
Outbox implements the Resend API, so every official Resend SDK works against it. Change the base URL and nothing else.
JavaScript / TypeScript#
import { Resend } from "resend"
const resend = new Resend(process.env.OUTBOX_API_KEY, {
baseUrl: "https://outbox.example.com",
})
const { data, error } = await resend.emails.send({
from: "Acme <[email protected]>",
to: ["[email protected]"],
subject: "Hello World",
html: "<strong>It works!</strong>",
})This is verified rather than asserted: the repo's bun run test:compat runs the official
resend package against a live Outbox and checks sends, retrieval, listing, scheduling,
cancellation, batching, audiences, contacts, API keys, and error shapes.
Python#
import resend
resend.api_key = os.environ["OUTBOX_API_KEY"]
resend.api_url = "https://outbox.example.com"
resend.Emails.send({
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"subject": "Hello World",
"html": "<strong>It works!</strong>",
})Ruby#
Resend.api_key = ENV["OUTBOX_API_KEY"]
Resend.base_url = "https://outbox.example.com"
Resend::Emails.send({
from: "Acme <[email protected]>",
to: ["[email protected]"],
subject: "Hello World",
html: "<strong>It works!</strong>"
})Go, PHP, Rust, Java, .NET, Elixir#
Each exposes a base URL or client option. Set it to your Outbox host; the request and response shapes are identical.
SMTP#
Not currently supported. Outbox speaks SMTP outbound and inbound, but does not accept submission over SMTP — use the HTTP API.
The bundled client#
@outbox/sdk ships in the repo. Zero dependencies, functional, and it accepts keys in
either camelCase or snake_case.
import { createClient } from "@outbox/sdk"
const outbox = createClient({
apiKey: process.env.OUTBOX_API_KEY!,
baseUrl: "https://outbox.example.com",
})
const { data, error } = await outbox.emails.send({
from: "Acme <[email protected]>",
to: ["[email protected]"],
subject: "Hello World",
html: "<strong>It works!</strong>",
})It returns { data, error } rather than throwing, matching the Resend SDK's ergonomics:
if (error) {
console.error(error.name, error.message)
} else {
console.log(error === null && data.id)
}Surface#
outbox.emails.send / get / list / update / cancel
outbox.emails.attachments.list / get
outbox.emails.received.list / get
outbox.emails.metrics
outbox.batch.send
outbox.domains.create / get / list / update / verify / remove
outbox.apiKeys.create / list / remove
outbox.segments.create / get / list / remove / contacts / metrics
outbox.audiences.create / get / list / remove
outbox.contacts.create / get / list / update / remove
outbox.contacts.topics.list / update
outbox.contacts.segments.list / add / remove
outbox.contactProperties.create / get / list / update / remove
outbox.topics.create / get / list / update / remove
outbox.broadcasts.create / get / list / update / send / remove / metrics / recipients
outbox.templates.create / get / list / update / publish / duplicate / remove
outbox.suppressions.add / get / list / remove
outbox.suppressions.batch.add / remove
outbox.webhooks.create / get / list / update / remove / verify
outbox.webhooks.events.list / get / attempts
outbox.automations.create / get / list / update / remove / runs / run
outbox.events.send
outbox.logs.list / getIdempotency#
await outbox.emails.send(
{ from: "…", to: ["…"], subject: "…", html: "…" },
{ idempotencyKey: `order-${orderId}-confirmation` },
)Verifying webhooks#
import { verifyWebhook } from "@outbox/sdk"
const event = await verifyWebhook({
payload: rawBody,
headers: {
id: req.headers["svix-id"],
timestamp: req.headers["svix-timestamp"],
signature: req.headers["svix-signature"],
},
webhookSecret: process.env.OUTBOX_WEBHOOK_SECRET!,
})Throws on a bad signature, a missing header, or a timestamp outside the five-minute window. Uses Web Crypto, so it runs in Node, Bun, Deno, Cloudflare Workers, and the browser — though not the browser, please.
Pass the raw body. Re-serialising parsed JSON changes the bytes and verification will fail.
Direct HTTP#
There is nothing unusual about the API — bearer token, JSON, and a User-Agent:
curl -X POST https://outbox.example.com/emails \
-H "Authorization: Bearer $OUTBOX_API_KEY" \
-H "User-Agent: my-app/1.0" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"subject": "Hello World",
"html": "<strong>It works!</strong>"
}'