Emails

Send a transactional email

Send one transactional email and receive its delivery status in the same response. Accepts a template id or an inline subject + body.

This is the send to reach for when you need to know what happened. The legacy POST /api/emails answers with row ids and no status, so telling an accepted send from a refused one costs a second request; here the receipt carries status, and from reports the sender actually used — which is worth reading, since a template may have supplied it.

Exactly ONE recipient. A single receipt cannot describe a fan-out, so to takes one address: use cc/bcc to copy others on the same message, and POST /api/emails/batch to send different ones.

202 Accepted is the success answer, and PENDING the usual status: the message is queued for the sending pipeline, not yet handed to the provider. Later states (DELIVERED, BOUNCED, …) arrive by webhook.

An optional Idempotency-Key header (1–255 chars, 24h TTL) makes a retry safe: the first request wins and a retry carrying the same key AND body replays its receipt. Reusing a key with a different body answers 422 rather than serving another request's result.

Requires the emails:send scope — Send emails from your verified domains.

post/api/v1/emails

Request

  • Base URL: https://api.sendly.now
  • URL: https://api.sendly.now/api/v1/emails
  • Auth: one of:
    • HTTP bearer
    • API key in cookie better-auth.session_token
    • OAuth 2 (authorization code, authorization URL https://app.sendly.now/api/auth/oauth2/authorize, token URL https://app.sendly.now/api/auth/oauth2/token, scopes: emails:send)

Headers

Idempotency-Keystring

Replay-safety key (24h TTL). Reuse it only to retry the identical request.

Request body

bccstring[]
bodystring
ccstring[]
dataobject

Arbitrary JSON value (string, number, boolean, null, array, or object).

headersobject

Extra header fields to add to the message, as name → value. A name must be an RFC 5322 field-name (printable ASCII, no spaces or colons) and must not be one Sendly writes itself: From, Sender, Reply-To, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Content-Type, Content-Transfer-Encoding, Content-Disposition, Return-Path, DKIM-Signature, DomainKey-Signature, Received, Authentication-Results, List-Unsubscribe, List-Unsubscribe-Post, and any X-SES-, X-Sendly-, Resent-* or ARC-* header. A reserved name, in any letter case, fails validation and nothing is sent.

namestring
replystring email
subjectstring
subscribedboolean
tagsstring[]
templatestring uuid

Response

Email queued

fromstring email required

The sender actually used. Worth reading rather than assuming: it is resolved server-side and may come from the template when the request named none.

idstring uuid required

The Email row this send created. Quote it in support requests.

status'PENDING' | 'SENDING' | 'SENT' | 'DELIVERED' | 'RECEIVED' | 'BOUNCED' | 'FAILED' | 'REJECTED' | 'RENDERING_FAILURE' | 'DELIVERY_DELAY' | 'CANCELLED' required

Delivery status at the moment of the response — PENDING for a send the worker has not picked up yet, which is the usual answer. Later states arrive via webhooks, not here.

tostring email required

The recipient the message was queued for.

Changes

No recorded changes to this operation across all 1 revision of this API.