The send API
POST /api/v1/send sends one transactional mail: a receipt, a reset link, a notice.
The send API is for mail your own app sends to one person at a time: a receipt, a password reset, a download link. One request is one mail. It goes out as transactional mail, so it has no marketing footer, it reaches people who never joined your list, and anyone it adds to your audience is never marketed to.
How to send a mail
- Create a key with the send scope under Settings > API keys and copy it. It is shown once.
- Export it in your shell as
KOLEA_API_KEY. - Check that the from address is on a sending domain you have verified.
- Send the request.
curl -X POST https://kolea.pro/api/v1/send \
-H "Authorization: Bearer $KOLEA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "reader@example.com",
"from_email": "you@your-verified-domain.com",
"subject": "Your receipt",
"markdown": "Thanks for your order, **Ada**.",
"idempotency_key": "order-1234"
}'The request
The body is JSON. to is required, and so is exactly one of markdown, document, or template.
| Field | What it is |
|---|---|
to | The recipient's address. Required. |
name | The recipient's name, up to 200 characters. |
subject | Required unless a template supplies one. |
markdown | The body as Markdown, up to 200,000 characters. |
document | The body as an editor document (JSON). |
template | The slug of a template under Mail > Transactional. |
variables | Values for the template: up to 100 names made of letters, digits, and underscores; values are text, numbers, or true/false. |
from_email | Must be on a verified domain. Defaults to your account's from address. |
from_name | Up to 120 characters. |
reply_to | An address for replies. |
idempotency_key | Up to 255 characters. Send the same key again and you get the first answer back, not a second mail. |
track | true to track opens and clicks. Off unless you ask. |
html is refused by name. Send Markdown, a document, or a template.
The response
202 Accepted comes back as soon as the mail is safely queued. It does not wait for delivery.
{"id": "...", "status": "queued", "to": "reader@example.com",
"idempotency_key": "order-1234", "template": null}A repeated idempotency key answers with the original body and the header Idempotent-Replayed: true.
A refusal is JSON, {"error": {"code": ..., "message": ..., "field": ...}}:
| Status | Code | When |
|---|---|---|
| 401 | unauthorized | The key is missing, wrong, or revoked. |
| 403 | forbidden | The key's scope is not send or admin. |
| 404 | not_found | No template with that slug. |
| 422 | invalid | A field is wrong; fields lists every problem. |
| 422 | from_domain_unverified | from_email is not on a verified domain. |
| 422 | account_unverified | Your account email is not confirmed yet. |
| 429 | rate_limited | Over the key's rate. Wait the seconds in Retry-After. |
Things to know
- Each key allows 120 accepted requests a minute unless you set a different rate when you create it.
- A person who hard bounced or complained is not mailed; the message is recorded as suppressed.
- A plan limit never refuses transactional mail.
- The rest of the API is described at
https://kolea.pro/api/v1/openapi.json, and a send key can call none of it.