A Resend-compatible API your existing code already speaks, plus authentication, suppression, and delivery events from a mail server we operate. White-label tenancy from the schema up — not a reseller layer on someone else's pool.
Drop-in compatible API Delivered from the MTA White-label multi-tenancy
Point your existing transactional client at our base URL and your code keeps working — same payloads, same response shapes. Migrate in one line, then grow into the superset.
Send with the exact Resend payload: from, to, cc, bcc, reply_to, subject, html, text, attachments, headers, and tags. Validation returns actionable errors, not 500s.
POST /emails/batch accepts up to a hundred messages in a single request — distinct recipients, subjects, and tags per entry — so high-volume jobs stay one round trip instead of a hundred.
Pass scheduled_at — an ISO 8601 timestamp with an explicit UTC offset — to queue a send for later. Cancel it with POST /emails/:id/cancel while it is still queued. Past or ambiguous times are rejected up front.
Send the same Idempotency-Key header twice and the second request returns the first result instead of a duplicate email. Safe retries through any flaky network.
We enqueue the message and return an id immediately. Your request thread never waits on the receiving server. Status then moves queued → sent → delivered, bounced, or complained.
Keep the resend SDK and set RESEND_BASE_URL=https://api.usermails.com. A typed UserMails SDK ships in this repo; it is not on npm yet.
// Keep your existing client. Change the base URL.
import { Resend } from "resend";
const resend = new Resend(process.env.USERMAILS_API_KEY);
// resend v6+: RESEND_BASE_URL=https://api.usermails.com
await resend.emails.send({
from: "noreply@acme.com",
to: "user@example.com",
subject: "Reset your password",
html: "<strong>Click to reset</strong>",
});Resend compatibility is a contract, not a one-time port. Features ship as a superset — your existing payloads never break.
Add a domain and we generate the keys and records that decide whether you reach the inbox — then verify them live.
We generate DKIM keys and derive the SPF, DMARC, and optional MAIL FROM records every authenticated sender needs — no guesswork.
Publish records straight to supported DNS providers, or copy-paste them into any registrar. Live re-verification shows pending, verified, or failed per record.
You cannot send from a domain this project has not verified. DMARC policy guidance walks you from none toward enforcement.
Credentials scoped to a single project, and a delivery path engineered so an accepted send is a kept promise.
Create and revoke keys per project. Dashboard keys default to sending-access (a leak cannot mint more keys). Full-access is explicit. Keys are shown once and stored only as hashes. Per-key rate limits are enforced.
Every send enters a durable queue before it leaves, with retries for transient failures. Accepted means queued; delivered means the receiving server returned 250.
Per-project suppression lists are enforced before a message is ever queued, so you can't re-mail an address that already hard-bounced or complained.
POST /verify flags invalid syntax, dead domains, disposable and role addresses, and Spamhaus DBL hits before you send.
Delivery, bounce, and complaint are captured from the mail server — pushed to you signed, and shown on the message.
Register endpoints per project. Payloads are HMAC-signed (usermails-signature: sha256=…) for email.sent, delivered, bounced, complained, and inbound mail.
At-least-once delivery with exponential backoff on failure. Manual one-click replay is not in the dashboard yet.
Open any message to see queued → sent → delivered / bounced / complained. Optional open and click events when tracking is enabled on that domain.
Dashboard tiles count accepted, delivered, bounced, and complained separately. Delivery rate is hidden until real feedback exists — we never imply inbox placement we cannot prove.
Opt-in per domain. A tracking pixel and rewritten links write opened / clicked onto the message timeline. Those events are not webhooked yet.
List-Unsubscribe and RFC 8058 one-click headers are injected on sends we relay. Honored immediately.
Multi-tenant from the schema up — organizations contain projects, projects scope every key, domain, log, and send. Isolation is enforced at the data layer, not the interface.
Role-based access — owner, admin, developer, viewer — per org. Every resource belongs to exactly one project; dashboard writes are gated by permission.
Logo, colors, and a powered-by toggle on plans that include branding. Custom dashboard hostnames are in the schema; assignment UI is not live yet.
White-label orgs create child accounts, switch into them, and see per-tenant send rollups. Stripe invoicing of those rollups is not live yet.
Transactional sending works today. These are real next steps, not hidden in the product copy.
Per-tenant or per-stream IPs with a warmup ramp. Today every tenant sends through the mail server we operate.
Seed-list folder placement (inbox / spam / missing) per mailbox provider. Today we report whether the receiving server accepted the message.
Plain-language bounce and auth-gap diagnosis on the log row, the API, and MCP. Bounce reason is already stored on the event.
A first-class contact store built from the same activity your transactional sends already produce.
One-off and recurring campaigns on the same authenticated infrastructure. Not an SMTP relay product, and not shipping with transactional.
Journeys triggered by the same event stream — welcome series, win-backs — without a second vendor.
Phased on purpose: a developer can fully migrate off Resend today, then turn on marketing when it ships — without re-platforming.
Create a project, verify a domain, drop in a key, and change one base URL. Free to start, no card required.