Docs / Use cases / Invoice & receipt
Use case

Invoice & receipt email

Send payment receipts and invoices automatically after a transaction, with one Mailbot API call.

Answer first: to send a receipt or invoice, POST https://api.mailbot.id/v1/send with your Bearer key and an html body containing the line items and totals. Set idempotency_key to your order or invoice id so webhook retries never double-send. Mailbot does not support file attachments on /v1/send — link to a hosted invoice/PDF instead.

Use case

After a successful payment, send the customer a receipt (proof of payment) or a formal invoice. The body is typically an HTML summary — order/invoice number, line items, totals, tax, payment method — optionally with a link to a hosted PDF copy your app generates.

Your backend owns the billing data: build the summary from the confirmed transaction, generate any PDF copy, host it, and include a secure link. Mailbot accepts the rendered email payload and returns a message id for the invoice or receipt record.

When to send

  • A payment is captured or succeeds.
  • A subscription renewal is billed.
  • A formal invoice is issued or becomes due.
Important: the /v1/send contract accepts to, subject, text, html, from, and idempotency_key only — there are no file attachments. To deliver a PDF invoice, host the file and include a secure link in the email body.

API call

cURL
curl https://api.mailbot.id/v1/send \
  -H "Authorization: Bearer $MAILBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "billing@yourdomain.com",
    "to": "customer@example.com",
    "subject": "Receipt for order #1042",
    "html": "<p>Thanks for your payment.</p><p>Order #1042</p><p>Pro plan (annual) — Rp 1.200.000</p><p><strong>Total: Rp 1.200.000</strong></p><p><a href=\"https://yourapp.com/invoices/1042.pdf\">Download invoice (PDF)</a></p>",
    "idempotency_key": "receipt-1042"
  }'
Node.js (fetch)
// in your payment webhook handler, after the payment is confirmed
const res = await fetch("https://api.mailbot.id/v1/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.MAILBOT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: "billing@yourdomain.com",
    to: order.customerEmail,
    subject: `Receipt for order #${order.id}`,
    html: `
      <p>Thanks for your payment.</p>
      <p>Order #${order.id}</p>
      <p>${order.lineItem} — ${order.total}</p>
      <p><strong>Total: ${order.total}</strong></p>
      <p><a href="${order.invoiceUrl}">Download invoice (PDF)</a></p>
    `,
    idempotency_key: `receipt-${order.id}`,
  }),
});
if (!res.ok) throw new Error("Receipt email failed");

Required fields

FieldRequiredNotes
toYesThe customer's email address.
subjectYesState the receipt or invoice and its order number, e.g. "Receipt for order #1042".
text or htmlYeshtml recommended for formatted receipts with line items and totals.
fromNoVerified sender; defaults to the configured sender if omitted.
idempotency_keyRecommendedStrongly recommended — set to the order/invoice id so payment-webhook retries don't double-send.

Example payload

JSON request
{
  "from": "billing@yourdomain.com",
  "to": "customer@example.com",
  "subject": "Receipt for order #1042",
  "text": "Thanks for your payment. Order #1042 — Pro plan (annual) Rp 1.200.000. Total: Rp 1.200.000. Download your invoice: https://yourapp.com/invoices/1042.pdf",
  "html": "<p>Thanks for your payment.</p><p>Order #1042</p><p>Pro plan (annual) — Rp 1.200.000</p><p><strong>Total: Rp 1.200.000</strong></p><p><a href=\"https://yourapp.com/invoices/1042.pdf\">Download invoice (PDF)</a></p>",
  "idempotency_key": "receipt-1042"
}

Example response

202 · queued
{
  "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

StatusMeaningWhat to do
400Invalid payload (bad to, missing subject/body).Fix the request; read details.
401Bad or missing API key.Check the Bearer header.
429Send limit reached.Back off; surface a "try again later" message to the user.
502 / 503Mailbot 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 · test email
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": "Receipt test" }'

Production checklist

  • idempotency_key set to the order/invoice id so payment-webhook retries don't double-send.
  • Receipts sent only after the payment is confirmed.
  • PDF/invoice hosted and linked in the body (no attachments).
  • Verified sender domain; from set to a verified address.
  • API key kept server-side; never sent to the browser or mobile client.
  • 429/5xx handled with backoff and a clear user message.