Verify a batch
A batch accepts exactly one input source: an inlineemails array containing 1–10000 addresses, or the listId of a ready list already stored in your account. Do not send both fields. The first accepted submission returns 202; replaying the identical body with the same Idempotency-Key returns 200, replayed: true, and the same request.id.
1. Submit and capture the request ID
jq is required by the shell examples. Keep request and result files in access-controlled storage because they contain email addresses.
To submit an existing ready list instead, keep the same headers and send only its ID:
2. Poll with a bound
The status response carriesrequest.state, request.partial, and request.finalized. Poll at a bounded interval and stop after a fixed number of attempts:
partial is true, result pages are a progress view, not proof that collection is complete. countsMayChange: true means later processing can still change the counters; terminal non-finalized failures can be partial while reporting countsMayChange: false. For a complete export, wait for finalized: true, then paginate.
3. Retrieve every result with the cursor
limit accepts 1–200. cursor/nextCursor is the canonical pagination contract. Continue until nextCursor is null; treat cursors as opaque. offset remains available for compatibility but should not be used for a new full export.
The script below writes pages to a temporary file and replaces the final export only after a validated terminal page. It retries 429 and temporary 5xx responses within explicit attempt and delay bounds. A permanent HTTP error, invalid JSON, missing nextCursor, repeated cursor, or page-budget overrun exits non-zero and preserves any earlier completed export.