Skip to main content
Kaer APIv1

MailEndpoints


POST /v1/mail/send
Scope
mail
Tier
Build and up
Price
$0.001 per message + $0.0005 per recipient
Free credit
No, paid credit only

Send transactional email from Kaer's own sending domain. Messages leave from api-<your account id>@kaer.dev with the display name <from_name> via Kaer (your account's email domain when from_name is empty), and a short footer naming that domain and the message id for abuse reports. Replies go to reply_to.

Request body

ParameterTypeDefaultDescription
toRequiredstring or string[]·Plain addresses, up to your tier's recipients per message. Duplicates are removed; Kaer's own domains are refused.
subjectRequiredstring·Up to 200 characters. Line breaks become spaces.
textstring·Plain-text body, up to 128 KB. Send text, html or both.
htmlstring·HTML body, up to 256 KB.
from_namestring·Display name, up to 64 characters. Quotes, <, >, @ and \ are removed.
reply_tostring·One plain address. Cannot be a Kaer address.
Idempotency-Keyheader·Optional, up to 200 characters. See Idempotency.

from, cc, bcc, headers and attachments are refused with 400 unsupported_field. The body is limited to 512 KB.

Response

FieldTypeDescription
idstringmsg_ and 24 hex characters.
objectstringmail.message
statusstringsent when the mail server accepted it.
fromstringThe sending address.
recipientsintegerRecipients after removing duplicates.
idempotent_replaybooleantrue when an Idempotency-Key repeat returned the first result.
kaer.cost_usdnumberWhat the message cost. Also in x-kaer-cost-usd.
{
  "id": "msg_63bd80dded23e6452659ed84",
  "object": "mail.message",
  "status": "sent",
  "from": "api-…@kaer.dev",
  "recipients": 1,
  "kaer": { "request_id": "req_…", "cost_usd": 0.0015 }
}

Headers: x-request-id, the x-ratelimit-* headers and x-kaer-cost-usd on a sent message. An idempotent replay has no x-kaer-cost-usd and no from.

Check a message's status

GET /v1/mail/messages/{id}

Returns id, object, status (sending, sent or failed), recipients, error (a code, or null), created_at and kaer.cost_usd. An unknown id is 404 message_not_found. We keep recipient counts and domains, never addresses, subjects or bodies.

Price

Worked examples
One message to 3 recipients$0.001 + 3 × $0.0005$0.0025
1,000 messages, one recipient each1,000 × ($0.001 + $0.0005)$1.50

A message the mail server does not accept is not charged.

Stay within your tier's limits

TierRecipients per day (UTC)Messages per minuteRecipients per message
Build100510
Scale1,0003050
Pro10,000120100

The minute cap counts messages sent in the last 60 seconds; the daily cap counts recipients since 00:00 UTC. Failed messages do not count. Over a cap you get 429 mail_rate_limit (Retry-After: 60) or mail_daily_limit (Retry-After until midnight UTC).

Errors

StatusCodeWhen
400invalid_jsonThe body is not valid JSON. Images also needs a JSON object.
400invalid_bodyThe mail body is not a JSON object.
400unsupported_fieldMail got from, cc, bcc, headers or attachments.
400to_requiredto is missing or empty.
400invalid_recipientA recipient is not a plain email address.
400reserved_recipientA recipient is on a Kaer sending domain.
400too_many_recipientsMore recipients than your tier allows in one message.
400subject_requiredsubject is missing or blank.
400subject_too_longsubject is over 200 characters.
400body_requiredNeither text nor html was sent.
400text_too_largetext is over 128 KB.
400html_too_largehtml is over 256 KB.
400invalid_from_namefrom_name is not a string.
400invalid_reply_toreply_to is not a plain email address.
400reserved_reply_toreply_to is a Kaer address.
413body_too_largeThe body is over the endpoint's limit: chat 1 MB, search 16 KB, batch 64 KB, images 8 KB, mail 512 KB.
403tier_requiredYour tier does not include this service yet.
402insufficient_creditsYour balance cannot cover the call's hold. Free credit never pays for mail.
429mail_rate_limitMessages in the last minute reached your tier's cap.
429mail_daily_limitRecipients today (UTC) would pass your tier's cap.
502mail_rejectedThe mail server refused the message. Nothing was charged.
502mail_transport_failedThe message could not be handed to the mail server. Nothing was charged.
503mail_unavailableMail sending is not available. Nothing was charged.
404message_not_foundNo message with that id on this account.

Send a message

This request sends a receipt with an Idempotency-Key, so a retry cannot send it twice.

curl https://api.kaer.ai/v1/mail/send \
  -H "Authorization: Bearer $KAER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-4812-receipt" \
  -d '{
    "to": ["[email protected]"],
    "subject": "Your receipt",
    "text": "Thanks for your order.",
    "from_name": "Acme",
    "reply_to": "[email protected]"
  }'

© 2026 Kaer Labs Ltd. All rights reserved.