Skip to main content
Two endpoints have a batch form: decide takes elements, events takes events. Both return per-item results inside a 200, so one bad item never fails its siblings, and both count as one request against the rate limit.

Decide several elements

  • Up to 50 items. The envelope’s user_id, identifiers, attributes, context and options are defaults that items may override.
  • Each item is a complete singular request, so a secret-key item may carry a declaration, and a publishable-key item may carry only the serving fields.
  • idempotency_key is per item. The envelope-level replayed counts how many items were replays.
  • A repeated (user, element) pair in one envelope is an item-level error, since the second decision would only end the first’s window.
  • Items may name different users, for cross-user jobs such as rendering a digest for many recipients.
The browser SDK uses this form to decide every tagged element near the viewport in one request per frame; the server SDK exposes it as decideMany().

Report several events

  • Up to 200 items. The envelope’s user_id, context and timestamp apply to items that omit them.
  • id is per item and echoed back. duplicates counts items whose id was already known, including an earlier item in the same batch.
  • Unknown fields are ignored on the envelope and on items; created_at and as_of are rejected per item.

Envelope errors versus item errors

An envelope error fails the whole request with a non-2xx status: a bad key, an unparseable body, an empty list (elements must be a non-empty array), more items than the cap. An item error is reported inside the 200 at the item’s index and uses the same { "error", "message" } shape as a standalone error. Handle both: check the status, then walk results.

When to batch

Batch when the items are known together: a page with several optimized elements, a flush of queued events, a nightly sync. Do not hold a decision back to fill a batch; the deadline on decide matters more than the request count. Events can wait: the server SDK queues them and flushes every five seconds or every hundred events, whichever comes first.