Guide
Send an email in one HTTP request
One endpoint, one JSON body, one response. Working samples in cURL, Python, Node.js, PHP and Go, then the fields that matter and the ones you can leave out.
The request
POST https://sendfleet.net/api/send/ X-API-Key: sk_live_your_key Content-Type: application/json
There is no SDK and no client library. If your language can make an HTTP request with a JSON body, it can send email.
The smallest body that works
One recipient per request. At least one of message, html or attachments is required, plus a sender and a recipient.
{
"to": "user@example.com",
"from_email": "hello@yourdomain.com",
"from_name": "Acme",
"subject": "Your order is confirmed",
"message": "Thanks for your order!"
}The same request in five languages
curl -X POST https://sendfleet.net/api/send/ \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "user@example.com",
"from_email": "hello@yourdomain.com",
"from_name": "Acme",
"subject": "Your order is confirmed",
"message": "Thanks for your order!"
}'The response
{
"success": true,
"mode": "byoc",
"idempotency_key": "8f14e45fceea167a5a36dedd4bea2543"
}mode tells you which sending path handled the message: byocmeans it went out through the customer's own AWS account, sharedthrough SendFleet's. It reflects the sending domain, not the plan name.
This is an acknowledgement, not a delivery confirmation. The response means the message was accepted for delivery. What happened next arrives later, and only if you have set up a webhook endpoint.
Fields
| Field | Required | What it does |
|---|---|---|
| to | Yes | One recipient address. |
| from_email | Yes | The sending address. Must be on a verified domain. |
| from_name | No | Display name shown next to the address. |
| subject | No | Subject line. |
| message | One of three | Plain-text body. |
| html | One of three | HTML body. Takes precedence over message when both are sent. |
| reply_to | No | Where replies go, if not from_email. |
| attachments | One of three | Base64-encoded files. SendRawEmail carries them. |
| idempotency_key | No | Your own key for this send. Use it to make a retry safe. |
When it fails
Errors come back as a JSON object with a single error key holding a machine-readable code, alongside an HTTP status that tells you the class of problem.
{
"error": "domain_not_verified"
}| Status | Meaning | What to do |
|---|---|---|
| 400 | The request body is invalid. | Fix the body. Do not retry unchanged. |
| 401 | The API key is missing, malformed or revoked. | Check the key. Do not retry. |
| 403 | The key cannot send to this domain, or sending is suspended. | Check domain scoping and account status. |
| 429 | Rate limited, or over the plan's monthly limit. | Back off. Distinguish the two from the error code. |
| 503 | The BYOC role could not be used. | Check the role still exists and still validates. |
The Error Codes reference has every code, what causes it, and whether retrying is safe.
Rate limit
60 requests per minute per key, on every plan. Exceeding it returns HTTP 429. If you need more than that, the ceiling is per key, so several keys will carry several ceilings.
HTML and plain text together
Send both when you can. html is what most recipients see, and message is what a text-only client reads.
{
"to": "user@example.com",
"from_email": "hello@yourdomain.com",
"subject": "Your order is confirmed",
"message": "Thanks for your order!",
"html": "<p>Thanks for your order!</p>"
}Next
Send Email has every field in full, including attachments. Verify webhook signatures covers what to do with the delivery events this request produces.