{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/enums/notification-type.json",
  "title": "Notification Type",
  "description": "Type of push notification fired by a seller agent. Media-buy-anchored notifications (`scheduled`, `final`, `delayed`, `adjusted`, `window_update`, `impairment`) fire against a media buy's `push_notification_config`. Account-anchored notifications (`creative.status_changed`, `creative.assignment_changed`, `indicators.changed`, `creative.purged`, `account.status_changed`, `product.*`, `signal.*`, `wholesale_feed.bulk_change`) fire against an account's `notification_configs[]` entries whose `event_types` include the value — these outlive any single media buy and anchor at the account. `indicators.changed` and `creative.assignment_changed` are invalidations repaired completely through `get_media_buys`; `list_creatives` may provide a bounded reverse projection. Agent-anchored notifications (`capabilities.changed`) fire against the agent-level subscriber set managed by `sync_agent_notification_configs`; they are valid before a buyer has any account. Account status changes use `account.status_changed` as an invalidation signal; receivers repair by re-reading `list_accounts`. Wholesale feed notifications carry the actual change payload in `/schemas/core/wholesale-feed-webhook.json`; product mirrors repair through `list_products` using `if_feed_version` and signal mirrors through `get_signals` using `if_wholesale_feed_version` (`get_products` remains the deprecated 3.x product fallback). Capability-change notifications carry only an invalidation payload in `/schemas/core/capabilities-changed-webhook.json`; receivers repair by re-reading `get_adcp_capabilities`. New notification types added to this enum MUST declare their anchor (media-buy, account, or agent), logical `notification_id` semantics, and repair key in the enumDescription. Sellers MUST reject `notification_configs[]` entries whose `event_types` include any media-buy-anchored or agent-anchored type, MUST reject `sync_agent_notification_configs` entries whose `event_types` include any media-buy-anchored or account-anchored type, and MUST reject `push_notification_config` registrations for persistent account-anchored or agent-anchored types.",
  "type": "string",
  "enum": [
    "scheduled",
    "final",
    "delayed",
    "adjusted",
    "window_update",
    "impairment",
    "creative.status_changed",
    "creative.assignment_changed",
    "indicators.changed",
    "creative.purged",
    "account.status_changed",
    "product.created",
    "product.updated",
    "product.priced",
    "product.removed",
    "signal.created",
    "signal.updated",
    "signal.priced",
    "signal.removed",
    "wholesale_feed.bulk_change",
    "capabilities.changed"
  ],
  "enumDescriptions": {
    "scheduled": "Scheduled delivery report fire. Fired at the cadence the buyer registered on reporting_webhook (e.g., hourly, daily). Carries the window's delivery metrics. **notification_id**: absent — point-in-time data event with no persistent state id (snapshot-and-log Rule 1). Dedupe by `idempotency_key` only.",
    "final": "Terminal delivery report fire. Sent once after the media buy reaches a terminal lifecycle state (completed, canceled, rejected). Carries final delivery aggregates. **notification_id**: absent — point-in-time data event with no persistent state id (snapshot-and-log Rule 1). Dedupe by `idempotency_key` only.",
    "delayed": "Off-cadence delivery report fire indicating that the seller has detected late-arriving data for a prior window. Buyers SHOULD reconcile the affected window against this fire. **notification_id**: absent — point-in-time data event with no persistent state id (snapshot-and-log Rule 1). Dedupe by `idempotency_key` only.",
    "adjusted": "Off-cadence delivery report fire indicating that the seller has revised a prior window's metrics (e.g., IVT filtering applied, attribution model run, makegood adjustment). Buyers SHOULD replace prior values for the affected window. **notification_id**: absent — point-in-time data event with no persistent state id (snapshot-and-log Rule 1). Dedupe by `idempotency_key` only.",
    "window_update": "Off-cadence delivery report fire indicating that a wider measurement window supersedes an earlier window for the same reporting period (for example, C3 superseding live or C7 superseding C3). Buyers SHOULD replace the slice named by `supersedes_window` with the new `measurement_window` data. **notification_id**: absent — point-in-time data event with no persistent state id (snapshot-and-log Rule 1). Dedupe by `idempotency_key` only.",
    "impairment": "Dependency state change fire. Sent when a resource referenced by the buy enters an offline state that affects delivery for at least one package. Payload carries the impairment object and the buy's updated health. See impairment.json and the impairment.coherence assertion. **notification_id**: equals `impairment.impairment_id`. Stable across re-emissions of the same open impairment and across the closing fire that signals resolution; a new impairment for the same resource after closure receives a new id.",
    "creative.status_changed": "Account-anchored fire. Sent when a creative in the account's library transitions status by seller or system initiative — `pending_review → approved`/`rejected`, `approved → pending_review` (re-review), `approved → suspended` (recoverable dependency/authorization loss), `suspended → approved` (recovery), `suspended → rejected` (terminal dependency/authorization loss), `approved → rejected` (post-approval revocation), `approved → archived` (seller-initiated). Fires per subscriber against each `notification_configs[]` entry whose `event_types` includes this value. Buyer-initiated transitions (archive, unarchive, resubmit) do NOT fire — those are acknowledged on the `sync_creatives` response path. Payload: `creative-status-changed-webhook.json`. **notification_id**: stable per (creative_id, transition) — re-emissions reuse the id; a fresh transition gets a new id.",
    "creative.assignment_changed": "Optional account-anchored invalidation for any seller that can detect assignment or approval changes, including inline-only sellers without an indicator catalog. Sent when a package–creative relationship is assigned, unassigned, or its aggregate/scoped approval outcome changes. Payload identifies account, media buy, package, and creative; receivers repair through get_media_buys. list_creatives may provide a bounded reverse projection but is not required. **notification_id**: stable per logical assignment change across re-emissions.",
    "indicators.changed": "Account-anchored invalidation. Sent to subscribed buyers when the semantic indicator assertion set or evaluated coverage changes on a media buy, package, or package–creative assignment, including invalidation after a material in-place creative update. A timestamp-only reevaluation does not fire. Payload identifies the relationship and affected types; get_media_buys is the universal repair path and creative-library sellers may additionally declare list_creatives. **notification_id**: stable per logical snapshot change across re-emissions.",
    "creative.purged": "Account-anchored fire. Sent when a creative is destroyed from the seller's library (retention sweep, takedown, legal erasure). Fires per subscriber against each `notification_configs[]` entry whose `event_types` includes this value. Soft purges retain a tombstone on `list_creatives` (with `include_purged: true`) for the webhook retention window and form a conformant snapshot/log pair. Hard purges do not retain a tombstone because compelled legal erasure forbids read-side recovery; they are explicitly outside the snapshot/log contract, and the webhook is the buyer's only signal. Payload: `creative-purged-webhook.json`. **notification_id**: stable per (creative_id, purge event); not coalesced (purge is a discrete destruction event).",
    "account.status_changed": "Account-anchored fire. Sent when an account lifecycle status changes after the initial sync_accounts result, including `pending_approval -> active`, `pending_approval -> rejected`, `active -> payment_required`, `active -> suspended`, recovery back to `active`, and terminal `closed`. Fires per subscriber against each `notification_configs[]` entry whose `event_types` includes this value. Payload: `account-status-changed-webhook.json`. The payload does not include the full account document or setup.url; receivers SHOULD re-run `list_accounts` for the account_id and reconcile from the authoritative account snapshot. **notification_id**: stable per (account_id, previous_status, status, observed_at) — re-emissions reuse the id; a fresh transition cycle receives a new id.",
    "product.created": "Sent when a new product is added to the seller's wholesale product feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `product.created` event with the full post-change Product object. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "product.updated": "Sent when product metadata changes in the seller's wholesale product feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `product.updated` event with the changed Product object when available and indicator `changed_fields[]`. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "product.priced": "Sent when product pricing changes in the seller's wholesale product feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `product.priced` event with the full post-change `pricing_options[]`, optional retired pricing ids, and optional `effective_at`. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "product.removed": "Sent when a product is no longer available in the seller's wholesale product feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `product.removed` event with the product id, optional removal reason, and cache scope. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "signal.created": "Sent when a new signal is added to the seller's wholesale signals feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `signal.created` event with the post-change signal identifiers and available metadata. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "signal.updated": "Sent when signal metadata changes in the seller's wholesale signals feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `signal.updated` event with the changed signal data when available and indicator `changed_fields[]`. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "signal.priced": "Sent when signal pricing changes in the seller's wholesale signals feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `signal.priced` event with the full post-change `pricing_options[]`, optional retired pricing ids, and optional `effective_at`. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "signal.removed": "Sent when a signal is no longer available in the seller's wholesale signals feed for the subscriber's account scope. Payload: `wholesale-feed-webhook.json` carrying a `signal.removed` event with the signal id, optional removal reason, and cache scope. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "wholesale_feed.bulk_change": "Sent when one operation changes too many wholesale product-feed or wholesale signals-feed entities for useful per-entity pushes. Payload: `wholesale-feed-webhook.json` carrying a `wholesale_feed.bulk_change` event with one affected entity type, approximate count, and repair recommendation. Receivers repair products through `list_products` (or deprecated 3.x `get_products`) and signals through `get_signals`. **notification_id**: equals `event.event_id`; re-emissions of the same logical change reuse the same value under a new `idempotency_key`.",
    "capabilities.changed": "Agent-anchored fire. Sent when the seller's advertised `get_adcp_capabilities` document materially changes. Fires per subscriber against each `sync_agent_notification_configs.notification_configs[]` entry whose `event_types` includes this value. Payload: `capabilities-changed-webhook.json`. The payload does not include the full capability document; receivers SHOULD re-run `get_adcp_capabilities`, compare `adcp.capability_changes.capabilities_version` or `last_modified` when present, and update their cache from that fresh response. **notification_id**: stable per material capability revision; re-emissions of the same revision reuse the id, and a later material revision receives a new id."
  }
}
