NevarMail

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 '{
    "use_case_id": "YOUR_USE_CASE_ID",
    "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

FieldTypeRequiredDescription
tostringYesRecipient email address
fromstringNoSender address for this message. Defaults to the use case's sender, else the project's default sender (with its display name and reply-to); with neither, the send is refused with 409 FROM_UNRESOLVABLE.
fromNamestringNoDisplay name for from
replyTostringNoReply-To address
replyToNamestringNoDisplay name for replyTo
ccstring or string[]NoCC email address(es). Not allowed together with templateId, nor under a suppressable use case (including the default) — one message carries one unsubscribe identity
bccstringNoBCC email address. Same rules as cc
subjectstringYes, unless templateId is providedEmail subject line
htmlstringNoHTML body content
textstringNoPlain text body content
templateIdstringNoTemplate to render for this send (see Send a templated email)
providerstringNoWhich connected account sends it: a provider ID, or sendgrid for your highest-priority SendGrid account. Omitted, it is that account. A provider that cannot send yet (anything but SendGrid) is refused with 409 SENDING_PROVIDER_UNAVAILABLE
prioritystringNo"low", "normal" (default), or "high"
use_case_idstring (UUID)Yes, unless your key is scoped to a projectThe use case this send runs as; list yours with GET /api/v1/use-cases. A key scoped to one project may omit it, and the send lands in that project's default use case, which is suppressable, so the email carries the unsubscribe footer. An organization-wide key that names none is refused with 422 USE_CASE_REQUIRED
emailTypestringNo"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
metadataobjectNoArbitrary 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 '{
    "use_case_id": "YOUR_USE_CASE_ID",
    "to": "jane@example.com",
    "templateId": "tmpl-welcome-001",
    "variables": {
      "user": { "name": "Jane Smith" },
      "company": { "name": "Acme Inc" }
    }
  }'

Request fields (templated send)

FieldTypeRequiredDescription
tostringYesRecipient email address
templateIdstringYesThe template to use
variablesobjectNoVariables 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 '{
    "use_case_id": "YOUR_USE_CASE_ID",
    "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:

FieldTypeRequiredDescription
scheduled_forstringYesISO 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/schedule

Returns 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/:id

Only 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 accounts can send. A send goes out on your highest-priority SendGrid account, or on the account the provider field names (by provider ID, or sendgrid). A provider naming anything else is refused with 409 SENDING_PROVIDER_UNAVAILABLE, never sent on a different account. The routing rules below (health, rate limits, priority) are what will apply once more providers can send.

A per-send from, fromName, replyTo or replyToName works on a SendGrid account. When the request names no from, the address comes from the use case's sender or the project's default sender — see Which sender a send uses. If no SendGrid key resolves for your organization, the send is refused with 409 SENDING_PROVIDER_UNAVAILABLE rather than sent from the wrong address.

On this page