MailcrateDocs

Batch Sending

Send up to 500 emails in one request, and handle the ones that fail without resending the ones that worked.

When one event in your system produces many emails, such as an order confirmation to the buyer plus a notice to each seller, send them in one request instead of many.

POST/public/sending/mail/batchscope · sending:write

Send a batch

The body is a messages array of 1 to 500 entries. Each entry takes exactly the same fields as a single send, so each can have its own recipient, template, data and lane:

Terminal
curl -X POST https://api.mailcrate.io/public/sending/mail/batch \
  -H "Authorization: Api-Key $MAILCRATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {
        "contactEmail": "ada@example.com",
        "templateId": "order-confirmation",
        "lane": "transactional",
        "data": { "orderNumber": "A-1042" },
        "idempotencyKey": "order-A-1042-buyer"
      },
      {
        "contactEmail": "grace@example.com",
        "templateId": "new-order-for-seller",
        "lane": "transactional",
        "data": { "orderNumber": "A-1042" },
        "idempotencyKey": "order-A-1042-seller-17"
      }
    ]
  }'

Read the results, not the status code

Messages are processed one by one, in order, and each one succeeds or fails on its own. A message with an unknown template or an unverified sender does not stop the others. So the request answers 200 even when some messages failed, and the response says which:

Response
{
  "total": 2,
  "succeeded": 1,
  "failed": 1,
  "results": [
    {
      "index": 0,
      "success": true,
      "data": { "id": "6f1c2a9e-3b7d-4c55-9a1e-2d8f0b4c7e11", "status": "created", "lane": "transactional" }
    },
    {
      "index": 1,
      "success": false,
      "error": { "statusCode": 404, "message": "Email template \"new-order-for-seller\" not found." }
    }
  ]
}
  • index is the message's position in your messages array.
  • data is what a single send would have returned. A suppressed recipient is a success with "status": "suppressed", not a failure.
  • error carries the status code and message a single send would have answered with.

Check failed after every batch. When it is not zero, fix and resend only the failed entries.

When the whole batch is rejected

The batch is checked as a whole before anything is sent. If the body is malformed (no messages, more than 500 entries, or an entry that fails validation, such as a bad email address) the request answers 400 and nothing is sent. Fix the request and send it again.

Retrying a batch

Give every message its own idempotencyKey. Then resending a whole batch after a timeout is safe: messages that already went out return their original delivery, and only the rest are sent.

The same contact can appear in a batch more than once. Because messages are processed in order, a contact created by the first message is found by the next.

From the CLI

mailcrate send-email-batch ./messages.json sends a JSON file of messages and exits non-zero if any of them failed. See CLI.

On this page