Order notification email
Notify customers of order confirmation, shipping, and status changes with one Mailbot API call per event.
Answer first: to notify a customer about an order, POST https://api.mailbot.id/v1/send with your Bearer key and a JSON body describing the order and its new status. Use an idempotency_key that combines the order id and the status (for example order-1042-shipped) so each status change is sent at most once.
Use case
Order notification emails keep customers informed across the order lifecycle — confirmation, payment received, shipped (with tracking), out for delivery, delivered, or cancelled. Each transition is one transactional email that tells the customer exactly where their order stands.
Each email is triggered by your backend or an order webhook when the order changes state. Mailbot accepts the message payload and returns a message id you can store beside that order event.
When to send
- An order is placed or confirmed.
- Payment is received for the order.
- The order is shipped — include a tracking link.
- The order is delivered.
- The order is cancelled or refunded.
idempotency_key unique per (order, status) so retried webhooks don't resend the same update.API call
curl https://api.mailbot.id/v1/send \
-H "Authorization: Bearer $MAILBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": "Your order #1042 has shipped",
"text": "Good news! Order #1042 has shipped. Track it: https://yourapp.com/orders/1042",
"idempotency_key": "order-1042-shipped"
}'
import os, requests
order_id = 1042
status = "shipped"
res = requests.post(
"https://api.mailbot.id/v1/send",
headers={
"Authorization": f"Bearer {os.environ['MAILBOT_API_KEY']}",
"Content-Type": "application/json",
},
json={
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": f"Your order #{order_id} has shipped",
"text": (
f"Good news! Order #{order_id} has shipped. "
f"Track it: https://yourapp.com/orders/{order_id}"
),
"idempotency_key": f"order-{order_id}-{status}",
},
)
res.raise_for_status()
Required fields
| Field | Required | Notes |
|---|---|---|
to | Yes | The customer's email address. |
subject | Yes | Carry the order ref and status, e.g. "Your order #1042 has shipped". |
text or html | Yes | The body with the order number, status, and a tracking/order link. |
from | No | Verified sender; defaults to the configured sender if omitted. |
idempotency_key | Recommended | Combine order id and status (e.g. order-1042-shipped) so retries don't double-send. |
Example payload
{
"from": "noreply@yourdomain.com",
"to": "user@example.com",
"subject": "Your order #1042 has shipped",
"text": "Good news! Order #1042 has shipped. Status: shipped. Track it: https://yourapp.com/orders/1042",
"html": "<p>Good news! Order <strong>#1042</strong> has shipped.</p><p>Status: shipped.</p><p><a href=\"https://yourapp.com/orders/1042\">Track your order</a></p>",
"idempotency_key": "order-1042-shipped"
}
Example response
{
"ok": true,
"id": "msg_3f8c1a...",
"status": "queued"
}
For delivered messages, the response can include status: "sent" and a delivery_id. See the API reference for every response shape.
Errors
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid payload (bad to, missing subject/body). | Fix the request; read details. |
401 | Bad or missing API key. | Check the Bearer header. |
429 | Send limit reached. | Back off; surface a "try again later" message to the user. |
502 / 503 | Mailbot is temporarily unable to accept the send. | Retry with backoff using the same idempotency_key. |
Full error handling guidance is in the integration guide.
Testing
For safe setup, use the standard test endpoint to confirm delivery reaches an address you control:
curl https://api.mailbot.id/v1/test-email \
-H "Authorization: Bearer $MAILBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "to": "safe@yourdomain.com", "label": "Order test" }'
Production checklist
- One email per real status transition (confirmed, paid, shipped, delivered, cancelled).
idempotency_key= order id + status, unique per transition.- Tracking and order links point to your app.
- Verified sender domain;
fromset to a verified address. - API key kept server-side; never sent to the browser or mobile client.
429/5xxhandled with backoff using the sameidempotency_key.- Keep this path transactional — avoid sending marketing content through it.