Skip to main content
When a batch fans a file of ten thousand contacts out into ten thousand executions, and each execution ends with “add this contact to a dialing list,” you don’t want ten thousand individual API calls hitting the downstream platform. Batched delivery solves this: each execution contributes its record to a shared buffer, and the platform delivers the buffer to the downstream system in bulk calls.

When to use it

Use batched delivery when a task performs a high-volume write against a rate-limited or bulk-oriented API — Five9 list operations are the canonical example. Many contact center APIs accept hundreds or thousands of records per call and throttle callers who send them one at a time. Keep the default direct delivery when a task is low-volume, needs its own response immediately, or calls an API with no bulk endpoint.
Only actions marked batch_capable in the catalog support batched delivery. A batch-capable action also declares batch_settings, and GET /catalog/actions/{action_id} now returns that object in full rather than leaving you to infer the limits from batch_capable alone.For five9__configuration_service__add_to_list it reads {"max_records_per_call": 50000, "supports_partial_success": true, "record_identifier_field": "number1"} — Five9 accepts up to 50,000 records in a single addToList call and reports per-record outcomes, so one bad row does not reject the batch.Always read supports_partial_success before batching a large group. It is not the same for every action. five9__configuration_service__add_numbers_to_dnc reports {"max_records_per_call": 50000, "supports_partial_success": false, "record_identifier_field": "number"}: Five9 validates a DNC write for the whole request, so a single invalid number rejects every number sent with it. Prefer smaller batches for that action than you would use for add_to_list, where a bad row costs you only that row. five9__configuration_service__remove_numbers_from_dnc reports the same settings and is batched the same way, conservatively — Five9 does not validate numbers on the removal path, so the setting is a deliberate floor rather than an observed limit.

Enabling it on a task

Set delivery: "batched" on the task and provide a batch_config. A batched task without a batch_config is rejected at creation time.

How it behaves

When a batched task runs, the execution resolves the task’s expressions as usual, then hands the resulting record to a shared batch collector for that action instead of calling the downstream API itself. Records from every concurrent execution using the same action converge into the same buffer. The execution pauses at that task until its record’s result comes back, then continues with the rest of the flow — from the flow’s point of view, a batched task looks just like a direct one, only with added latency while the batch fills. The buffer flushes — one bulk call to the downstream system — when either trigger fires, whichever comes first:
  • Size — the buffer reaches max_batch_size records.
  • Timeflush_interval elapses since the last flush.
If fewer than min_batch_size records have accumulated when the interval elapses, the flush is deferred to let the batch fill further. Records are never held indefinitely, though: after a few consecutive deferrals, a force-flush delivers whatever is buffered, even below the minimum.
Tune max_batch_size to the downstream API’s per-call record limit and flush_interval to the latency you can tolerate. A large min_batch_size improves bulk efficiency at the cost of latency during quiet periods.

Configuration reference

Failure handling

Failures can happen at two levels:
  • The bulk call fails (network error, downstream outage, rejected batch). on_batch_failure governs the response — with the default retry_batch, transient failures are retried automatically with backoff before the batch is declared failed.
  • Individual records fail inside an otherwise-successful bulk call, on actions whose downstream API supports partial success. on_record_failure governs what each originating execution sees: with the default signal_failed, the execution receives the failure as its task result and can branch on it with an exit condition.
Each execution receives the result for its own record. One record failing does not fail the other executions whose records shared the same bulk call.
An execution waits up to 10 minutes for its record’s batch result. If no result arrives in that window — for example, the downstream system is down and retries are exhausted — the task’s result is a batch_timeout error, which the flow can detect with an exit condition.

Observability

Batching is an internal throughput mechanic — there is no customer-facing API to inspect batch state, buffer contents, or per-flush breakdowns, and the flow surface never exposes one. From your point of view a batched task behaves exactly like a direct one; the buffer, its size, and its flush cadence are implementation details of how the platform delivers records efficiently. Operators running the platform observe flush activity through structured server logs — each flush is logged with useful context (the action, the number of records delivered, and the running cumulative count) for debugging throughput. This visibility lives in the logs, not in the API.

Next steps

Integration catalog

Find batch-capable actions and their per-call limits.

Trigger with records

Fan a file of records out into one execution per row.