ok: true and place their payload in data. Errors use this shape:
details and requestId are optional. Use error.code for machine handling and error.message to explain the failure. Preserve any details that identify affected entities.
Choose the next action by failure type
For example, retrying an offer archive will not solve
offer is used by rotators. Remove or replace the offer in the relevant rotator pools first, then repeat the archive. See Archive and restore.
Retry temporary failures deliberately
ForRATE_LIMITED, honor Retry-After when supplied and reduce request concurrency. If no retry delay is provided, use a bounded backoff rather than a tight loop.
An event query can return SCROLL_BUDGET_EXCEEDED when it cannot advance within its scan budget. Shorten the date range or narrow the campaign and event type. Repeating the same broad query faster does not reduce the work it requires.
A BAD_CURSOR needs a new event query without the old cursor. Keep the original dates and filters for a continued scroll. Changing the query while reusing its cursor invalidates that continuation.
For a timeout or temporary failure during a write, first check whether the intended change already exists. A lost response does not prove that the server rejected the operation. Avoid blindly resending a create request and producing a duplicate entity.
Capture enough context to investigate
Log the HTTP method, public endpoint path, status, error code, request ID when present, and the relevant non-secret entity IDs. For report issues, include the date range and timezone. Keep Authorization headers and credentials out of logs. Raw event responses can contain request-level visitor data, so store only the fields needed for the investigation. Ifwhoami succeeds and a small report query succeeds, expand the request one choice at a time. Add the desired dimensions, then filters, then a larger date range. The first change that fails gives you a concrete request to correct or report.