Sending
More ways to use this page
Send up to 100 messages
POST/v1/
TypeScript sendora
Python sendora
Key sk_… a server key
Accepts an array of messages and answers one result per message, in order: accepted with its id, or refused with the same error the single send would give. The Idempotency-Key is required. A retry under the same key sends nothing twice: every item accepted before is answered again with replayed set, and only the items that failed are attempted again.
Parameters
idempotency-keyin headerstringrequiredAny text of 1 to 255 printable characters that identifies this batch; the same key with a different item is refused for that item.
Request body
fromone of 2requiredThe sender. Its domain must be a verified sending domain of the server.
- string (email)
emailstring (email)requirednamestring (at least 1, at most 200 characters) or nullA display name of up to 200 characters.
streamIdstring (uuid)The stream of this server the message goes on; the default transactional stream when absent.
toarray of one of 2, at least 1requiredRecipients; at most 50 across to, cc and bcc.
- string (email)
emailstring (email)requirednamestring (at least 1, at most 200 characters) or nullA display name of up to 200 characters.
ccarray of one of 2Copied recipients, shown in the message.
- string (email)
emailstring (email)requirednamestring (at least 1, at most 200 characters) or nullA display name of up to 200 characters.
bccarray of one of 2Blind-copied recipients.
- string (email)
emailstring (email)requirednamestring (at least 1, at most 200 characters) or nullA display name of up to 200 characters.
subjectstring (at least 1, at most 998 characters)requiredThe subject line.
textstring (at least 1 character)The plain-text part. At least one of text and html is required.
htmlstring (at least 1 character)The HTML part.
headersmap of string to stringdefault {}Custom headers by name, at most 20. Sendora writes these itself, so a message may not set them: From, Sender, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Return-Path, Received, Delivered-To, DKIM-Signature, DomainKey-Signature, Authentication-Results, Received-SPF, and any name that starts with Content-, Resent-, ARC- or X-Kumo.
attachmentsarray of object, at most 20At most 20. A message with its attachments encoded may be at most 10 MB.
namestringrequiredcontentstring (base64)requiredcontentTypestringcontentIdstring or null
tagstring or nullA label of up to 100 characters, returned with the message and its events.
metadatamap of string to stringdefault {}Up to 20 key-value pairs of your own, returned with the message and its events.
[
{
"from": {
"email": "no-reply@example.se",
"name": "Example AB"
},
"to": [
"anna@example.com"
],
"subject": "Your invoice for September",
"text": "Hi Anna, your invoice is attached.",
"attachments": [
{
"name": "invoice.pdf",
"content": "JVBERi0xLjcK",
"contentType": "application/pdf"
}
],
"tag": "invoice",
"metadata": {
"invoiceId": "2026-0912"
}
}
]Responses
200Every message answered on its own; the batch as a whole never fails halfway.
resultsarray of one of 18requiredOne result per message, in request order.
The message was accepted for delivery.
messageIdstring (uuid)requiredThe id the message log, the events and the webhooks refer to.
status"accepted"requiredsubmittedAtstring (date-time)requiredWhen the message was accepted.
testbooleanrequiredTrue when the server is a test server: the message goes through everything but delivery, and nobody receives it.
indexintegerrequiredThe position of the message in the request.
replayedbooleanrequiredTrue when an earlier request under the same key already sent this item.
A refusal carries
message,index,statusanderror, one of these codes, with the fields the code adds:Code Meaning Adds invalid_request The message does not match what a send takes. issues(path,message)from_domain_ not_ verified The From domain is not a verified sending domain of this server. stream_not_ found The streamId names no stream of this server. stream_archived The stream is archived and takes no new messages. stream_paused Sendora has paused the stream after complaints; it takes no messages until support has resumed it. stream_not_ sendable An inbound stream receives mail; it takes no messages and has no suppression list. Name a transactional or broadcast stream. unsubscribe_placeholder_ missing A message on a broadcast stream must carry {{ unsubscribe_url }} in every part it has. list_unsubscribe_ reserved On a broadcast stream Sendora writes the List-Unsubscribe pair itself, so a message may not carry one. recipient_suppressed One or more recipients are on the suppression list of the stream. streamId,suppressed(address,reason)test_address_ on_ live_ server Addresses at simulator.sendora.se act out an outcome on a test server; a live server never sends to them. addressesidempotency_key_ mismatch The Idempotency-Key was already used for a different request. rate_limited More was sent within a minute than the limit allows. scope,limit,retryAftermonthly_cap_ reached The monthly cap of the account, the server or the test servers is used up. scope,cap,used,resetsAtsending_disabled Sending is disabled for everyone for the moment; retry after the seconds in Retry-After. account_paused The account is paused by Sendora. account_not_ active The account is closed, or not yet approved for a live server's sends or an inbound stream. payment_required The account has no active subscription.
Example
{
"results": [
{
"index": 0,
"messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
"status": "accepted",
"submittedAt": "2026-09-15T12:00:00.000Z",
"test": false,
"replayed": false
}
]
}Errors
Every error answers error, the code, and message, a sentence for a person. A code that adds fields is shown in full below the table.
| Code | Status | Meaning |
|---|---|---|
invalid_ | 400 | The body, the query or a header does not match what the route takes. |
idempotency_ | 400 | Batch sends need an Idempotency-Key header. |
unauthorized | 401 | The key is missing, malformed or revoked. |
payment_ | 402 | The account has no active subscription. |
wrong_ | 403 | The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes. |
account_ | 403 | The account is paused by Sendora. |
account_ | 403 | The account is closed, or not yet approved for a live server's sends or an inbound stream. |
request_ | 413 | The body exceeds 10 MB. |
sending_ | 503 | Sending is disabled for everyone for the moment; retry after the seconds in Retry-After. |
Retry-Afterheader on 503integerSeconds to wait before trying again.
invalid_request
issuesarray of objectOne entry per invalid field; absent when a header is wrong.
pathstringrequiredThe field, dotted, such as to.0.email; empty when the whole body is wrong.
messagestringrequired
Example
{
"error": "invalid_request",
"message": "The request is invalid: to.0: Invalid email address",
"issues": [
{
"path": "to.0",
"message": "Invalid email address"
}
]
}