Guides
Sending email
Transactional email is the mail your application sends one person because of something they did: a receipt, a sign-in link, an order update. It has its own key, its own limits and no unsubscribe link.
Before the first send
- A domain on your account that is set up for sending. Add it in the console under Domains; the records are set up with you, and the domain is ready once they are seen.
- A key with the
mail:sendscope. Keep it to that scope alone unless the same system needs more.
The from address must be on one of those domains. A domain that is not on the account is answered 400; one that is not ready yet, 409 conflict.
/emailsSend an email
Sends one transactional email: a message your application sends one person because of something they did, such as a receipt, a sign-in link or an order update. It carries no unsubscribe link, so the rules are strict. An address that bounced or marked your mail as spam is never sent to. Someone who unsubscribed may still get account, security, receipt and order mail, but never a notification, and never a message that reads as selling; that is refused with the words that gave it away. Refusals answer 409 and are listed in GET /emails. The from address must be on one of your domains that is set up for sending (400 if the domain is not yours, 409 if it is not ready, 409 if sending is stopped for the account). One address gets at most 20 messages a day, and the account has an hourly limit by plan; either answers 429. Give text, html or both; without text, a plain text part is made from the HTML. Send an idempotencyKey to make retries safe: the same key returns the first message with "repeated": true instead of sending again. The message body is not kept, only who, when, the subject and the outcome. Needs a key holding mail:send.
Body
- fromstring (email)required
- The sender. Its domain must be one of yours, verified and set up for sending.
- fromNamestringoptional
- A display name for the sender, up to 120 characters.
- tostring (email)required
- The one recipient.
- replyTostring (email)optional
- Where replies go.
- subjectstringrequired
- 1 to 300 characters.
- textstringoptional
- The plain text part, up to 200,000 characters. Give text, html or both.
- htmlstringoptional
- The HTML part, up to 500,000 characters.
- category'account' | 'security' | 'receipt' | 'order' | 'notification'required
- What kind of message this is. Only account, security, receipt and order mail may reach someone who unsubscribed.
- idempotencyKeystringoptional
- Up to 200 characters. A retry with the same key returns the first message and sends nothing.
curl -X POST https://app.rykonmail.com/api/v1/emails \
-H "Authorization: Bearer $RYKON_MAIL_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "orders@northwind-local.test",
"fromName": "Northwind Traders",
"to": "jamie.chen@example.com",
"replyTo": "help@northwind-local.test",
"subject": "Your receipt for order 10482",
"text": "Thanks for your order.\n\nOrder 10482: 2 x Linen apron, $48.00.\nTotal paid: $48.00.",
"html": "<p>Thanks for your order.</p><p>Order 10482: 2 x Linen apron, $48.00.<br>Total paid: <strong>$48.00</strong>.</p>",
"category": "receipt",
"idempotencyKey": "order-10482-receipt"
}'{
"id": "682e5ffd-1528-4b9e-9b81-65903d3d9593",
"category": "receipt",
"from": "orders@northwind-local.test",
"to": "jamie.chen@example.com",
"subject": "Your receipt for order 10482",
"state": "sent",
"messageId": "simulated-fa61a1bd-2389-4b00-ab0c-63ac54867b0c",
"error": null,
"createdAt": "2026-10-30T06:18:05.177Z"
}In the reference: Send an email
Categories
Every message names its category. It is how a person who unsubscribed from your marketing still gets the mail they cannot do without, and only that.
| category | For | After unsubscribing |
|---|---|---|
| account | Sign-up confirmations, email changes, account notices | Still delivered |
| security | Sign-in links, password resets, new device alerts | Still delivered |
| receipt | Receipts and invoices | Still delivered |
| order | Order, shipping and booking updates | Still delivered |
| notification | Activity notifications: a comment, a mention, a digest | Not sent |
Who may receive what
Transactional mail skips consent, which would make it the easy way around it. So the rules are firm, and a message that breaks one is refused, never queued:
- An address that bounced or marked your mail as spam is never sent to, whatever the category.
- Someone who unsubscribed gets
account,security,receiptandordermail only, and not if it reads as selling. The refusal names the words that made it read that way. - One address gets at most 20 transactional messages a day.
A refusal is answered 409 refused with the reason. Do not retry it; see Errors.
Idempotency
Give each message an idempotencyKey that is unique to it in your system, such as order-1042-receipt. If your request times out, send it again with the same key: the first message is returned, marked "repeated": true, and nothing is sent twice. If we could not hand the message over at all, a retry with the same key sends it.
Content
- Give
text,htmlor both. When you give only HTML, a readable text part is made from it for the clients and filters that want one. - No unsubscribe link is added: nobody can opt out of their own password reset. Do not put marketing in a transactional message; send it as a campaign.
- The body is not stored. The log keeps who, when, the subject and the outcome, and you can read it in the console under Sending.
Your own reputation
/emailsList sent emails
The 100 most recent transactional messages, newest first, including the ones that were refused and why. With them: how many were sent in the last hour and day, how many were refused today, the account's hourly limit and the most one address may get in a day. Bodies are never kept, so they are not here. Needs sending:read.
Query parameters
- tostring (email)optional
- Only messages to this address.
- state'sent' | 'refused' | 'failed'optional
- Only messages in this state.
curl "https://app.rykonmail.com/api/v1/emails?to=jamie.chen%40example.com" \
-H "Authorization: Bearer $RYKON_MAIL_KEY"{
"messages": [
{
"id": "ba525624-1079-436d-9525-88eb1b013547",
"category": "order",
"from": "orders@northwind-local.test",
"to": "jamie.chen@example.com",
"subject": "20% off everything this weekend",
"state": "refused",
"messageId": null,
"error": "jamie.chen@example.com unsubscribed and this reads as marketing (% off, shop now); transactional mail must not sell",
"createdAt": "2026-10-30T06:18:05.232Z"
},
{
"id": "682e5ffd-1528-4b9e-9b81-65903d3d9593",
"category": "receipt",
"from": "orders@northwind-local.test",
"to": "jamie.chen@example.com",
"subject": "Your receipt for order 10482",
"state": "sent",
"messageId": "simulated-fa61a1bd-2389-4b00-ab0c-63ac54867b0c",
"error": null,
"createdAt": "2026-10-30T06:18:05.177Z"
}
],
"lastHour": 1,
"lastDay": 27,
"refusedToday": 25,
"hourlyLimit": 2000,
"perRecipientPerDay": 20
}In the reference: List sent emails