list_account_changes returns material changes to AdCP-visible state on one
account, including changes made outside the observing buyer’s calls. Use it
after a snapshot bootstrap, after receiving account.change_recorded, or for
an account-level audit of state transitions.
The feed is optional and appears only when
get_adcp_capabilities.account.change_feed.supported is true.
What the feed covers
For every resource type the seller advertises, a material committed change must both appear here and be reflected on its authoritative read, regardless of whether it originated through AdCP, a seller operator or system, another authorized principal, or a connected platform. The feed describes control-plane changes: creation, configuration, lifecycle, relationships, reporting corrections, and deletion markers. It excludes reads, failed operations, dry runs, exact idempotency replays, delivery counter increments, raw audience members, raw events, catalog item bodies, and webhook delivery attempts. For the complete coverage matrix and rationale, see the account change feed draft.Request
Request schema:account/list-account-changes-request.json
Acquire a high-water checkpoint before reading several snapshots:
Response
Response schema:account/list-account-changes-response.json
Each change record names the changed resource, action, server-derived origin,
optional changed paths and revision, and an allowlisted read-only
repair.task hint. It deliberately does not include full before/after values.
Cursor contract
Cursor order, not timestamps, defines the total order. Appends never reorder prior pages. A filtered empty page still advances across scanned nonmatching records, so persist every returned cursor. A cursor is scoped to the authenticated principal, resolved account, and normalized filters. Do not move it between credentials or filter sets. Sellers MUST reject a principal, account, or filter mismatch withINVALID_REQUEST at
cursor; applying new filters at an old position could permanently skip
history.
The cursor also binds an authorization-scope epoch. If visible resources for
the principal expand or contract, the seller returns CURSOR_EXPIRED with
details.reason: "authorization_scope_changed". Rebootstrap snapshots so
changes skipped under the old visibility cannot become an invisible gap.
Sellers retain changes for at least 90 days. An expired cursor returns
CURSOR_EXPIRED; it never silently restarts. Recovery is to obtain a new
latest checkpoint, rebuild all authoritative snapshots, then drain changes
after the checkpoint.
Race-free bootstrap
- Register
account.change_recordedthroughsync_accounts. - Obtain C0 with
starting_position: "latest". - Enumerate
list_accounts,get_media_buys,list_creatives, financials, delivery, and other advertised reads for the account. Include all lifecycle statuses and exhaust every page. - Drain changes after C0. Locally allowlist
repair.task, construct and validate the read request from the authenticated account andresourceidentity, then invoke it. Never dispatch feed-supplied task arguments. - Persist the returned cursor and repeat after each signed notification.
- Poll periodically so a missed webhook does not create a gap.
through_cursor is only a target watermark. Do not
install it without reading all intervening pages.
Change granularity
The feed contains at least one record per independently repairable identity. Several package or assignment changes may coalesce under their media buy whenget_media_buys repairs the complete changed closure; changes to independent
creatives require separate records. Records from one operation may share
batch_id, but retain independent change_id values and notifications.
For seller-mediated mutations, snapshot and records commit atomically. For an
external platform, records commit with the seller’s ingestion of the observed
change. A pass-through authoritative read may lead the feed only within the
source’s declared stale_after_seconds freshness bound.
Shared-account example
Suppose a connected platform changescr_8421 while the buyer is idle. The
seller records the creative revision, makes it visible on list_creatives,
appends the account change, and then fires account.change_recorded. The buyer
drains from its cursor and rereads list_creatives; it does not treat the
webhook payload as the creative document.
This is the same flow for a seller operator changing a campaign budget or
another authorized buyer pausing a package. Account visibility is based on
current authorization, not on which principal created the resource.
Relationship to webhook_activity
webhook_activity[] answers whether a webhook delivery was attempted. This
feed answers which material business-state changes were recorded. A change can
exist even when a webhook is missed; one change can also have several delivery
attempts. Never use the transport log as account history.