BeaconBox
Esc

Type to search.

Dashboard

Batches

Up to 100 pushes in one call. Always returns 200, and the item that failed is reported rather than raised.

POST /api/v1/messages/batch takes a list of complete pushes, up to 100, and processes them independently.

It is a list of separate updates, not one update fanned out to many recipients. Order updates are individual by nature: fifty orders means fifty tracking numbers, so a shared body would only serve the marketing blast this product is deliberately not for.

curl https://api.beaconbox.eu/api/v1/messages/batch \
-H "Authorization: Bearer $BEACONBOX_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: dispatch-run-2026-10-02" \
-d '{
  "items": [
    {"recipient_email": "a@example.com",
     "subject": "Your order is on its way",
     "body": "Tracking XY123456789EE.",
     "reference": "#A-10294",
     "order_status": "shipped",
     "kind": "updateable"},
    {"recipient_email": "b@example.com",
     "subject": "Your order is on its way",
     "body": "Tracking XY987654321EE.",
     "reference": "#A-10295",
     "order_status": "shipped",
     "kind": "updateable"}
  ]
}'
Response · 200 OK
{
"items": [
  {
    "index": 0,
    "ok": true,
    "result": {
      "id": "v55favd767qu",
      "recipient_email": "a@example.com",
      "subject": "Your order is on its way",
      "kind": "updateable",
      "status": "active",
      "created": true,
      "scheduled_for": null,
      "nudged": true,
      "email": {
        "sending": true,
        "skipped_reason": null
      },
      "sms": null,
      "sms_units": 0,
      "whatsapp": null,
      "whatsapp_opt_in": null,
      "reference": "#A-10294",
      "order_status": "shipped",
      "created_at": "2026-10-02T20:11:10.674762Z",
      "updated_at": "2026-10-02T20:11:10.674762Z"
    },
    "error_code": null,
    "detail": null
  },
  {
    "index": 1,
    "ok": false,
    "result": null,
    "error_code": "common.validation_failed",
    "detail": "body: must not be blank"
  }
],
"succeeded": 1,
"failed": 1
}

One key for the whole call

The batch takes a single Idempotency-Key. Replaying it replays the whole stored response, including the per-item failures, rather than re-running the items that succeeded.

So a retry after a dropped connection is safe, and the failures you get back the second time are the same failures, not new attempts.

Derive the key from the run rather than from the contents: a dispatch batch keyed dispatch-run-2026-10-02 collapses correctly when the job retries, which is the case this is for.

When to use it

Use a batch when you genuinely have many updates at once: a nightly dispatch run, a courier file imported in one go.

Do not use it to parallelise unrelated pushes. A batch is one request with one key, so an item that needs retrying cannot be retried on its own. For independent updates arriving at their own pace, individual pushes with individual keys are both simpler and more robust.

Limits

One hundred items, and at least one. A batch over the limit is rejected with common.validation_failed before anything is processed, so nothing is half-sent.