Send a transactional email
Send a one-off email, send from a template, or schedule one for later — with the request and response shapes you will actually get back.
NevarMail provides three ways to send email through the public API (/api/v1/*, authenticated with an API key): direct sends, templated sends with variable substitution, and scheduled sends for future delivery.
Send a plain email
Send a single email with a subject, body, and recipient.
curl -X POST https://app.nevarmail.com/api/v1/email/send \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"to": "recipient@example.com",
"subject": "Order Confirmation",
"html": "<h1>Order Confirmed</h1><p>Your order #1234 has been placed.</p>",
"text": "Order Confirmed. Your order #1234 has been placed."
}'Request fields
| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Recipient email address |
from | string | No | Sender address for this message; defaults to your configured sending address. Honored only on a provider that carries a per-send sender — otherwise 409 FROM_OVERRIDE_UNAVAILABLE rather than silently sending from ours |
fromName | string | No | Display name for from |
replyTo | string | No | Reply-To address |
replyToName | string | No | Display name for replyTo |
cc | string or string[] | No | CC email address(es). Not allowed together with templateId, nor under a suppressable use case (including the default) — one message carries one unsubscribe identity |
bcc | string | No | BCC email address. Same rules as cc |
subject | string | Yes, unless templateId is provided | Email subject line |
html | string | No | HTML body content |
text | string | No | Plain text body content |
templateId | string | No | Template to render for this send (see Send a templated email) |
provider | string | No | Provider to use (defaults to auto-selection) |
priority | string | No | "low", "normal" (default), or "high" |
use_case_id | string (UUID) | No | The use case this send is filed under. Omitted, the send lands in the default use case of your organization's default project — which is suppressable, so the email carries the unsubscribe footer |
emailType | string | No | "transactional" (default) or "marketing". A marketing email cannot carry cc or bcc -- one message carries one unsubscribe identity, so a copied recipient's unsubscribe would opt out the to address instead of their own; send each recipient their own message |
metadata | object | No | Arbitrary metadata to attach |
One of html, text, or templateId is required.
Response
Success responses use the standard envelope (see Authentication):
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"messageId": "msg-abc123@yourdomain.com",
"status": "sent",
"provider": "sendgrid",
"sentAt": "2026-03-22T12:00:00.000Z"
},
"requestId": "req_..."
}Send a templated email
There is no separate templated-send endpoint. Templated sends go through the same POST /api/v1/email/send endpoint: provide templateId and omit both html and text, and the template supplies the subject and body. Variables to interpolate into the template go in variables.
curl -X POST https://app.nevarmail.com/api/v1/email/send \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"to": "jane@example.com",
"templateId": "tmpl-welcome-001",
"variables": {
"user": { "name": "Jane Smith" },
"company": { "name": "Acme Inc" }
}
}'Request fields (templated send)
| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Recipient email address |
templateId | string | Yes | The template to use |
variables | object | No | Variables to interpolate into the template |
cc and bcc are not supported alongside templateId -- a templated send renders and tracks unsubscribe state per recipient, so there is no correct address to copy. A request with templateId and either cc or bcc is rejected with 400 CC_BCC_NOT_SUPPORTED_FOR_TEMPLATE. Send one request per recipient instead.
The response uses the same envelope and shape as a plain send.
See Templates for creating and managing templates.
Schedule an email
Schedule an email for future delivery.
curl -X POST https://app.nevarmail.com/api/v1/email/schedule \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"to": "recipient@example.com",
"subject": "Weekly Report",
"html": "<h1>Your weekly report is ready</h1>",
"scheduled_for": "2027-01-15T09:00:00Z"
}'The request body includes the same fields as a plain email send (html or text required), plus:
| Field | Type | Required | Description |
|---|---|---|---|
scheduled_for | string | Yes | ISO 8601 datetime with an explicit UTC offset (Z or ±HH:MM), and must be in the future |
templateId is not supported on scheduled sends -- provide html or text directly. A request with templateId is rejected with 400 VALIDATION_ERROR.
Note the casing: you send scheduled_for, and you read back scheduledFor. The request field is snake_case; the scheduled-email object returned by this endpoint and by GET /api/v1/email/schedule uses camelCase throughout.
Response (201):
{
"data": {
"id": "sched-001",
"emailData": { "to": "recipient@example.com", "subject": "Weekly Report" },
"scheduledFor": "2027-01-15T09:00:00.000Z",
"status": "pending",
"retryCount": 0,
"maxRetries": 3,
"result": null,
"error": null,
"createdAt": "2026-03-22T12:00:00.000Z",
"sentAt": null
},
"requestId": "req_..."
}List scheduled emails
GET /api/v1/email/scheduleReturns all scheduled emails for the org, each with one of these statuses: pending, processing, sent, failed, or cancelled.
{
"data": [
{
"id": "sched-001",
"emailData": { "to": "recipient@example.com", "subject": "Weekly Report" },
"scheduledFor": "2027-01-15T09:00:00.000Z",
"status": "pending",
"retryCount": 0,
"maxRetries": 3,
"result": null,
"error": null,
"createdAt": "2026-03-22T12:00:00.000Z",
"sentAt": null
}
],
"requestId": "req_..."
}Cancel a scheduled email
DELETE /api/v1/email/schedule/:idOnly a scheduled send with status pending can be cancelled. If the row has already moved to processing, sent, failed, or cancelled, the request fails with 409 SCHEDULE_NOT_CANCELLABLE.
{
"data": { "cancelled": true },
"requestId": "req_..."
}Provider selection
Today only SendGrid can be connected, so every send goes to your SendGrid account and there is nothing to select. The provider field on a send request is accepted and honoured, and the routing rules below (health, rate limits, priority) are what will apply once more than one provider can be connected.
A per-send from, fromName, replyTo or replyToName works on a SendGrid account. If the request names a sender and no SendGrid key resolves for your organization, the send is refused with 409 FROM_OVERRIDE_UNAVAILABLE rather than sent from the wrong address.