HTTP Email API (2026): Send Transactional Mail over HTTPS with Rovela
Send transactional email over HTTPS and JSON instead of an SMTP socket: POST /emails, Bearer API keys, Idempotency-Key, and how Rovela mailbox SMTP differs.
Send email over HTTPS, not over a socket to port 25
An HTTP email API is a transactional mail service you call the same way you call the rest of your backend: HTTPS, a Bearer token, and a JSON body. You do not open an SMTP conversation, negotiate EHLO / STARTTLS / AUTH, or keep a connection pool of mail sockets in your app. Rovela’s Email API is one endpoint — POST https://api.rovela.dev/emails — that queues the message, DKIM-signs it with your domain key, and returns an id.
This is a protocol-level intro to sending mail over HTTP. It is not Send Email from an AI Coding Agent via HTTP (tooling for coding agents), not the comparison in Email API vs SMTP, and not the five-minute first send in Send Your First Email in 5 Minutes. If you are mid-migration from Nodemailer or PHPMailer SMTP, use Migrate SMTP to an Email API. For the category definition of transactional mail, see Transactional Email API.
Start from the Email API product page, the Quick Start, the Send Email API, and Authentication. Rovela also offers mailbox SMTP on mx.rovela.dev port 465 for people and mail apps; that is a different path, described below.
Related product guides in this series:
- Transactional Email API
- Migrate SMTP to an Email API
- Email API for SaaS Apps
- Send Email with curl
- Transactional Email API + Hosted Mailboxes
- Inbound and Outbound Email API
- Email Sending API
- Email Notification API
- Email API Integration
- Batch Transactional Email API
- Transactional Email Webhooks
- A Simple Transactional Email API
- Send Transactional Email from Your App
- Verified Domain Email API
What the HTTP request looks like
Authenticate with Authorization: Bearer re_your_api_key (Authentication). The body is a flat JSON object: from, to, subject, and at least one of html, text, or template.
curl -X POST https://api.rovela.dev/emails \
-H "Authorization: Bearer re_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@yourdomain.com>",
"to": "you@example.com",
"subject": "Hello from Rovela",
"html": "<p>It worked.</p>",
"text": "It worked."
}'
A successful response looks like {"object": "email", "id": "9f1c2e40-..."}. That 200 means accepted for delivery, not “already in the inbox.” Delivery runs in the background so your request never waits on the receiving mail server (Email API, Quick Start).
The same call from Node or Python is an ordinary HTTP client:
const res = await fetch("https://api.rovela.dev/emails", {
method: "POST",
headers: {
Authorization: "Bearer " + process.env.ROVELA_API_KEY,
"Content-Type": "application/json",
"Idempotency-Key": `signup-verify:${userId}:${codeId}`,
},
body: JSON.stringify({
from: process.env.MAIL_FROM, // e.g. "Acme <no-reply@yourdomain.com>"
to: user.email,
subject: `Your Acme code: ${code}`,
html: `<p>Your verification code is <b>${code}</b>. It expires in 10 minutes.</p>`,
text: `Your verification code is ${code}. It expires in 10 minutes.`,
tags: { kind: "signup-otp", userId },
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`Rovela ${res.status}: ${err.message}`);
}
const { id } = await res.json(); // accepted and queued — not yet delivered
Language-specific walk-throughs already exist for How to Send Email in Node.js and How to Send Email with Python; this post stays on the HTTP contract those guides share.
HTTP vs SMTP in the application
| Concern | SMTP from your app | HTTP email API |
|---|---|---|
| Transport | TCP to port 25, 465, or 587 | HTTPS to api.rovela.dev |
| Auth | AUTH / mailbox password | Authorization: Bearer API key |
| Payload | MIME built in your library | JSON fields (html, text, attachments) |
| Timeouts / retries | Often your problem | Retry the POST; add Idempotency-Key |
| Delivery status | Parse DSNs or poll logs | GET /emails/:id, events, or webhooks |
| Outbound firewalls | Port 25 often blocked | 443 is usually open |
Port roles are covered in SMTP Ports 25, 465, and 587. Rovela’s SMTP product page is for business mailboxes: host mx.rovela.dev, port 465 with implicit TLS, username = the mailbox address, password = a device credential. A mailbox can send only as itself, with a documented cap of 50 recipients per message and 30 messages a minute from one client address. The same page says that for programmatic sending at volume, you should use the HTTP API (which adds tracking, logs, and webhooks). Do not treat mailbox SMTP as a hidden high-volume app relay.
Making HTTP sending safe
- Verified
from. Unverified domains are refused with400naming the domain. See Verified Domain Email API. sending_accesson the server only. Never put a key in a browser, mobile app, or public repo. A leaked sending key is someone sending as your domain (Authentication).Idempotency-Keyon anything retried. Queues, serverless retries, and user double-clicks all re-enter the same logical send. Keys last 24 hours and can be up to 256 characters (Idempotency Keys for Email APIs, Idempotency guide).- Prefer
sending_accessin production.full_accessis for tooling that must read messages, manage domains, templates, or webhooks. - Watch outcomes over HTTP too. Register a webhook (Transactional Email Webhooks) or, with
full_access,GET /emails/:id.
Optional fields you will actually use: reply_to, cc / bcc (they count toward the 50-recipient cap and toward quota), scheduled_at, tags, attachments, and stored template objects. Batch sending is a separate HTTP endpoint: POST /emails/batch — see Batch Transactional Email API.
When HTTP is the wrong tool
- A human sending from Outlook, Apple Mail, or Thunderbird should use mailbox SMTP/IMAP, not an API key (SMTP, Transactional Email API + Hosted Mailboxes).
- A marketing send to a list or segment should use broadcasts, not a tight loop of transactional
POSTs (Transactional vs Marketing Email). - You already accepted a finished body and only need “deliver later” without a running worker —
scheduled_atis still HTTP, just deferred (Scheduled Email Sending).
FAQ
Do I need to install a library? No. curl, fetch, httpx, net/http, or any HTTPS client is enough (Installation).
Can I call the API from the browser? You should not. sending_access in client-side code is a ready-made spam engine from your domain. Put a server in the middle (Email API Integration).
Is this the same as “send email with curl”? curl is one HTTP client. The contract is the same; the curl-specific flags, errors, and cancel examples live in Send Email with curl.
How do I know the mail was delivered? Query GET /emails/:id with a full_access key, or subscribe to email.delivered / email.bounced webhooks. The product page notes that a webhook is typically pushed within about a minute of the receiving server’s decision (Email API).
What about inbound replies? Sending is only half of some products. Inbound and Outbound Email API and Inbound Email API Webhooks cover receiving.
Use HTTPS for app mail
Point your server at POST /emails, keep sending_access in the environment, and let Rovela speak SMTP to the internet. That is the HTTP email API: one request, a message id, and webhooks for what happens after the queue.