Skip to main content
Batch sends are for campaigns, bulk notifications, and scheduled blasts. One API call processes up to 1000 messages — each with its own recipient, optional per-row idempotency key, and optional variables.

Minimal batch

Response shape

Batch always returns HTTP 200 — even when some rows fail. The response tells you exactly which succeeded and which didn’t:
success is a convenience boolean — true only when every row succeeded. Your code should branch on failed > 0 to handle partial success gracefully.

Per-row idempotency

Each message can carry its own idempotency_key, scoped per row:

Batch with templates

Use a shared template at the batch level, override variables per row:
A row can also override the template:

Scheduled batch

Schedule every message in the batch for the same time:

Limits

If you need more than 1000 in one go, chunk into multiple calls with a small jitter between them:
Rate limits count each batch call as 1 request — 1000 messages in one batch is still 1/s against the rate limiter.

Partial-success handling

The canonical pattern:
Fail-loud: if you have an SLO on delivery, log the failed rows so you can follow up manually or push them into a retry queue.