From f0124f2a327e7702a6fdb50c950e7374a2ef6896 Mon Sep 17 00:00:00 2001 From: garvitkaushik-123 Date: Sun, 28 Jun 2026 01:44:06 +0530 Subject: [PATCH] fix(docs): update 225 broken internal links after building/ restructure The docs/building/ tree was reorganized from flat implementation/integration/understanding directories into by-layer/L0-L4, concepts, operating, and verification, but cross-references in 86 files still pointed at the old paths. Co-Authored-By: Claude Opus 4.6 --- docs/accounts/overview.mdx | 6 +++--- .../accounts/tasks/get_account_financials.mdx | 4 ++-- docs/accounts/tasks/list_accounts.mdx | 4 ++-- docs/accounts/tasks/report_usage.mdx | 4 ++-- docs/accounts/tasks/sync_accounts.mdx | 16 +++++++-------- docs/accounts/tasks/sync_governance.mdx | 6 +++--- .../brand-protocol/building-a-brand-agent.mdx | 2 +- docs/building/by-layer/L1/request-signing.mdx | 4 ++-- .../verification/addie-socket-mode.mdx | 6 +++--- docs/creative/catalogs.mdx | 4 ++-- docs/creative/multi-agent-orchestration.mdx | 2 +- docs/creative/specification.mdx | 2 +- .../task-reference/build_creative.mdx | 2 +- .../task-reference/get_creative_delivery.mdx | 2 +- .../task-reference/list_creatives.mdx | 4 ++-- .../task-reference/sync_creatives.mdx | 2 +- docs/faq.mdx | 12 +++++------ docs/governance/campaign/index.mdx | 2 +- docs/governance/campaign/safety-model.mdx | 2 +- docs/governance/campaign/specification.mdx | 16 +++++++-------- .../campaign/tasks/check_governance.mdx | 12 +++++------ .../campaign/tasks/get_plan_audit_logs.mdx | 2 +- docs/governance/campaign/tasks/sync_plans.mdx | 2 +- .../tasks/get_media_buy_artifacts.mdx | 2 +- .../creative/get_creative_features.mdx | 2 +- docs/governance/creative/index.mdx | 2 +- docs/governance/property/specification.mdx | 2 +- .../property/tasks/property_lists.mdx | 2 +- docs/intro.mdx | 4 ++-- .../foundations/a1-agentic-advertising.mdx | 4 ++-- .../foundations/a2-protocol-architecture.mdx | 4 ++-- .../a2b-testing-your-first-agent.mdx | 2 +- .../foundations/a3-ecosystem-governance.mdx | 2 +- docs/learning/instructional-design.mdx | 2 +- docs/learning/specialist/creative.mdx | 2 +- docs/learning/specialist/governance.mdx | 2 +- docs/learning/specialist/media-buy.mdx | 4 ++-- docs/learning/specialist/security.mdx | 8 ++++---- docs/learning/specialist/signals.mdx | 2 +- .../specialist/sponsored-intelligence.mdx | 4 ++-- docs/learning/tracks/buyer.mdx | 6 +++--- docs/learning/tracks/platform.mdx | 20 +++++++++---------- docs/learning/tracks/publisher.mdx | 6 +++--- .../advanced-topics/accounts-and-security.mdx | 6 +++--- .../agentic-execution-engine.mdx | 2 +- docs/media-buy/advanced-topics/index.mdx | 4 ++-- docs/media-buy/commerce-media.mdx | 10 +++++----- docs/media-buy/media-buys/index.mdx | 6 +++--- .../media-buys/optimization-reporting.mdx | 10 +++++----- .../product-discovery/refinement.mdx | 2 +- docs/media-buy/specification.mdx | 2 +- .../task-reference/create_media_buy.mdx | 10 +++++----- .../task-reference/get_media_buy_delivery.mdx | 4 ++-- .../task-reference/get_media_buys.mdx | 2 +- .../media-buy/task-reference/get_products.mdx | 4 ++-- docs/media-buy/task-reference/index.mdx | 2 +- .../task-reference/sync_audiences.mdx | 4 ++-- .../task-reference/sync_catalogs.mdx | 6 +++--- .../task-reference/sync_event_sources.mdx | 2 +- .../task-reference/update_media_buy.mdx | 10 +++++----- docs/protocol/architecture.mdx | 4 ++-- docs/protocol/design-principles.mdx | 2 +- docs/protocol/get_adcp_capabilities.mdx | 12 +++++------ docs/protocol/required-tasks.mdx | 2 +- docs/quickstart.mdx | 6 +++--- docs/reference/glossary.mdx | 12 +++++------ docs/reference/known-limitations.mdx | 6 +++--- docs/reference/migration/index.mdx | 10 +++++----- docs/reference/migration/media-buy-status.mdx | 2 +- .../migration/prerelease-upgrades.mdx | 4 ++-- docs/reference/migration/v3-readiness.mdx | 2 +- docs/reference/privacy-considerations.mdx | 16 +++++++-------- docs/reference/release-notes.mdx | 4 ++-- docs/reference/schema-extensions.mdx | 6 +++--- docs/reference/test-vectors/index.mdx | 8 ++++---- docs/reference/url-canonicalization.mdx | 6 +++--- docs/reference/versioning.mdx | 2 +- docs/reference/whats-new-in-v3.mdx | 8 ++++---- docs/signals/ecosystem.mdx | 4 ++-- docs/signals/specification.mdx | 6 +++--- docs/signals/tasks/activate_signal.mdx | 6 +++--- docs/signals/tasks/get_signals.mdx | 2 +- docs/sponsored-intelligence/specification.mdx | 2 +- .../tasks/si_initiate_session.mdx | 2 +- docs/trust.mdx | 2 +- docs/trusted-match/specification.mdx | 4 ++-- 86 files changed, 213 insertions(+), 213 deletions(-) diff --git a/docs/accounts/overview.mdx b/docs/accounts/overview.mdx index 3d0a190c6d..93e8b56a8a 100644 --- a/docs/accounts/overview.mdx +++ b/docs/accounts/overview.mdx @@ -41,7 +41,7 @@ The Accounts Protocol applies across all vendor protocols. An orchestrator estab | Governance | Content standards billing | | Creative | Creative service billing | -The account reference may be a seller-assigned `account_id` (seller-owned namespaces, usually `require_operator_auth: true`) or a natural key — `brand` + `operator` (buyer-declared accounts, `require_operator_auth: false`). For buyer-declared accounts, the natural-key `AccountRef` MUST remain valid on subsequent calls even if the seller also echoes an internal `account_id`. For sandbox, account-id namespaces use pre-existing test accounts discovered via `list_accounts` or supplied out-of-band, while buyer-declared accounts declare sandbox via `sync_accounts` with `sandbox: true`. See [Account references](/docs/building/integration/accounts-and-agents#account-references) for details. +The account reference may be a seller-assigned `account_id` (seller-owned namespaces, usually `require_operator_auth: true`) or a natural key — `brand` + `operator` (buyer-declared accounts, `require_operator_auth: false`). For buyer-declared accounts, the natural-key `AccountRef` MUST remain valid on subsequent calls even if the seller also echoes an internal `account_id`. For sandbox, account-id namespaces use pre-existing test accounts discovered via `list_accounts` or supplied out-of-band, while buyer-declared accounts declare sandbox via `sync_accounts` with `sandbox: true`. See [Account references](/docs/building/by-layer/L2/accounts-and-agents#account-references) for details. ## Account Status Lifecycle @@ -182,7 +182,7 @@ A single `SCOPE_INSUFFICIENT` response is observationally indistinguishable betw `FIELD_NOT_PERMITTED` does not follow this pattern. The agent-autonomous recovery path — strip the disallowed field and resubmit — supersedes the retry consideration. Buyers MUST NOT retry the identical failing request for `FIELD_NOT_PERMITTED`; they SHOULD correct and resubmit immediately. -See [Authorization (RBAC)](/docs/building/implementation/error-handling#authorization-rbac) for the normative retry exception clause on these codes. +See [Authorization (RBAC)](/docs/building/by-layer/L3/error-handling#authorization-rbac) for the normative retry exception clause on these codes. ### Standard named scope: `attestation_verifier` @@ -258,7 +258,7 @@ The introspection model — "the caller asks the authorization-enforcing party w ## Parties -The Accounts Protocol operates with four party types. See [Accounts and agents](/docs/building/integration/accounts-and-agents) for full details on billing hierarchy, trust models, and authorized operators. +The Accounts Protocol operates with four party types. See [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) for full details on billing hierarchy, trust models, and authorized operators. | Party | Role | Identified by | |-----------|------|---------------| diff --git a/docs/accounts/tasks/get_account_financials.mdx b/docs/accounts/tasks/get_account_financials.mdx index 866bf2aeac..b2d8cf231d 100644 --- a/docs/accounts/tasks/get_account_financials.mdx +++ b/docs/accounts/tasks/get_account_financials.mdx @@ -76,7 +76,7 @@ asyncio.run(main()) | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | object | Yes | [Account reference](/docs/building/integration/accounts-and-agents#account-references) — by `account_id` or natural key (`brand` + `operator` + optional `sandbox`). Must be an operator-billed account. | +| `account` | object | Yes | [Account reference](/docs/building/by-layer/L2/accounts-and-agents#account-references) — by `account_id` or natural key (`brand` + `operator` + optional `sandbox`). Must be an operator-billed account. | | `period` | object | No | Date range for spend summary: `start` and `end` as ISO 8601 dates. Defaults to the current billing cycle if omitted. | ## Response @@ -230,4 +230,4 @@ asyncio.run(main()) - [list_accounts](/docs/accounts/tasks/list_accounts) -- Discover accounts and check their status - [get_adcp_capabilities](/docs/protocol/get_adcp_capabilities) -- Check `account_financials` before calling this task -- [Accounts and agents](/docs/building/integration/accounts-and-agents) -- Billing models and account references +- [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) -- Billing models and account references diff --git a/docs/accounts/tasks/list_accounts.mdx b/docs/accounts/tasks/list_accounts.mdx index 3ef0fa9f28..e9c2015468 100644 --- a/docs/accounts/tasks/list_accounts.mdx +++ b/docs/accounts/tasks/list_accounts.mdx @@ -92,7 +92,7 @@ the authenticated caller. Use `account` when re-reading one known account by | `operator` | Operator domain. Always present — when the brand operates directly, `operator` equals the brand's domain. | | `status` | Current account state: `active`, `pending_approval`, `rejected`, `payment_required`, `suspended`, or `closed` | | `billing` | Billing model in effect: `operator` or `agent` | -| `account_scope` | How the seller scoped this account: `operator`, `brand`, `operator_brand`, or `agent`. See [account scope](/docs/building/integration/accounts-and-agents#account-scope). | +| `account_scope` | How the seller scoped this account: `operator`, `brand`, `operator_brand`, or `agent`. See [account scope](/docs/building/by-layer/L2/accounts-and-agents#account-scope). | | `payment_terms` | Payment terms agreed for this account: `net_15`, `net_30`, `net_45`, `net_60`, `net_90`, or `prepay`. Binding for all invoices when the account is active. | | `governance_agents` | Governance agent endpoints registered on this account. Present when governance agents have been configured via [`sync_governance`](/docs/accounts/tasks/sync_governance). | | `setup` | Present when `status: "pending_approval"`. Contains `url` for completing setup and `message` explaining what's needed. | @@ -229,5 +229,5 @@ asyncio.run(main()) - [sync_accounts](/docs/accounts/tasks/sync_accounts) — Sync advertiser accounts with a seller - [sync_governance](/docs/accounts/tasks/sync_governance) — Sync governance agents to accounts -- [Accounts and agents](/docs/building/integration/accounts-and-agents) — Billing models, trust models, and authorized operators +- [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) — Billing models, trust models, and authorized operators - [Brand protocol](/docs/brand-protocol/brand-json) — How vendor agents resolve brand identity from the brand's `domain` diff --git a/docs/accounts/tasks/report_usage.mdx b/docs/accounts/tasks/report_usage.mdx index b45127aa23..ca33297a3d 100644 --- a/docs/accounts/tasks/report_usage.mdx +++ b/docs/accounts/tasks/report_usage.mdx @@ -28,7 +28,7 @@ Each record requires `account`, `vendor_cost`, and `currency`. Additional fields | Field | Type | Required | Description | |-------|------|----------|-------------| -| `account` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references) | Yes | Account for this record — by `account_id` or `{ brand, operator }`. | +| `account` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Yes | Account for this record — by `account_id` or `{ brand, operator }`. | | `vendor_cost` | number | Yes | Amount owed to the vendor for this record, in `currency` | | `currency` | string | Yes | ISO 4217 currency code | | `pricing_option_id` | string | Vendor: Yes | Pricing option from the vendor's discovery response (`get_signals`, `list_creatives`, `list_content_standards`, `list_property_lists`) or execution response (`build_creative`). The vendor uses this to verify the correct rate was applied. | @@ -187,4 +187,4 @@ Report upon campaign completion to close out the final period. - [sync_accounts](/docs/accounts/tasks/sync_accounts) — Sync advertiser accounts with a seller before reporting - [Accounts Protocol](/docs/accounts/overview) — How account establishment and settlement fit together -- [Accounts and agents](/docs/building/integration/accounts-and-agents) — Billing hierarchy and operator model +- [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) — Billing hierarchy and operator model diff --git a/docs/accounts/tasks/sync_accounts.mdx b/docs/accounts/tasks/sync_accounts.mdx index e9bf6b67ec..9c33e3898a 100644 --- a/docs/accounts/tasks/sync_accounts.mdx +++ b/docs/accounts/tasks/sync_accounts.mdx @@ -95,8 +95,8 @@ asyncio.run(main()) |-------|------|----------|-------------| | `brand` | object | Yes | Brand reference identifying the advertiser. Contains `domain` (house domain where brand.json is hosted) and optional `brand_id` (for multi-brand houses). See [brand-ref](/docs/brand-protocol/brand-json). | | `operator` | string | Yes | Domain of the entity operating on the brand's behalf (e.g. `pinnacle-media.com`). When the brand operates directly, set to the brand's domain. Verified against the brand's `authorized_operators` in brand.json. | -| `billing` | string | Yes | Who should be invoiced: `operator`, `agent`, or `advertiser`. Check `get_adcp_capabilities` for `supported_billing` to see what the seller accepts at the capability level. The seller must either accept this billing model or reject the request. Sellers MAY additionally reject a value the seller-wide capability accepts when the calling buyer agent's commercial relationship does not permit it — e.g., a buyer agent onboarded as passthrough-only (no payments relationship — only the operator can be invoiced). The two gates use distinct error codes — `BILLING_NOT_SUPPORTED` for the seller-wide capability gate, `BILLING_NOT_PERMITTED_FOR_AGENT` for the per-buyer-agent gate — so agents can dispatch on autonomous-retry vs human-onboarding without parsing prose. See [Buyer-agent identity](/docs/building/integration/accounts-and-agents#buyer-agent-identity) and [Billing and Account Setup](/docs/building/implementation/error-handling#billing-and-account-setup). | -| `billing_entity` | object | No | Structured business entity details for the party responsible for payment. Contains `legal_name` (required), plus optional `vat_id`, `tax_id`, `registration_number`, `address`, `contacts`, and `bank`. Bank details are write-only — included in requests but never echoed in responses. See [billing entity and invoice recipient](/docs/building/integration/accounts-and-agents#billing-entity-and-invoice-recipient). | +| `billing` | string | Yes | Who should be invoiced: `operator`, `agent`, or `advertiser`. Check `get_adcp_capabilities` for `supported_billing` to see what the seller accepts at the capability level. The seller must either accept this billing model or reject the request. Sellers MAY additionally reject a value the seller-wide capability accepts when the calling buyer agent's commercial relationship does not permit it — e.g., a buyer agent onboarded as passthrough-only (no payments relationship — only the operator can be invoiced). The two gates use distinct error codes — `BILLING_NOT_SUPPORTED` for the seller-wide capability gate, `BILLING_NOT_PERMITTED_FOR_AGENT` for the per-buyer-agent gate — so agents can dispatch on autonomous-retry vs human-onboarding without parsing prose. See [Buyer-agent identity](/docs/building/by-layer/L2/accounts-and-agents#buyer-agent-identity) and [Billing and Account Setup](/docs/building/by-layer/L3/error-handling#billing-and-account-setup). | +| `billing_entity` | object | No | Structured business entity details for the party responsible for payment. Contains `legal_name` (required), plus optional `vat_id`, `tax_id`, `registration_number`, `address`, `contacts`, and `bank`. Bank details are write-only — included in requests but never echoed in responses. See [billing entity and invoice recipient](/docs/building/by-layer/L2/accounts-and-agents#billing-entity-and-invoice-recipient). | | `payment_terms` | string | No | Payment terms for this account: `net_15`, `net_30`, `net_45`, `net_60`, `net_90`, or `prepay`. The seller must either accept these terms or reject the account — terms are never silently remapped. When omitted, the seller applies its default terms. | | `sandbox` | boolean | No | When true, set up a sandbox account with no real platform calls or billing. Only applicable to buyer-declared accounts (`require_operator_auth: false`). For account-id namespaces, sandbox accounts are pre-existing test accounts discovered via `list_accounts` or supplied out-of-band. | | `notification_configs` | array | No | Account-level webhook subscribers for events that outlive any single media buy: creative lifecycle notifications and wholesale feed change webhooks. Omit to leave existing subscribers unchanged; send `[]` to remove all subscribers; send a full array to replace. Entries are keyed by account-scoped `subscriber_id`; an existing `subscriber_id` is upserted, and persisted IDs absent from the sent array are removed. | @@ -126,7 +126,7 @@ Returns an `accounts` array with per-account results. Individual accounts may be | `status` | Current state of the account (see [Account status](#account-status)). | | `billing` | Billing model applied. Matches the requested value. | | `billing_entity` | Business entity details for the invoiced party, echoed from the request. Sellers may add fields the agent omitted (e.g., `registration_number` from a credit check) but must not return data from a different entity. Bank details are omitted (write-only). | -| `account_scope` | How the seller scoped this account: `operator` (shared across brands for this operator), `brand` (shared across operators for this brand), `operator_brand` (dedicated to this operator+brand pair), or `agent` (agent-scoped account shared across declared brand/operator pairs). See [account scope](/docs/building/integration/accounts-and-agents#account-scope). | +| `account_scope` | How the seller scoped this account: `operator` (shared across brands for this operator), `brand` (shared across operators for this brand), `operator_brand` (dedicated to this operator+brand pair), or `agent` (agent-scoped account shared across declared brand/operator pairs). See [account scope](/docs/building/by-layer/L2/accounts-and-agents#account-scope). | | `setup` | Present when `status: "pending_approval"`. Contains `url` for completing credit or legal setup, `message` explaining what's needed, and optional `expires_at`. | | `rate_card` | Seller-assigned rate card identifier (when applicable). | | `payment_terms` | Payment terms agreed for this account: `net_15`, `net_30`, `net_45`, `net_60`, `net_90`, or `prepay`. When the account is active, these are the binding terms for all invoices. | @@ -141,7 +141,7 @@ Returns an `accounts` array with per-account results. Individual accounts may be | Status | Meaning | Next step | |--------|---------|-----------| -| `active` | Ready to use | Use [account reference](/docs/building/integration/accounts-and-agents#account-references) in protocol operations | +| `active` | Ready to use | Use [account reference](/docs/building/by-layer/L2/accounts-and-agents#account-references) in protocol operations | | `pending_approval` | Seller reviewing | Human may need to visit `setup.url` to complete credit or legal process. Poll `list_accounts` for updates. | | `rejected` | Seller declined the request | Review rejection reason in `warnings`, adjust and retry, or contact seller | | `payment_required` | Credit limit reached or funds depleted | Add funds or increase credit limit. Route spend to other accounts. | @@ -170,7 +170,7 @@ If the buyer did not provide `push_notification_config`, poll [`list_accounts`]( Each per-account entry uses one of two key shapes, never both: - **Provisioning mode** — flat `brand` + `operator` + `billing` at the entry root. The seller provisions or upserts accounts. Used for buyer-declared accounts (`require_operator_auth: false`). This is the shape AdCP 3.0 shipped with. Sellers MAY echo an `account_id`, but the natural-key `AccountRef` remains valid for subsequent calls. -- **Settings-update mode** — `account` (an [AccountRef](/docs/building/integration/accounts-and-agents#account-references)) at the entry root, with `brand`/`operator`/`billing` absent. The seller updates the account's settable state — no provisioning side effects. Used for account-id namespaces only when the seller exposes settings updates through this task; upstream-managed accounts are discovered via `list_accounts`, while seller-defined account IDs may be supplied out-of-band. Buyer-declared account sellers MAY also accept this mode for settings updates against accounts they previously provisioned. +- **Settings-update mode** — `account` (an [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references)) at the entry root, with `brand`/`operator`/`billing` absent. The seller updates the account's settable state — no provisioning side effects. Used for account-id namespaces only when the seller exposes settings updates through this task; upstream-managed accounts are discovered via `list_accounts`, while seller-defined account IDs may be supplied out-of-band. Buyer-declared account sellers MAY also accept this mode for settings updates against accounts they previously provisioned. Schema enforces the exclusivity via `oneOf` — sending both shapes on the same entry is a validation error. Sellers that don't implement settings-update mode reject `account`-keyed entries with `UNSUPPORTED_PROVISIONING`; sellers that don't provision through `sync_accounts`, including account-id namespaces, reject natural-key provisioning entries with the same code. @@ -520,8 +520,8 @@ asyncio.run(main()) | Error Code | Description | Resolution | |------------|-------------|------------| | `ACCOUNT_NOT_FOUND` | Referenced account does not exist or is not accessible | Check `account_id` or re-sync | -| `BILLING_NOT_SUPPORTED` | Seller-wide capability gate (`supported_billing` does not include the value) or per-account-relationship gate; see [Billing and Account Setup](/docs/building/implementation/error-handling#billing-and-account-setup) | Check `get_adcp_capabilities` for `supported_billing`, adjust or omit `billing`; inspect `error.details.scope` to disambiguate capability vs account scope | -| `BILLING_NOT_PERMITTED_FOR_AGENT` | Seller-wide capability accepts the value, but the calling buyer agent's commercial relationship does not (e.g., passthrough-only — no payments relationship); see [Buyer-agent identity](/docs/building/integration/accounts-and-agents#buyer-agent-identity) | Retry with `error.details.suggested_billing` (typically `operator`) when present; when absent, surface to a human — the agent cannot extend its own commercial relationship | +| `BILLING_NOT_SUPPORTED` | Seller-wide capability gate (`supported_billing` does not include the value) or per-account-relationship gate; see [Billing and Account Setup](/docs/building/by-layer/L3/error-handling#billing-and-account-setup) | Check `get_adcp_capabilities` for `supported_billing`, adjust or omit `billing`; inspect `error.details.scope` to disambiguate capability vs account scope | +| `BILLING_NOT_PERMITTED_FOR_AGENT` | Seller-wide capability accepts the value, but the calling buyer agent's commercial relationship does not (e.g., passthrough-only — no payments relationship); see [Buyer-agent identity](/docs/building/by-layer/L2/accounts-and-agents#buyer-agent-identity) | Retry with `error.details.suggested_billing` (typically `operator`) when present; when absent, surface to a human — the agent cannot extend its own commercial relationship | | `PAYMENT_TERMS_NOT_SUPPORTED` | Seller does not accept the requested payment terms | Omit `payment_terms` to accept the seller's default, or negotiate offline | | `ACCOUNT_PAYMENT_REQUIRED` | Account has an outstanding balance requiring payment | Resolve outstanding balance or route to another account | | `ACCOUNT_SUSPENDED` | Account is suspended | Contact seller to resolve | @@ -531,6 +531,6 @@ asyncio.run(main()) - [list_accounts](/docs/accounts/tasks/list_accounts) -- Poll for status changes on pending accounts - [sync_governance](/docs/accounts/tasks/sync_governance) -- Sync governance agents to accounts -- [Accounts and agents](/docs/building/integration/accounts-and-agents) -- Billing models, trust models, and authorized operators +- [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) -- Billing models, trust models, and authorized operators - [Brand protocol](/docs/brand-protocol/brand-json) -- How seller agents resolve brand identity from the `brand.domain` - [get_adcp_capabilities](/docs/protocol/get_adcp_capabilities) -- Discover `supported_billing` and `require_operator_auth` before syncing accounts diff --git a/docs/accounts/tasks/sync_governance.mdx b/docs/accounts/tasks/sync_governance.mdx index b853b99ea6..5d45c38405 100644 --- a/docs/accounts/tasks/sync_governance.mdx +++ b/docs/accounts/tasks/sync_governance.mdx @@ -5,7 +5,7 @@ description: "sync_governance syncs governance agent endpoints to specific accou testable: false --- -Sync the governance agent endpoint for specific accounts. The seller persists the agent and calls it via `check_governance` during media buy lifecycle events. Each account entry pairs an [account reference](/docs/building/integration/accounts-and-agents#account-references) with exactly one governance agent, supporting both account-id namespaces (`account_id`) and buyer-declared accounts (`brand` + `operator`). +Sync the governance agent endpoint for specific accounts. The seller persists the agent and calls it via `check_governance` during media buy lifecycle events. Each account entry pairs an [account reference](/docs/building/by-layer/L2/accounts-and-agents#account-references) with exactly one governance agent, supporting both account-id namespaces (`account_id`) and buyer-declared accounts (`brand` + `operator`). An account binds to one governance agent that owns the full lifecycle. Authorization, delivery monitoring, and compliance are phases of the same evaluation against one plan, not specialisms held by separate authorities; specialist review (legal, brand safety, category) composes inside the governance agent rather than across multiple registrations. `governance_agents` is an array with `maxItems: 1` because the array shape is the shape 3.0 shipped with — the constraint is load-bearing and not a staging post toward loosening. The envelope's `governance_context` is singular below this layer; relaxing the cap would require a coordinated wire-shape change that is not planned. See [One governance agent per account](/docs/governance/campaign/specification#one-governance-agent-per-account). @@ -108,7 +108,7 @@ asyncio.run(main()) | Field | Type | Required | Description | |-------|------|----------|-------------| -| `account` | object | Yes | [Account reference](/docs/building/integration/accounts-and-agents#account-references): `{account_id}` for account-id namespaces or `{brand, operator}` for buyer-declared accounts. | +| `account` | object | Yes | [Account reference](/docs/building/by-layer/L2/accounts-and-agents#account-references): `{account_id}` for account-id namespaces or `{brand, operator}` for buyer-declared accounts. | | `governance_agents` | array | Yes | Governance agent endpoint for this account. Array with exactly one entry (`minItems: 1`, `maxItems: 1`). | **The governance agent:** @@ -294,4 +294,4 @@ Earlier drafts of 3.0 allowed up to 10 governance agents per account with per-ag - [list_accounts](/docs/accounts/tasks/list_accounts) — Discover accounts and their current governance agents - [sync_accounts](/docs/accounts/tasks/sync_accounts) — Provision or link advertiser accounts - [check_governance](/docs/governance/campaign/tasks/check_governance) — How sellers call governance agents during media buy events -- [Accounts and agents](/docs/building/integration/accounts-and-agents) — Account models, billing, and trust +- [Accounts and agents](/docs/building/by-layer/L2/accounts-and-agents) — Account models, billing, and trust diff --git a/docs/brand-protocol/building-a-brand-agent.mdx b/docs/brand-protocol/building-a-brand-agent.mdx index d0eeec36c5..e0aa532b26 100644 --- a/docs/brand-protocol/building-a-brand-agent.mdx +++ b/docs/brand-protocol/building-a-brand-agent.mdx @@ -721,7 +721,7 @@ async function checkLinkedAccount(extra: any): Promise { } ``` -How you identify callers depends on your authentication setup. The MCP transport provides session information; your auth middleware maps that to a linked account. See the [authentication guide](/docs/building/integration/authentication) for patterns. +How you identify callers depends on your authentication setup. The MCP transport provides session information; your auth middleware maps that to a linked account. See the [authentication guide](/docs/building/by-layer/L2/authentication) for patterns. ## Rights and creative integration diff --git a/docs/building/by-layer/L1/request-signing.mdx b/docs/building/by-layer/L1/request-signing.mdx index e9ce7c8c59..7c844ee6d6 100644 --- a/docs/building/by-layer/L1/request-signing.mdx +++ b/docs/building/by-layer/L1/request-signing.mdx @@ -745,6 +745,6 @@ For the full error code taxonomy, see [Transport error taxonomy](/docs/building/ - [Security: Signed Requests](/docs/building/by-layer/L1/security#signed-requests-transport-layer) — normative spec with verifier checklist, canonicalization rules, and replay dedup sizing - [Push Notifications](/docs/building/by-layer/L3/webhooks) — webhook setup including signature verification -- [Validate Your Agent](/docs/building/validate-your-agent) — full compliance validation including signing conformance -- [Build an Agent](/docs/building/build-an-agent) — SDK setup and storyboard validation +- [Validate Your Agent](/docs/building/verification/validate-your-agent) — full compliance validation including signing conformance +- [Build an Agent](/docs/building/by-layer/L4/build-an-agent) — SDK setup and storyboard validation - [RFC 9421](https://www.rfc-editor.org/rfc/rfc9421) — HTTP Message Signatures specification diff --git a/docs/building/verification/addie-socket-mode.mdx b/docs/building/verification/addie-socket-mode.mdx index 51a79b3b30..593b3f2b79 100644 --- a/docs/building/verification/addie-socket-mode.mdx +++ b/docs/building/verification/addie-socket-mode.mdx @@ -122,7 +122,7 @@ Addie dispatches the storyboard through the open socket and renders the result a Failing steps include trimmed error text so you can fix in place and re-run without leaving the chat. Iterate until green. -You can run any storyboard in the [Compliance Catalog](/docs/building/compliance-catalog) this way — sales, creative, signals, governance, signed requests, etc. Ask Addie what's available if you're not sure: *"What conformance storyboards apply to a sales agent?"* +You can run any storyboard in the [Compliance Catalog](/docs/building/verification/compliance-catalog) this way — sales, creative, signals, governance, signed requests, etc. Ask Addie what's available if you're not sure: *"What conformance storyboards apply to a sales agent?"* ## What Addie can do once you're connected @@ -189,8 +189,8 @@ For tool-level visibility, log inside your `setRequestHandler` callbacks — Add - [`@adcp/sdk/server` `ConformanceClient`](https://github.com/adcontextprotocol/adcp-client/blob/main/src/lib/server/socket-mode/conformance-client.ts) — adopter-side primitive - [`get_adcp_capabilities`](/docs/protocol/get_adcp_capabilities) — the discovery tool every storyboard starts with -- [Compliance Catalog](/docs/building/compliance-catalog) — full list of available storyboards -- [Get Test-Ready](/docs/building/get-test-ready) — what your agent needs in place before any storyboard can pass +- [Compliance Catalog](/docs/building/verification/compliance-catalog) — full list of available storyboards +- [Get Test-Ready](/docs/building/verification/get-test-ready) — what your agent needs in place before any storyboard can pass - [AAO Verified](/docs/building/verification/aao-verified) — the public trust mark you graduate to once your agent is stable - Channel design: [adcp#3991](https://github.com/adcontextprotocol/adcp/issues/3991) - Deployment-scoped controller rule: [adcp#3986](https://github.com/adcontextprotocol/adcp/issues/3986) diff --git a/docs/creative/catalogs.mdx b/docs/creative/catalogs.mdx index cf8d5b7222..c516d58e99 100644 --- a/docs/creative/catalogs.mdx +++ b/docs/creative/catalogs.mdx @@ -87,7 +87,7 @@ sequenceDiagram end ``` -This is the same dependency order documented in [Account state](/docs/building/integration/account-state): `sync_catalogs` → `sync_creatives` → `create_media_buy`. +This is the same dependency order documented in [Account state](/docs/building/by-layer/L2/account-state): `sync_catalogs` → `sync_creatives` → `create_media_buy`. ### When to use sync_catalogs vs inline @@ -1186,7 +1186,7 @@ Budget allocation across catalog items is a platform optimization decision — s ## Related documentation -- **[Account state](/docs/building/integration/account-state)** — How catalogs fit into account state and the setup sequence +- **[Account state](/docs/building/by-layer/L2/account-state)** — How catalogs fit into account state and the setup sequence - **[Brand identity](/docs/brand-protocol/brand-json)** — Brand identity and assets - **[SI Chat Protocol](/docs/sponsored-intelligence/si-chat-protocol)** — Conversational brand experiences - **[sync_creatives](/docs/creative/task-reference/sync_creatives)** — Submitting creative manifests diff --git a/docs/creative/multi-agent-orchestration.mdx b/docs/creative/multi-agent-orchestration.mdx index 785fd524a9..05fc73dd77 100644 --- a/docs/creative/multi-agent-orchestration.mdx +++ b/docs/creative/multi-agent-orchestration.mdx @@ -340,7 +340,7 @@ The orchestrator does not need format-specific logic for routing or syncing — ## Next steps -- [Orchestrator design patterns](/docs/building/implementation/orchestrator-design) — State machines, persistence, and retry patterns for multi-agent systems +- [Orchestrator design patterns](/docs/building/operating/orchestrator-design) — State machines, persistence, and retry patterns for multi-agent systems - [Creative libraries and concepts](/docs/creative/creative-libraries) — Managing creatives in a single agent's library - [Creative capabilities on sales agents](/docs/creative/sales-agent-creative-capabilities) — When the seller manages both media and creative - [Generative creative](/docs/creative/generative-creative) — AI-powered creative generation workflows diff --git a/docs/creative/specification.mdx b/docs/creative/specification.mdx index 167928fd42..7af3855eb7 100644 --- a/docs/creative/specification.mdx +++ b/docs/creative/specification.mdx @@ -389,7 +389,7 @@ Retrieve creative delivery data with variant-level metrics. ## Error handling -Creative agents MUST return errors using the [standard AdCP error schema](/docs/building/implementation/error-handling). +Creative agents MUST return errors using the [standard AdCP error schema](/docs/building/by-layer/L3/error-handling). Common error codes: diff --git a/docs/creative/task-reference/build_creative.mdx b/docs/creative/task-reference/build_creative.mdx index f8e92928f1..5470567ae1 100644 --- a/docs/creative/task-reference/build_creative.mdx +++ b/docs/creative/task-reference/build_creative.mdx @@ -47,7 +47,7 @@ For information about legacy format IDs and how to reference formats, see [Creat | `preview_quality` | string | No | Render quality for inline previews: `"draft"` or `"production"`. Independent of the build `quality` — you can build at draft and preview at production, or vice versa. Only used when `include_preview` is true. | | `preview_output_format` | string | No | Output format for preview renders: `"url"` (default) or `"html"`. Only used when `include_preview` is true. | | `macro_values` | object | No | Macro values to pre-substitute into the output manifest's assets. Keys are universal macro names (e.g., `CLICK_URL`, `CACHEBUSTER`); values are the literal substitution strings. The creative agent translates universal macros to its platform's native syntax. Macros not provided here remain as `{MACRO}` placeholders for the sales agent to resolve at serve time. | -| `account` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference for pricing and billing. When present, the creative agent applies account-specific pricing from the rate card, records the build against the account, and can enforce quotas. Required by creative agents that charge for their services. | +| `account` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference for pricing and billing. When present, the creative agent applies account-specific pricing from the rate card, records the build against the account, and can enforce quotas. Required by creative agents that charge for their services. | | `push_notification_config` | object | No | Operation-scoped webhook configuration for async terminal completion/failure notifications when `build_creative` returns `submitted`. Submitted tasks remain pollable via `get_task_status` whether or not this field is present; agents MUST NOT return `submitted` solely because this field is present. | ### Pricing response fields diff --git a/docs/creative/task-reference/get_creative_delivery.mdx b/docs/creative/task-reference/get_creative_delivery.mdx index f9ae764743..694e9aabf7 100644 --- a/docs/creative/task-reference/get_creative_delivery.mdx +++ b/docs/creative/task-reference/get_creative_delivery.mdx @@ -18,7 +18,7 @@ At least one scoping filter (`media_buy_ids` or `creative_ids`) is required. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Limits results to creatives within this account. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Limits results to creatives within this account. | | `media_buy_ids` | string[] | Yes* | Filter to specific media buys by publisher ID | | `creative_ids` | string[] | Yes* | Filter to specific creatives by ID | | `start_date` | string | No | Start date for delivery period (YYYY-MM-DD, interpreted in the platform's reporting timezone) | diff --git a/docs/creative/task-reference/list_creatives.mdx b/docs/creative/task-reference/list_creatives.mdx index 747af235f6..fb263f7299 100644 --- a/docs/creative/task-reference/list_creatives.mdx +++ b/docs/creative/task-reference/list_creatives.mdx @@ -48,7 +48,7 @@ Implemented by any agent that hosts a creative library — creative agents (ad s | `include_purged` | boolean | No | Include soft-purged creative tombstones (default: false). See [Purged tombstones](#purged-tombstones). | | `include_webhook_activity` | boolean | No | Include recent webhook fires per creative (default: false). See [Webhook activity](#webhook-activity). | | `webhook_activity_limit` | integer | No | Maximum `webhook_activity[]` records per creative when `include_webhook_activity: true` (default: 50, range 1–200). | -| `account` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference for pricing. When provided with `include_pricing`, the agent returns `pricing_options` from this account's rate card on each creative. | +| `account` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference for pricing. When provided with `include_pricing`, the agent returns `pricing_options` from this account's rate card on each creative. | | `fields` | array | No | Specific fields to return (omit for all fields). Includes `"pricing_options"` for sparse selection. | ## Filtering options @@ -57,7 +57,7 @@ The `filters` object supports these optional, composable filters: | Filter | Type | Description | |--------|------|-------------| -| `accounts` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references)[] | Filter by owning accounts | +| `accounts` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references)[] | Filter by owning accounts | | `format_ids` | FormatID[] | Filter by structured format IDs | | `statuses` | [CreativeStatus](/docs/creative/specification#creative-status-lifecycle)[] | Filter by approval status | | `tags` | string[] | Filter by tags (all must match) | diff --git a/docs/creative/task-reference/sync_creatives.mdx b/docs/creative/task-reference/sync_creatives.mdx index fc370adcfa..9387c4d11c 100644 --- a/docs/creative/task-reference/sync_creatives.mdx +++ b/docs/creative/task-reference/sync_creatives.mdx @@ -791,7 +791,7 @@ Two distinct async patterns — match the right one to the agent's behavior: Poll `tasks/get` or wait for the webhook. The completion artifact carries the `creatives` array with per-item `action`/`status` results; operation-level failures surface as `status: "failed"` on the task. -**See:** [Webhooks](/docs/building/implementation/webhooks) for webhook configuration. +**See:** [Webhooks](/docs/building/by-layer/L3/webhooks) for webhook configuration. ## Sync modes diff --git a/docs/faq.mdx b/docs/faq.mdx index 05448f7850..d358187996 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -132,7 +132,7 @@ AdCP is maintained by AgenticAdvertising.org (AAO), an independent specification - **Layer.** AdCP describes the campaign layer — the buyer/seller workflow above the impression-level auction (product discovery, media buy creation, creative, signals, governance). IAB Tech Lab's portfolio (OpenRTB, VAST, `ads.txt`/`sellers.json`, Open Measurement SDK, content taxonomy, audience taxonomy, GPP) standardizes the impression layer and the supply-chain primitives below. AdCP coexists with all of them — content taxonomy fields align with IAB content categories, audience segments can reference IAB audience taxonomy IDs, and [`adagents.json`](/docs/governance/property/adagents) extends the `ads.txt`/`sellers.json` relationship semantics rather than replacing them. - **Cadence.** AAO works through public RFCs and working groups on GitHub on a monthly cycle, suited to an agentic surface that is still moving. IAB Tech Lab's standardization process is built for slower, broader-consensus deliberation across a much larger membership. -AdCP is Apache 2.0 — IAB Tech Lab or any other body is free to adopt, reference, or align with the specification. See [Industry landscape](/docs/building/understanding/industry-landscape) for the full picture of how AdCP, OpenRTB, MCP, and A2A relate. +AdCP is Apache 2.0 — IAB Tech Lab or any other body is free to adopt, reference, or align with the specification. See [Industry landscape](/docs/building/concepts/industry-landscape) for the full picture of how AdCP, OpenRTB, MCP, and A2A relate. @@ -148,7 +148,7 @@ As of April 2026: | **Maintainer** | IAB Tech Lab | AgenticAdvertising.org | | **Maturity** | Emerging framework across multiple sub-initiatives | 3.0 GA (released April 2026) | | **Scope** | Umbrella for multiple agentic initiatives | Single specification covering media buying, creative, signals, brand governance, and execution (TMP) | -| **Governance verification** | Being defined | Signed governance context with 15-step verification (Layer 4 of the [security model](/docs/building/understanding/security-model)) | +| **Governance verification** | Being defined | Signed governance context with 15-step verification (Layer 4 of the [security model](/docs/building/concepts/security-model)) | | **Public schemas** | Being defined | [Published](https://adcontextprotocol.org/schemas/v3/), Apache 2.0 | We do not yet publish a formal technical comparison because AAMP is still defining its normative surface. Implementers interested in both should watch both specifications as they stabilize. @@ -172,7 +172,7 @@ A platform implementing both sees AdCP for "surface the right offer and engage t You can, and for some deployments that is the right call — proprietary internal protocols are fine when the scope stays inside a single organization. -A shared protocol earns its cost when two conditions hold: (1) agents need to interoperate across organizational boundaries, and (2) the guarantees an implementer needs — idempotency, signed governance, structural privacy separation, conformance — are nontrivial to build from scratch. AdCP already specifies the wire, publishes schemas, runs conformance tests, and carries a signed-governance profile with 15-step verification (see the [security model](/docs/building/understanding/security-model)). Rebuilding that internally is a real cost, and if you want counterparties to trust your internal protocol, you have to socialize it anyway. +A shared protocol earns its cost when two conditions hold: (1) agents need to interoperate across organizational boundaries, and (2) the guarantees an implementer needs — idempotency, signed governance, structural privacy separation, conformance — are nontrivial to build from scratch. AdCP already specifies the wire, publishes schemas, runs conformance tests, and carries a signed-governance profile with 15-step verification (see the [security model](/docs/building/concepts/security-model)). Rebuilding that internally is a real cost, and if you want counterparties to trust your internal protocol, you have to socialize it anyway. If AdCP is missing something you need, the cheaper path is usually: extend via `ext.{vendor}`, or propose a change to the working group. See the [contributing guide](https://github.com/adcontextprotocol/adcp/blob/main/CONTRIBUTING.md). @@ -182,7 +182,7 @@ MCP defines *how* an agent calls a tool. AdCP defines *what* the agent says when AdCP is what makes the tools interchangeable. If every publisher's MCP server speaks AdCP's `create_media_buy`, one buyer agent can integrate with all of them. Without AdCP, "connect to a new publisher" is a new development task every time. -Put differently: MCP is the transport, AdCP is the protocol. You use MCP to *carry* AdCP tasks — the same way HTTP carries REST payloads. See [Industry landscape](/docs/building/understanding/industry-landscape) for how AdCP, OpenRTB, MCP, and A2A relate. +Put differently: MCP is the transport, AdCP is the protocol. You use MCP to *carry* AdCP tasks — the same way HTTP carries REST payloads. See [Industry landscape](/docs/building/concepts/industry-landscape) for how AdCP, OpenRTB, MCP, and A2A relate. @@ -230,7 +230,7 @@ See [CHARTER.md](https://github.com/adcontextprotocol/adcp/blob/main/CHARTER.md) -AdCP today uses bearer-token authentication between agents — see [authentication](/docs/building/integration/authentication) for the shipped model. +AdCP today uses bearer-token authentication between agents — see [authentication](/docs/building/by-layer/L2/authentication) for the shipped model. AdCP 3.1 will add request signing for mutating calls (`create_*`, `update_*`, `sync_*`, `activate_*`, `acquire_*`) via RFC 9421 HTTP Signatures or JWS-signed bodies as a normative requirement, with sellers verifying against the buyer's published signing keys. Bearer tokens alone will not be sufficient for mutating calls. Tracked in [#2307](https://github.com/adcontextprotocol/adcp/issues/2307). @@ -249,7 +249,7 @@ AdCP uses [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) and [ - **MCP and A2A** define how agents communicate (the transport) - **AdCP** defines what agents say about advertising (the domain) -AdCP tasks are the same regardless of transport. A [`get_products`](/docs/media-buy/task-reference/get_products) call has the same request schema and response schema whether it travels over MCP or A2A. See [protocol comparison](/docs/building/understanding/protocol-comparison) for details on how the two transports differ. +AdCP tasks are the same regardless of transport. A [`get_products`](/docs/media-buy/task-reference/get_products) call has the same request schema and response schema whether it travels over MCP or A2A. See [protocol comparison](/docs/building/concepts/protocol-comparison) for details on how the two transports differ. diff --git a/docs/governance/campaign/index.mdx b/docs/governance/campaign/index.mdx index 64664c6ea1..cc284d4167 100644 --- a/docs/governance/campaign/index.mdx +++ b/docs/governance/campaign/index.mdx @@ -214,7 +214,7 @@ Finding severity levels indicate urgency: - **`warning`** -- Human should review. Used on `approved` responses when action is allowed but attention is needed. - **`critical`** -- Action is blocked. Used on `denied` responses. -When the governance agent determines that human review is required (e.g., a reallocation exceeds the plan's `reallocation_threshold`, or the plan has `human_review_required: true`), the task goes async — it returns standard async task lifecycle statuses and eventually resolves to `approved` or `denied` once the human acts. This integrates with the existing AdCP async task mechanism. The caller does not need special handling beyond supporting async tasks (see [task lifecycle](/docs/building/implementation/task-lifecycle)). +When the governance agent determines that human review is required (e.g., a reallocation exceeds the plan's `reallocation_threshold`, or the plan has `human_review_required: true`), the task goes async — it returns standard async task lifecycle statuses and eventually resolves to `approved` or `denied` once the human acts. This integrates with the existing AdCP async task mechanism. The caller does not need special handling beyond supporting async tasks (see [task lifecycle](/docs/building/by-layer/L3/task-lifecycle)). ## Relationship to other governance domains diff --git a/docs/governance/campaign/safety-model.mdx b/docs/governance/campaign/safety-model.mdx index e35e3dcb97..fd5a4c2f64 100644 --- a/docs/governance/campaign/safety-model.mdx +++ b/docs/governance/campaign/safety-model.mdx @@ -39,7 +39,7 @@ That independence is the whole point. A design where the only way to reconstruct The signed token also binds the approval to a specific plan, a specific seller, a specific phase of the media buy, and a unique transaction identifier. A token approving a $500K flight for Seller A cannot be silently reused to authorize a $500K flight at Seller B, nor can an approval for Q1 be replayed in Q3. -See [Signed Governance Context](/docs/building/implementation/security#signed-governance-context) for the implementer-facing profile (claim set, key discovery, revocation, verification rules). +See [Signed Governance Context](/docs/building/by-layer/L1/security#signed-governance-context) for the implementer-facing profile (claim set, key discovery, revocation, verification rules). ## Separation of duties diff --git a/docs/governance/campaign/specification.mdx b/docs/governance/campaign/specification.mdx index 4bbf2e924a..2298ddbbc6 100644 --- a/docs/governance/campaign/specification.mdx +++ b/docs/governance/campaign/specification.mdx @@ -157,7 +157,7 @@ Orchestrators fanning out the same plan to multiple sellers produce one intent t #### Seller enforcement -A seller receiving a spend-commit request for a plan with a configured governance agent MUST require a valid, in-date **intent-phase** `governance_context` token on the request, verified per the [seller verification checklist](/docs/building/implementation/security#seller-verification-checklist). The token MUST carry `phase: "intent"`, match the request's `plan_id` (via `sub`), and be addressed (`aud`) to this seller. A request without a token, with a token that fails verification, or with a token issued for a different plan, a different seller, or a non-intent phase MUST be rejected with `PERMISSION_DENIED`. The seller then performs its own execution check by calling `check_governance` with `planned_delivery` and the received `governance_context`; that call produces the `purchase`-phase token (bound to the seller-assigned `media_buy_id`) used for the remainder of the media buy lifecycle. This two-step flow is what makes the buyer-side MUST real: a buyer that skips `check_governance` cannot produce a valid intent token, and the spend-commit is rejected before the seller ever reaches its execution check. +A seller receiving a spend-commit request for a plan with a configured governance agent MUST require a valid, in-date **intent-phase** `governance_context` token on the request, verified per the [seller verification checklist](/docs/building/by-layer/L1/security#seller-verification-checklist). The token MUST carry `phase: "intent"`, match the request's `plan_id` (via `sub`), and be addressed (`aud`) to this seller. A request without a token, with a token that fails verification, or with a token issued for a different plan, a different seller, or a non-intent phase MUST be rejected with `PERMISSION_DENIED`. The seller then performs its own execution check by calling `check_governance` with `planned_delivery` and the received `governance_context`; that call produces the `purchase`-phase token (bound to the seller-assigned `media_buy_id`) used for the remainder of the media buy lifecycle. This two-step flow is what makes the buyer-side MUST real: a buyer that skips `check_governance` cannot produce a valid intent token, and the spend-commit is rejected before the seller ever reaches its execution check. Sellers MUST persist the accepted intent token and any lifecycle tokens they subsequently hold, keyed at minimum by `jti` with `iss`, `aud`, `sub` (plan_id), `phase`, decision outcome, and the timestamp of acceptance. Retention follows the seller's regulatory retention period. Without seller-side retention, the audit log is single-sourced from the governance agent; independent reconciliation between seller records and `get_plan_audit_logs` is the cross-check that catches a compromised or misbehaving governance agent. @@ -179,8 +179,8 @@ The buyer-side intent check and the seller-side execution check each produce a d #### Interaction with idempotency -- **Retry of an identical payload carrying the prior intent-phase `governance_context`:** no re-invocation. The cached governance response is reused; the token signature and freshness are re-validated. Seller-side replay-dedup keys (see the [verification checklist](/docs/building/implementation/security#seller-verification-checklist)) MUST treat a repeated `jti` carrying the same `idempotency_key` as a legitimate retry rather than a replay attack — this is the one narrow carve-out. -- **Re-plan with a different payload (new `idempotency_key` per [Idempotency](/docs/building/implementation/security#idempotency)):** a fresh `check_governance` invocation is required. A new `governance_context` token is issued. +- **Retry of an identical payload carrying the prior intent-phase `governance_context`:** no re-invocation. The cached governance response is reused; the token signature and freshness are re-validated. Seller-side replay-dedup keys (see the [verification checklist](/docs/building/by-layer/L1/security#seller-verification-checklist)) MUST treat a repeated `jti` carrying the same `idempotency_key` as a legitimate retry rather than a replay attack — this is the one narrow carve-out. +- **Re-plan with a different payload (new `idempotency_key` per [Idempotency](/docs/building/by-layer/L1/security#idempotency)):** a fresh `check_governance` invocation is required. A new `governance_context` token is issued. A retry after a human approval does not re-invoke governance; the existing token remains the authorization until it expires. Post-execution lifecycle retries operate against the seller's `purchase`-phase token, which is a distinct artifact governed by the seller's execution check, not the buyer's intent check. @@ -703,7 +703,7 @@ On the first `check_governance` call (before any context exists), the governance Governance agents SHOULD treat `governance_context` as a lookup key into server-side state or a signed token, not as a plain-text encoding of governance state. If state is encoded directly, it MUST be signed (e.g., HMAC) so tampering by intermediaries is detectable. -In AdCP 3.0 the encoded value is a compact JWS signed per the [AdCP JWS profile](/docs/building/implementation/security#adcp-jws-profile). The token carries a required `plan_hash` claim that binds the attestation to the exact plan state the governance agent evaluated (see [Plan binding and audit](#plan-binding-and-audit) below). Callers still treat the value as opaque for correlation; sellers that opt into verification follow the [seller verification checklist](/docs/building/implementation/security#seller-verification-checklist), which verifies the token's authenticity, authorization scope, and freshness — not the buyer's plan. +In AdCP 3.0 the encoded value is a compact JWS signed per the [AdCP JWS profile](/docs/building/by-layer/L1/security#adcp-jws-profile). The token carries a required `plan_hash` claim that binds the attestation to the exact plan state the governance agent evaluated (see [Plan binding and audit](#plan-binding-and-audit) below). Callers still treat the value as opaque for correlation; sellers that opt into verification follow the [seller verification checklist](/docs/building/by-layer/L1/security#seller-verification-checklist), which verifies the token's authenticity, authorization scope, and freshness — not the buyer's plan. ### Plan binding and audit @@ -719,13 +719,13 @@ What the claim delivers: `plan_hash = base64url_no_pad(SHA-256(JCS(plan_payload)))` where: -- `JCS` is [RFC 8785 JSON Canonicalization Scheme](https://www.rfc-editor.org/rfc/rfc8785) — the same scheme used for [idempotency payload equivalence](/docs/building/implementation/security#payload-equivalence). Governance agents and auditor verifiers SHOULD use the same library implementations listed there. JCS sorts object keys lexicographically by code point (caller key order in the `sync_plans` request does not affect the hash) and preserves the distinction between an omitted optional field and an explicit `null` (these produce different hashes). Governance agents MUST hash the plan as-supplied; they MUST NOT synthesize omitted optionals to default values and MUST NOT drop explicit nulls. +- `JCS` is [RFC 8785 JSON Canonicalization Scheme](https://www.rfc-editor.org/rfc/rfc8785) — the same scheme used for [idempotency payload equivalence](/docs/building/by-layer/L1/security#payload-equivalence). Governance agents and auditor verifiers SHOULD use the same library implementations listed there. JCS sorts object keys lexicographically by code point (caller key order in the `sync_plans` request does not affect the hash) and preserves the distinction between an omitted optional field and an explicit `null` (these produce different hashes). Governance agents MUST hash the plan as-supplied; they MUST NOT synthesize omitted optionals to default values and MUST NOT drop explicit nulls. - `plan_payload` is **one element of the `plans[]` array as supplied on `sync_plans`** — a single plan object, not the `sync_plans` request envelope and not the `plans` wrapper array. The preimage is the current plan-revision state at the time of attestation, i.e., the plan object the governance agent just evaluated. Implementations constructing the preimage start from the plan-revision object and remove the closed set of bookkeeping fields listed below. - `base64url_no_pad` follows RFC 4648 §5 with trailing `=` padding stripped — consistent with `jti` and other base64url values in the JWS profile. Governance agents MUST emit the unpadded form. Verifiers (governance agents re-verifying their own tokens, auditors, buyer-side compliance tooling) MUST compare by base64url-decoding both sides to the raw 32-byte SHA-256 digest and comparing bytes — NOT by string equality of the encoded form — so padding, case, or alphabet variation is rejected as a decode failure rather than producing a false non-match. A `plan_hash` that does not decode to exactly 32 bytes MUST be rejected. #### Excluded fields -Closed list — governance agents MUST NOT extend or shrink it; any addition is a breaking change requiring a profile version bump, same rule as [Payload equivalence](/docs/building/implementation/security#payload-equivalence): +Closed list — governance agents MUST NOT extend or shrink it; any addition is a breaking change requiring a profile version bump, same rule as [Payload equivalence](/docs/building/by-layer/L1/security#payload-equivalence): - `version` — governance-agent revision counter, set by the agent on each re-sync - `status` — plan lifecycle status managed by the agent @@ -748,14 +748,14 @@ All other fields — including `ext`, `custom_policies`, `objectives`, `delegati Governance agents MUST: - Compute `plan_hash` over the current plan state on every `check_governance` call and include it in the signed JWS payload. The hash MUST be over the plan the agent just evaluated; stale attestations over mutated plans MUST NOT be produced. -- Refresh the signature on every `check_governance` invocation — fresh `jti`, `iat`, `exp`, and `plan_hash`. Governance agents MUST NOT cache and re-emit a previously-signed `governance_context` token across plan revisions. Envelope idempotency response caching is a separate regime — `governance_context` is on the closed exclusion list in [Payload equivalence](/docs/building/implementation/security#payload-equivalence) precisely so it can rotate on replay. +- Refresh the signature on every `check_governance` invocation — fresh `jti`, `iat`, `exp`, and `plan_hash`. Governance agents MUST NOT cache and re-emit a previously-signed `governance_context` token across plan revisions. Envelope idempotency response caching is a separate regime — `governance_context` is on the closed exclusion list in [Payload equivalence](/docs/building/by-layer/L1/security#payload-equivalence) precisely so it can rotate on replay. - **Retain the per-revision `plan_hash`** alongside each internal plan-revision record — MUST, regardless of whether `audit_log_pointer` is exposed. Retention is what delivers the forever-binding property; without universal retention, every governance agent that doesn't use `audit_log_pointer` silently voids the audit layer for its entire token corpus. An audit log that cannot be joined back to the attested plan state is half an audit trail, and a governance agent that cannot verify its own historical tokens cannot detect tampering of its own store. Retained values are implementation-internal and are never exposed on the wire except through the normalized response on [`get_plan_audit_logs`](/docs/governance/campaign/tasks/get_plan_audit_logs), which echoes `plan_hash` per entry so auditors do not have to reconstruct from the governance agent's private records. #### Wire-verification contract `plan_hash` is not listed in `crit`. `crit` is wire-verifier semantics (RFC 7515 §4.1.11): it forces verifiers to reject tokens whose listed claims they cannot process. No wire verifier processes `plan_hash` — the only parties who can fetch the preimage (governance agent, auditor, buyer compliance) are off-wire. Listing in `crit` would force sellers to reject tokens they have no basis to verify, with no offsetting benefit. Governance agents MUST emit the claim and MUST NOT list it in `crit`. -Sellers persist and forward `governance_context` verbatim and perform the [15-step JWS verification checklist](/docs/building/implementation/security#seller-verification-checklist) — authenticity, authorization scope, freshness. They treat `plan_hash` as opaque cargo inside the token and never inspect it. +Sellers persist and forward `governance_context` verbatim and perform the [15-step JWS verification checklist](/docs/building/by-layer/L1/security#seller-verification-checklist) — authenticity, authorization scope, freshness. They treat `plan_hash` as opaque cargo inside the token and never inspect it. #### Verification recipes diff --git a/docs/governance/campaign/tasks/check_governance.mdx b/docs/governance/campaign/tasks/check_governance.mdx index 12b39e115f..c602bce58d 100644 --- a/docs/governance/campaign/tasks/check_governance.mdx +++ b/docs/governance/campaign/tasks/check_governance.mdx @@ -43,7 +43,7 @@ The orchestrator calls `check_governance` with `tool` and `payload` before sendi The seller calls `check_governance` with `governance_context` and `planned_delivery` when processing a request on an account that has a governance agent configured (set via [`sync_governance`](/docs/accounts/tasks/sync_governance)). Execution checks are always binding — if the governance agent denies, the seller must not proceed. -Before executing the check, the seller verifies the signed `governance_context` token that arrived on the protocol envelope from the buyer. The buyer produces an **intent-phase** token (per the [JWS profile](/docs/building/implementation/security#adcp-jws-profile)); the seller's own execution check produces the `purchase`/`modification`/`delivery`-phase tokens bound to the assigned `media_buy_id` for the rest of the lifecycle. +Before executing the check, the seller verifies the signed `governance_context` token that arrived on the protocol envelope from the buyer. The buyer produces an **intent-phase** token (per the [JWS profile](/docs/building/by-layer/L1/security#adcp-jws-profile)); the seller's own execution check produces the `purchase`/`modification`/`delivery`-phase tokens bound to the assigned `media_buy_id` for the rest of the lifecycle. ``` on receive(create_media_buy request): @@ -79,7 +79,7 @@ Sellers can adopt committed governance checks incrementally: When a governance agent is configured on the plan, buyer agents MUST invoke `check_governance` before every spend-commit request (`create_media_buy`, `update_media_buy`, `acquire_rights`, `update_rights`, `activate_signal`, `build_creative`) — full stop. There is no dollar floor, no anomaly threshold, and no cold-start exemption; every commit goes through the governance agent. The buyer-side call is an intent check (`tool` + `payload`), which produces an intent-phase `governance_context` token the buyer attaches to its request to the seller. The governance agent decides internally whether to auto-approve, apply conditions, deny, or escalate to human review per the plan's `budget.reallocation_threshold` and `human_review_required` fields. -Seller-side enforcement makes the MUST real through the [signed `governance_context` token](/docs/building/implementation/security#signed-governance-context): a seller receiving a spend-commit for a plan with a configured governance agent MUST require a valid, in-date intent-phase token (`phase: "intent"`, `sub` equal to the plan_id, `aud` addressed to this seller), and MUST reject with `PERMISSION_DENIED` otherwise. The seller then performs its own execution check — calling `check_governance` with `planned_delivery` and the received `governance_context` — which produces the `purchase`-phase token bound to the newly assigned `media_buy_id` for the rest of the lifecycle. A buyer that skips the intent check cannot produce a valid intent token, so the commit is rejected before the seller ever reaches its execution check. +Seller-side enforcement makes the MUST real through the [signed `governance_context` token](/docs/building/by-layer/L1/security#signed-governance-context): a seller receiving a spend-commit for a plan with a configured governance agent MUST require a valid, in-date intent-phase token (`phase: "intent"`, `sub` equal to the plan_id, `aud` addressed to this seller), and MUST reject with `PERMISSION_DENIED` otherwise. The seller then performs its own execution check — calling `check_governance` with `planned_delivery` and the received `governance_context` — which produces the `purchase`-phase token bound to the newly assigned `media_buy_id` for the rest of the lifecycle. A buyer that skips the intent check cannot produce a valid intent token, so the commit is rejected before the seller ever reaches its execution check. When no governance agent is configured on the plan, `check_governance` invocation is neither required nor meaningful — there is nothing to call. Sellers MAY refuse to transact on plans lacking a configured governance agent as a matter of their own commercial policy. @@ -105,7 +105,7 @@ Governance agents SHOULD return `denied` (not `conditions`) after 3 unsuccessful ### Human review -When the governance agent determines that human review is required (e.g., the action exceeds the plan's `reallocation_threshold`, or the plan carries `human_review_required: true`), it handles the escalation internally. The `check_governance` task goes async — the caller receives standard async task lifecycle statuses (`submitted`, `working`) and eventually gets `approved` or `denied` once the human acts. The caller does not need special handling for this case beyond supporting async tasks (see [task lifecycle](/docs/building/implementation/task-lifecycle)). +When the governance agent determines that human review is required (e.g., the action exceeds the plan's `reallocation_threshold`, or the plan carries `human_review_required: true`), it handles the escalation internally. The `check_governance` task goes async — the caller receives standard async task lifecycle statuses (`submitted`, `working`) and eventually gets `approved` or `denied` once the human acts. The caller does not need special handling for this case beyond supporting async tasks (see [task lifecycle](/docs/building/by-layer/L3/task-lifecycle)). For `committed` checks (seller-side), the seller sets a timeout. If the governance agent does not respond within the timeout, the seller treats it as `denied` and returns an error to the orchestrator. The orchestrator can re-initiate the media buy after the governance agent resolves. @@ -147,7 +147,7 @@ The presence of `next_check` in a response is the signal that the governance age } ``` -On the first `check_governance` call, the governance agent extracts what it needs from `payload`. The response includes a `governance_context` string that the caller attaches to the protocol envelope and includes on all subsequent governance calls for this governed action. In 3.0 the governance agent MUST emit a compact JWS signed per the [AdCP JWS profile](/docs/building/implementation/security#signed-governance-context) so sellers can verify authenticity, authorization scope, and freshness (the 15-step seller checklist). The token also carries a required `plan_hash` audit-layer claim — see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for canonicalization rules, retention obligations, and the eleven reference vectors governance-agent implementers SHOULD validate against before shipping. +On the first `check_governance` call, the governance agent extracts what it needs from `payload`. The response includes a `governance_context` string that the caller attaches to the protocol envelope and includes on all subsequent governance calls for this governed action. In 3.0 the governance agent MUST emit a compact JWS signed per the [AdCP JWS profile](/docs/building/by-layer/L1/security#signed-governance-context) so sellers can verify authenticity, authorization scope, and freshness (the 15-step seller checklist). The token also carries a required `plan_hash` audit-layer claim — see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for canonicalization rules, retention obligations, and the eleven reference vectors governance-agent implementers SHOULD validate against before shipping. ### Intent check (rights license) @@ -430,7 +430,7 @@ The seller MUST adjust pacing and re-call `check_governance` immediately. The `n | `purchase_type` | enum | No | The kind of financial commitment being validated: `media_buy` (default), `rights_license`, `signal_activation`, or `creative_services`. When omitted, the governance agent assumes `media_buy`. | | `tool` | string | Intent | The AdCP tool being checked. Present on intent checks (orchestrator). The governance agent uses the presence of `tool` + `payload` to identify an intent check. | | `payload` | object | Intent | Full tool arguments as they would be sent to the seller. Present on intent checks. | -| `governance_context` | string | No | Governance context token from a prior `check_governance` response. Include on subsequent lifecycle checks so the governance agent can maintain continuity. On execution checks, the governance agent uses `governance_context` + `planned_delivery` to identify the check. This is the sole lifecycle correlator across all purchase types. See [Signed Governance Context](/docs/building/implementation/security#signed-governance-context) for the JWS profile and seller verification; see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for the `plan_hash` audit-layer claim. | +| `governance_context` | string | No | Governance context token from a prior `check_governance` response. Include on subsequent lifecycle checks so the governance agent can maintain continuity. On execution checks, the governance agent uses `governance_context` + `planned_delivery` to identify the check. This is the sole lifecycle correlator across all purchase types. See [Signed Governance Context](/docs/building/by-layer/L1/security#signed-governance-context) for the JWS profile and seller verification; see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for the `plan_hash` audit-layer claim. | | `phase` | enum | Execution | `purchase`, `modification`, or `delivery`. Defaults to `purchase`. Present on execution checks. | | `planned_delivery` | object | Execution | What will actually be delivered. Present on execution checks. See [planned delivery](/docs/governance/campaign/specification#integration-with-create_media_buy). | | `delivery_metrics` | object | Delivery | Actual delivery performance data. Required when `phase` is `delivery`. | @@ -470,7 +470,7 @@ The seller MUST adjust pacing and re-call `check_governance` immediately. The `n | `mode` | enum | `audit`, `advisory`, or `enforce` — governance mode active when this check was evaluated. Recorded by the governance agent from its runtime configuration at check time, not from a plan field. Lets counterparties, regulators, and auditors distinguish whether an `approved` decision reflects deliberate `enforce` enforcement or `audit`-mode silent logging. | | `expires_at` | string | Present when `verdict` is `approved` or `conditions`. The caller must act before this time or re-call. A lapsed approval is no approval. | | `next_check` | string | When the seller should next call `check_governance` with delivery metrics. Present when the governance agent expects ongoing delivery reporting. | -| `governance_context` | string | Governance context token for this governed action. Present when `verdict` is `approved` or `conditions`. Attach to the protocol envelope and include on all subsequent governance calls. This is the sole lifecycle correlator for all purchase types. See [Signed Governance Context](/docs/building/implementation/security#signed-governance-context) for the JWS profile and seller verification; see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for the `plan_hash` audit-layer claim. Sellers that do not verify MUST still persist and forward the token verbatim. | +| `governance_context` | string | Governance context token for this governed action. Present when `verdict` is `approved` or `conditions`. Attach to the protocol envelope and include on all subsequent governance calls. This is the sole lifecycle correlator for all purchase types. See [Signed Governance Context](/docs/building/by-layer/L1/security#signed-governance-context) for the JWS profile and seller verification; see [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit) for the `plan_hash` audit-layer claim. Sellers that do not verify MUST still persist and forward the token verbatim. | | `authority_remaining` | object | Buyer-side plan budget authority remaining after this check — not the seller's allocated budget. Present when `verdict` is `approved` or `conditions` for execution checks. Contains `budget_remaining` (number), `currency` (string), and `budget_used_pct` (number, 0-100). Orchestrators use this to track plan-level spend against the media plan's total authority. | ## Error codes diff --git a/docs/governance/campaign/tasks/get_plan_audit_logs.mdx b/docs/governance/campaign/tasks/get_plan_audit_logs.mdx index 6bbc8ba44e..6fffe9b949 100644 --- a/docs/governance/campaign/tasks/get_plan_audit_logs.mdx +++ b/docs/governance/campaign/tasks/get_plan_audit_logs.mdx @@ -267,7 +267,7 @@ You can combine `plan_ids` and `portfolio_plan_ids` to query both specific plans ## Authorization -The request schema does not carry an envelope `account` field — tenant identity is resolved from the submitted IDs. The governance agent MUST verify that the authenticated principal is authorized for every `plan_ids` member, every plan expanded from `portfolio_plan_ids`, and every governed action addressed by `governance_contexts`. When any element fails the authorization check the governance agent MUST fail closed with a generic `PLAN_NOT_FOUND` response — the error body MUST NOT distinguish "unauthorized" from "not found" or name the offending ID. See [Agent and Account Isolation](/docs/building/implementation/security#agent-and-account-isolation) for the pattern and existence-leak guardrails. +The request schema does not carry an envelope `account` field — tenant identity is resolved from the submitted IDs. The governance agent MUST verify that the authenticated principal is authorized for every `plan_ids` member, every plan expanded from `portfolio_plan_ids`, and every governed action addressed by `governance_contexts`. When any element fails the authorization check the governance agent MUST fail closed with a generic `PLAN_NOT_FOUND` response — the error body MUST NOT distinguish "unauthorized" from "not found" or name the offending ID. See [Agent and Account Isolation](/docs/building/by-layer/L1/security#agent-and-account-isolation) for the pattern and existence-leak guardrails. ## Error codes diff --git a/docs/governance/campaign/tasks/sync_plans.mdx b/docs/governance/campaign/tasks/sync_plans.mdx index e2bfd60bcd..d19156be77 100644 --- a/docs/governance/campaign/tasks/sync_plans.mdx +++ b/docs/governance/campaign/tasks/sync_plans.mdx @@ -124,7 +124,7 @@ These fields use the same ISO codes and semantics as `product-filters`, `offerin ## Plan-hash preimage -Each plan item a buyer supplies here is the preimage the governance agent hashes to produce the `plan_hash` audit-layer claim carried in every [signed `governance_context`](/docs/building/implementation/security#signed-governance-context). Canonicalization rules, the closed bookkeeping exclusion list, retention obligations, and the full set of reference test vectors are specified in [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit). Governance-agent implementers SHOULD run their hashing code against the eleven vectors under [`static/compliance/source/test-vectors/plan-hash/`](https://github.com/adcontextprotocol/adcp/tree/main/static/compliance/source/test-vectors/plan-hash) before shipping. +Each plan item a buyer supplies here is the preimage the governance agent hashes to produce the `plan_hash` audit-layer claim carried in every [signed `governance_context`](/docs/building/by-layer/L1/security#signed-governance-context). Canonicalization rules, the closed bookkeeping exclusion list, retention obligations, and the full set of reference test vectors are specified in [Plan binding and audit](/docs/governance/campaign/specification#plan-binding-and-audit). Governance-agent implementers SHOULD run their hashing code against the eleven vectors under [`static/compliance/source/test-vectors/plan-hash/`](https://github.com/adcontextprotocol/adcp/tree/main/static/compliance/source/test-vectors/plan-hash) before shipping. ## Fields diff --git a/docs/governance/content-standards/tasks/get_media_buy_artifacts.mdx b/docs/governance/content-standards/tasks/get_media_buy_artifacts.mdx index 68ce811ee4..9a3f49718b 100644 --- a/docs/governance/content-standards/tasks/get_media_buy_artifacts.mdx +++ b/docs/governance/content-standards/tasks/get_media_buy_artifacts.mdx @@ -32,7 +32,7 @@ The buyer retrieves artifacts the seller has collected per the sampling configur | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Only returns artifacts for media buys belonging to this account. When omitted, returns artifacts across all accessible accounts. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Only returns artifacts for media buys belonging to this account. When omitted, returns artifacts across all accessible accounts. | | `media_buy_id` | string | Yes | Media buy to get artifacts from | | `package_ids` | array | No | Filter to specific packages | | `failures_only` | boolean | No | Only return artifacts where the seller's local model returned `local_verdict: "fail"` (see [behavior with unevaluated records](#failures_only-and-unevaluated-records)) | diff --git a/docs/governance/creative/get_creative_features.mdx b/docs/governance/creative/get_creative_features.mdx index 2558c24dd6..f7e7654cf2 100644 --- a/docs/governance/creative/get_creative_features.mdx +++ b/docs/governance/creative/get_creative_features.mdx @@ -177,7 +177,7 @@ When this call was initiated by `build_creative` and the evaluator is unreachabl ## Async evaluation -Some evaluations (e.g., sandboxed malware scanning) take time. The agent returns `status: "working"` and delivers results via webhook when complete. This uses the standard [async task pattern](/docs/building/implementation/async-operations) — no custom status values needed. +Some evaluations (e.g., sandboxed malware scanning) take time. The agent returns `status: "working"` and delivers results via webhook when complete. This uses the standard [async task pattern](/docs/building/by-layer/L3/async-operations) — no custom status values needed. ## Orchestrator logic diff --git a/docs/governance/creative/index.mdx b/docs/governance/creative/index.mdx index 7fabe3863a..c94dea9f60 100644 --- a/docs/governance/creative/index.mdx +++ b/docs/governance/creative/index.mdx @@ -205,4 +205,4 @@ Governance agents that charge MUST implement the [Accounts Protocol](/docs/accou ## Async evaluation -If evaluation takes time (e.g., sandboxed execution for malware scanning), the agent returns `status: "working"` and delivers results via the standard webhook mechanism. No custom status values or webhook events needed — the existing [async task pattern](/docs/building/implementation/async-operations) handles this. +If evaluation takes time (e.g., sandboxed execution for malware scanning), the agent returns `status: "working"` and delivers results via the standard webhook mechanism. No custom status values or webhook events needed — the existing [async task pattern](/docs/building/by-layer/L3/async-operations) handles this. diff --git a/docs/governance/property/specification.mdx b/docs/governance/property/specification.mdx index 53a5c6d691..de716cfd26 100644 --- a/docs/governance/property/specification.mdx +++ b/docs/governance/property/specification.mdx @@ -353,7 +353,7 @@ All AdCP Governance responses follow a consistent structure: ### Error Codes -- `REFERENCE_NOT_FOUND`: Referenced property, policy, or property list does not exist or is not accessible by the caller. Returned uniformly for both "does not exist" and "exists but unauthorized" — see [Uniform response for inaccessible references](/docs/building/implementation/error-handling#standard-error-codes). +- `REFERENCE_NOT_FOUND`: Referenced property, policy, or property list does not exist or is not accessible by the caller. Returned uniformly for both "does not exist" and "exists but unauthorized" — see [Uniform response for inaccessible references](/docs/building/by-layer/L3/error-handling#standard-error-codes). - `PROPERTY_NOT_MONITORED`: Governance agent doesn't cover this property - `METHODOLOGY_NOT_SUPPORTED`: Requested methodology version unavailable - `PARTIAL_RESULTS`: Some properties couldn't be evaluated diff --git a/docs/governance/property/tasks/property_lists.mdx b/docs/governance/property/tasks/property_lists.mdx index d0a4704db4..d274802fb2 100644 --- a/docs/governance/property/tasks/property_lists.mdx +++ b/docs/governance/property/tasks/property_lists.mdx @@ -657,7 +657,7 @@ Pass property lists to media buy creation: | Code | Description | |------|-------------| -| `REFERENCE_NOT_FOUND` | Property list ID doesn't exist, or the caller lacks access. Returned uniformly for both cases — see [Uniform response for inaccessible references](/docs/building/implementation/error-handling#standard-error-codes). Sellers MUST NOT distinguish "exists but unauthorized" from "does not exist." | +| `REFERENCE_NOT_FOUND` | Property list ID doesn't exist, or the caller lacks access. Returned uniformly for both cases — see [Uniform response for inaccessible references](/docs/building/by-layer/L3/error-handling#standard-error-codes). Sellers MUST NOT distinguish "exists but unauthorized" from "does not exist." | | `INVALID_FILTER` | Filter configuration is invalid | | `LIST_NAME_EXISTS` | A list with this name already exists | diff --git a/docs/intro.mdx b/docs/intro.mdx index 6499d1d632..e7bae9b4de 100644 --- a/docs/intro.mdx +++ b/docs/intro.mdx @@ -575,7 +575,7 @@ AdCP doesn't assume a single AI handles everything. Specialized agents handle wh These agents communicate over two transport protocols: **MCP** (for AI assistants calling tools) and **A2A** (for agent-to-agent collaboration). Same tasks, same schemas, different transport. -**How you know an agent does what it claims:** Every agent tells the network which broad areas it handles and which specific flows it supports — and those claims are testable. The protocol ships compliance storyboards that a runner executes against the agent. If it passes, the claim is verifiable. See the [Compliance Catalog](/docs/building/compliance-catalog). +**How you know an agent does what it claims:** Every agent tells the network which broad areas it handles and which specific flows it supports — and those claims are testable. The protocol ships compliance storyboards that a runner executes against the agent. If it passes, the claim is verifiable. See the [Compliance Catalog](/docs/building/verification/compliance-catalog). ## Brief to live ads @@ -702,7 +702,7 @@ go get github.com/adcontextprotocol/adcp-go/adcp ## Open-source examples -The [Prebid Sales Agent](https://github.com/prebid/salesagent) is a full-stack seller agent (Python backend, TypeScript protocol layer) with GAM integration, built by a Prebid working group. It is a community example, not a maintained reference implementation. To build your own agent, start with the [official SDKs](/docs/building/schemas-and-sdks) and [skill files](/docs/building/build-an-agent). +The [Prebid Sales Agent](https://github.com/prebid/salesagent) is a full-stack seller agent (Python backend, TypeScript protocol layer) with GAM integration, built by a Prebid working group. It is a community example, not a maintained reference implementation. To build your own agent, start with the [official SDKs](/docs/building/schemas-and-sdks) and [skill files](/docs/building/by-layer/L4/build-an-agent). ## Organization diff --git a/docs/learning/foundations/a1-agentic-advertising.mdx b/docs/learning/foundations/a1-agentic-advertising.mdx index 400ba862a2..a22e289568 100644 --- a/docs/learning/foundations/a1-agentic-advertising.mdx +++ b/docs/learning/foundations/a1-agentic-advertising.mdx @@ -33,7 +33,7 @@ Review these pages before starting the module with Addie. They provide the conce The strategic vision: allocation vs day trading, the fragmentation problem, and why agents need a shared protocol. - + How AdCP compares to OpenRTB, platform APIs, and direct IO. Understand where agentic advertising fits in the landscape. @@ -45,7 +45,7 @@ Review these pages before starting the module with Addie. They provide the conce The five principles that define how humans stay in control when agents execute autonomously. - + What changes for security when an agent spends money without a human in the loop — and the trust primitives that make it safe. diff --git a/docs/learning/foundations/a2-protocol-architecture.mdx b/docs/learning/foundations/a2-protocol-architecture.mdx index c66d8ca192..11aa9f09ed 100644 --- a/docs/learning/foundations/a2-protocol-architecture.mdx +++ b/docs/learning/foundations/a2-protocol-architecture.mdx @@ -41,7 +41,7 @@ description: "Module A2: Execute your first AdCP media buy. Free 20-minute hands The Agent-to-Agent protocol — how specialized agents collaborate on complex campaigns. - + How tasks move through states: from request to completion, including async operations. @@ -61,7 +61,7 @@ description: "Module A2: Execute your first AdCP media buy. Free 20-minute hands | **Request signing** | A cryptographic signature on the request that lets the seller verify who sent it and that it wasn't tampered with in transit | | **Idempotency key** | A unique tag on each mutating request that lets a buyer safely retry without creating a duplicate | | **Domain** | A broad protocol area an agent supports — `media_buy`, `creative`, `signals`, `governance`, `brand`, `sponsored_intelligence`. Declared via `supported_protocols`. | -| **Specialism** | A narrow capability claim within a domain — e.g. `sales-guaranteed`, `creative-generative`, `signal-marketplace`. Declared via `specialisms`. See the [Compliance Catalog](/docs/building/compliance-catalog). | +| **Specialism** | A narrow capability claim within a domain — e.g. `sales-guaranteed`, `creative-generative`, `signal-marketplace`. Declared via `specialisms`. See the [Compliance Catalog](/docs/building/verification/compliance-catalog). | | **Canonical formats** | AdCP 3.1's v2 path for creative requirements: products can publish `format_options[]` that narrow shared creative archetypes such as `image` or `video_hosted`. Validate against the canonical first, then the product's narrowing. | | **Storyboard** | A scripted compliance scenario shipped by the protocol at `/compliance/{version}/` — agents don't write them, they're run against agents. An agent demonstrates its domain and specialism claims by passing the matching storyboards. | diff --git a/docs/learning/foundations/a2b-testing-your-first-agent.mdx b/docs/learning/foundations/a2b-testing-your-first-agent.mdx index 1b9eb01dc5..cb5cb8193c 100644 --- a/docs/learning/foundations/a2b-testing-your-first-agent.mdx +++ b/docs/learning/foundations/a2b-testing-your-first-agent.mdx @@ -34,7 +34,7 @@ description: "Module A2B: Hands-on lab — initialize an MCP session, call get_p How to attach assets to a buy, dry-run validation, and assignment patterns. - + Error codes, retry behavior, and how to read the `errors[]` array. diff --git a/docs/learning/foundations/a3-ecosystem-governance.mdx b/docs/learning/foundations/a3-ecosystem-governance.mdx index 2cd980addd..ca7fb37509 100644 --- a/docs/learning/foundations/a3-ecosystem-governance.mdx +++ b/docs/learning/foundations/a3-ecosystem-governance.mdx @@ -62,7 +62,7 @@ Completing A1 + A2 + A3 earns the **AdCP basics** credential. The commercial layer: advertisers, operators, authentication, billing, and account lifecycle. - + How AdCP defends against unauthorized spend, cross-tenant leakage, replay attacks, and SSRF across the ecosystem. diff --git a/docs/learning/instructional-design.mdx b/docs/learning/instructional-design.mdx index 625f2d5e5d..686fb4365d 100644 --- a/docs/learning/instructional-design.mdx +++ b/docs/learning/instructional-design.mdx @@ -184,7 +184,7 @@ Modules A1-A3, B1-B3, C1-C3, and D1-D3 follow this flow: ### Build project modules -Modules B4, C4, and D4 use a five-phase approach built on the same tools developers use in practice — [skill files](/docs/building/build-an-agent) to generate agents and [storyboards](/docs/building/validate-your-agent) to validate them: +Modules B4, C4, and D4 use a five-phase approach built on the same tools developers use in practice — [skill files](/docs/building/by-layer/L4/build-an-agent) to generate agents and [storyboards](/docs/building/verification/validate-your-agent) to validate them: 1. **Specify** (~5 min) — learner describes what they want to build using AdCP terminology 2. **Build** (~5 min) — learner points their AI coding assistant at the matching skill file from `@adcp/sdk`, which generates a working agent from the specification diff --git a/docs/learning/specialist/creative.mdx b/docs/learning/specialist/creative.mdx index a5bb8d6252..a20527e177 100644 --- a/docs/learning/specialist/creative.mdx +++ b/docs/learning/specialist/creative.mdx @@ -17,7 +17,7 @@ Passing earns the **AdCP specialist — Creative** credential. ## Specialisms this track prepares you to validate -The following `specialisms` fall under the `creative` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/compliance-catalog) for the full taxonomy. +The following `specialisms` fall under the `creative` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full taxonomy. | Specialism | Status | What it covers | |---|---|---| diff --git a/docs/learning/specialist/governance.mdx b/docs/learning/specialist/governance.mdx index bf8653b2e7..222f9985fa 100644 --- a/docs/learning/specialist/governance.mdx +++ b/docs/learning/specialist/governance.mdx @@ -17,7 +17,7 @@ Passing earns the **AdCP specialist — Governance** credential. ## Specialisms this track prepares you to validate -The following `specialisms` fall under the `governance` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/compliance-catalog) for the full taxonomy. +The following `specialisms` fall under the `governance` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full taxonomy. | Specialism | Status | What it covers | |---|---|---| diff --git a/docs/learning/specialist/media-buy.mdx b/docs/learning/specialist/media-buy.mdx index c9236daf1e..4c427160a2 100644 --- a/docs/learning/specialist/media-buy.mdx +++ b/docs/learning/specialist/media-buy.mdx @@ -28,7 +28,7 @@ Agents in the `media_buy` domain declare specific flows they support via the `sp | `sales-broadcast-tv` | stable | Broadcast linear TV with guaranteed inventory and FCC cancellation rules | | `sales-social` | stable | Social media advertising platform with self-service flows | -See the [Compliance Catalog](/docs/building/compliance-catalog) for the full taxonomy and the [`specialism` enum](https://adcontextprotocol.org/schemas/v3/enums/specialism.json) for the authoritative list. +See the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full taxonomy and the [`specialism` enum](https://adcontextprotocol.org/schemas/v3/enums/specialism.json) for the authoritative list. ## What you'll demonstrate @@ -92,7 +92,7 @@ See the [Compliance Catalog](/docs/building/compliance-catalog) for the full tax How campaign workflows in AdCP connect to impression-time execution patterns. - + Architecture patterns for multi-agent orchestration. diff --git a/docs/learning/specialist/security.mdx b/docs/learning/specialist/security.mdx index 40238ed6af..7d019dcb45 100644 --- a/docs/learning/specialist/security.mdx +++ b/docs/learning/specialist/security.mdx @@ -21,7 +21,7 @@ This module covers AdCP-specific controls — the threat model, layered defenses ## Specialisms this track prepares you to validate -The following `specialisms` fall under the security domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/compliance-catalog) for the full taxonomy. +The following `specialisms` fall under the security domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full taxonomy. | Specialism | Status | What it covers | |---|---|---| @@ -45,10 +45,10 @@ S4 (Governance) covers the 15-step JWS seller verification from the **seller's** ## Prerequisite reading - + AdCP's five-layer defense model: identity, isolation, idempotency, signed governance, and auditability. - + Implementation reference: idempotency enforcement, webhook HMAC verification, SSRF discipline, signed governance, principal isolation, and insert-rate ceiling. @@ -60,7 +60,7 @@ S4 (Governance) covers the 15-step JWS seller verification from the **seller's** Principal isolation, account-scoped access, and multi-tenant separation. - + static-credential enforcement, OAuth discovery, RFC 9728 audience binding, and the authentication baseline specialism. diff --git a/docs/learning/specialist/signals.mdx b/docs/learning/specialist/signals.mdx index d0fc9bd5ab..d24f8c9cfc 100644 --- a/docs/learning/specialist/signals.mdx +++ b/docs/learning/specialist/signals.mdx @@ -17,7 +17,7 @@ Passing earns the **AdCP specialist — Signals** credential. ## Specialisms this track prepares you to validate -The following `specialisms` fall under the `signals` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/compliance-catalog) for the full taxonomy. +The following `specialisms` fall under the `signals` domain. Each has its own compliance storyboard — see the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full taxonomy. | Specialism | Status | What it covers | |---|---|---| diff --git a/docs/learning/specialist/sponsored-intelligence.mdx b/docs/learning/specialist/sponsored-intelligence.mdx index fa9fcc4344..eddbd02d93 100644 --- a/docs/learning/specialist/sponsored-intelligence.mdx +++ b/docs/learning/specialist/sponsored-intelligence.mdx @@ -21,7 +21,7 @@ Passing earns the **AdCP specialist — Sponsored Intelligence** credential. ## Sponsored Intelligence as a full protocol -In 3.0, Sponsored Intelligence was promoted from a specialism to a full protocol. An agent that supports SI declares `sponsored_intelligence` in `supported_protocols` on `get_adcp_capabilities` — not as a specialism. The compliance runner executes the SI domain baseline storyboard at `/compliance/{version}/domains/sponsored-intelligence/` plus every universal storyboard. See the [Compliance Catalog](/docs/building/compliance-catalog). +In 3.0, Sponsored Intelligence was promoted from a specialism to a full protocol. An agent that supports SI declares `sponsored_intelligence` in `supported_protocols` on `get_adcp_capabilities` — not as a specialism. The compliance runner executes the SI domain baseline storyboard at `/compliance/{version}/domains/sponsored-intelligence/` plus every universal storyboard. See the [Compliance Catalog](/docs/building/verification/compliance-catalog). ## What you'll demonstrate @@ -53,7 +53,7 @@ In 3.0, Sponsored Intelligence was promoted from a specialism to a full protocol Product and offering catalogs — the raw material for generative creative on AI platforms. - + How to expose inventory to AI buyer agents, including governance enforcement. diff --git a/docs/learning/tracks/buyer.mdx b/docs/learning/tracks/buyer.mdx index 63124a51fc..8efc62c626 100644 --- a/docs/learning/tracks/buyer.mdx +++ b/docs/learning/tracks/buyer.mdx @@ -35,7 +35,7 @@ How buyer agents orchestrate across multiple sales agents simultaneously: discov Campaign creation: manual mode, proposal mode, validation, and approval lifecycle. - + Architecture patterns for agents that coordinate across multiple sellers. @@ -50,7 +50,7 @@ How buyer agents orchestrate across multiple sales agents simultaneously: discov Declare `adcp_major_version` on requests; sellers respond with `VERSION_UNSUPPORTED` when incompatible. - + Error taxonomy: transient, correctable, terminal. Includes `GOVERNANCE_DENIED`, `TERMS_REJECTED`, `VERSION_UNSUPPORTED`. @@ -272,7 +272,7 @@ See [Build a caller](/docs/building/by-layer/L4/build-a-caller) for client setup Buyer agents don't claim specialisms — specialisms describe what sellers offer. But your buyer agent should handle every specialism it expects to transact against. The storyboards a seller passes (declared via `supported_protocols` and `specialisms` in their `get_adcp_capabilities`) tell you what behaviors to expect. -Review the [Compliance Catalog](/docs/building/compliance-catalog) and note which specialisms your target sellers claim — that's your test matrix. +Review the [Compliance Catalog](/docs/building/verification/compliance-catalog) and note which specialisms your target sellers claim — that's your test matrix. ### Assessment rubric diff --git a/docs/learning/tracks/platform.mdx b/docs/learning/tracks/platform.mdx index 8d0647b86f..1b6024e891 100644 --- a/docs/learning/tracks/platform.mdx +++ b/docs/learning/tracks/platform.mdx @@ -32,13 +32,13 @@ Technical deep dive on building an AdCP-compliant MCP server. Transport options The definitive guide: tool calls, response format, available tools, context management. - + OAuth 2.0 for agent authentication, token management, and operator credentials. - + How brands, operators, agents, and accounts relate to each other. - + Managing context across multi-turn agent interactions. @@ -83,7 +83,7 @@ Cryptographic signatures for supply chain verification. How platforms validate a How publishers declare authorized sellers, and how buyers verify them. - + Security implementation patterns for AdCP servers. @@ -132,13 +132,13 @@ How AdCP coexists with existing programmatic infrastructure. Migration strategie The clearest view of how AdCP campaign workflows connect to impression-time execution. - + Handling long-running operations — essential for bridging real-time and agentic systems. - + Event-driven updates for delivery, status changes, and campaign modifications. - + Error patterns, retry strategies, and graceful degradation. @@ -173,7 +173,7 @@ How AdCP coexists with existing programmatic infrastructure. Migration strategie **~45 min** | Prerequisite: D3 -Build working AdCP infrastructure using any AI coding assistant (Claude Code, Cursor, Copilot) with the [`@adcp/sdk`](/docs/building/schemas-and-sdks) SDK. Point your coding assistant at a [skill file](/docs/building/build-an-agent) — choose `build-seller-agent` or `build-signals-agent` depending on what you want to build. This is the most ambitious build project. +Build working AdCP infrastructure using any AI coding assistant (Claude Code, Cursor, Copilot) with the [`@adcp/sdk`](/docs/building/schemas-and-sdks) SDK. Point your coding assistant at a [skill file](/docs/building/by-layer/L4/build-an-agent) — choose `build-seller-agent` or `build-signals-agent` depending on what you want to build. This is the most ambitious build project. ### What you'll build @@ -191,7 +191,7 @@ Run the matching storyboard against your running agent: npx @adcp/sdk@latest storyboard run my-agent media_buy_seller ``` -The storyboard validates protocol compliance across the complete workflow. See [Validate Your Agent](/docs/building/validate-your-agent) for setup, debugging, and the full CLI reference. +The storyboard validates protocol compliance across the complete workflow. See [Validate Your Agent](/docs/building/verification/validate-your-agent) for setup, debugging, and the full CLI reference. ### Specialisms you can claim @@ -201,7 +201,7 @@ Platform agents often span multiple domains. Declare each protocol you implement - Signal platform: `supported_protocols: ["signals"]`, `specialisms: ["signal-marketplace"]` or `["signal-owned"]` - Governance platform: `supported_protocols: ["governance"]`, `specialisms: ["content-standards", "property-lists", "collection-lists"]` -See the [Compliance Catalog](/docs/building/compliance-catalog) for every specialism and the storyboards that verify each claim. +See the [Compliance Catalog](/docs/building/verification/compliance-catalog) for every specialism and the storyboards that verify each claim. ### Assessment rubric diff --git a/docs/learning/tracks/publisher.mdx b/docs/learning/tracks/publisher.mdx index 271f4bc097..18a28c233a 100644 --- a/docs/learning/tracks/publisher.mdx +++ b/docs/learning/tracks/publisher.mdx @@ -204,7 +204,7 @@ Given sample Context Match and Identity Match responses, determine which package **~45 min** | Prerequisite: B3 -Create a working sales agent that responds to real buyer queries. Point your AI coding assistant (Claude Code, Cursor, Copilot) at the [`build-seller-agent`](/docs/building/build-an-agent) skill file — it generates an agent validated against AdCP storyboards, with optional [`comply_test_controller`](/docs/building/implementation/comply-test-controller) scaffolding for deterministic lifecycle testing in sandbox mode. The skill tested is specifying correct AdCP behavior. +Create a working sales agent that responds to real buyer queries. Point your AI coding assistant (Claude Code, Cursor, Copilot) at the [`build-seller-agent`](/docs/building/by-layer/L4/build-an-agent) skill file — it generates an agent validated against AdCP storyboards, with optional [`comply_test_controller`](/docs/building/by-layer/L3/comply-test-controller) scaffolding for deterministic lifecycle testing in sandbox mode. The skill tested is specifying correct AdCP behavior. ### What you'll build @@ -226,7 +226,7 @@ Run the `media_buy_seller` storyboard against your running agent: npx @adcp/sdk@latest storyboard run my-agent media_buy_seller ``` -The storyboard exercises the complete buyer workflow — discovery, account sync, media buy, creatives, delivery — and validates every response. See [Validate Your Agent](/docs/building/validate-your-agent) for setup and debugging. +The storyboard exercises the complete buyer workflow — discovery, account sync, media buy, creatives, delivery — and validates every response. See [Validate Your Agent](/docs/building/verification/validate-your-agent) for setup and debugging. ### Specialisms you can claim @@ -239,7 +239,7 @@ Declare `media_buy` in `supported_protocols` and choose the specialism that matc - `sales-broadcast-tv` — broadcast linear TV - `sales-social` — social platform with self-service flows -See the [Compliance Catalog](/docs/building/compliance-catalog) for the full list. +See the [Compliance Catalog](/docs/building/verification/compliance-catalog) for the full list. ### Assessment rubric diff --git a/docs/media-buy/advanced-topics/accounts-and-security.mdx b/docs/media-buy/advanced-topics/accounts-and-security.mdx index e016165e00..9c226cb55a 100644 --- a/docs/media-buy/advanced-topics/accounts-and-security.mdx +++ b/docs/media-buy/advanced-topics/accounts-and-security.mdx @@ -17,7 +17,7 @@ Authorization: Bearer The server validates this token and identifies the **agent** making the request. The agent may have access to one or more accounts. -See [Authentication](/docs/building/integration/authentication) for details on obtaining credentials and authentication methods. +See [Authentication](/docs/building/by-layer/L2/authentication) for details on obtaining credentials and authentication methods. ### Agents and Accounts @@ -26,7 +26,7 @@ AdCP distinguishes between: - **Agent**: The authenticated entity making API calls (e.g., `"pinnacle_trading_desk"`) - **Account**: The billing relationship for a media buy (e.g., `"acme_c/o_pinnacle"`) -An agent may operate on multiple accounts. For example, an agency trading desk might manage accounts for multiple advertisers and their own house account. See [Accounts and Agents](/docs/building/integration/accounts-and-agents) for details. +An agent may operate on multiple accounts. For example, an agency trading desk might manage accounts for multiple advertisers and their own house account. See [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents) for details. ## Data Isolation @@ -40,7 +40,7 @@ This model ensures that one account's data cannot be accessed by agents who lack ## Security Requirements -For the full normative implementation reference — two-step authorization, row-level security, IDOR defense, and the wider security posture (webhooks, idempotency, signed governance context) — see [Security — Agent and Account Isolation](/docs/building/implementation/security#agent-and-account-isolation). +For the full normative implementation reference — two-step authorization, row-level security, IDOR defense, and the wider security posture (webhooks, idempotency, signed governance context) — see [Security — Agent and Account Isolation](/docs/building/by-layer/L1/security#agent-and-account-isolation). ### Required Security Measures diff --git a/docs/media-buy/advanced-topics/agentic-execution-engine.mdx b/docs/media-buy/advanced-topics/agentic-execution-engine.mdx index 7956b81b23..e37f1d130b 100644 --- a/docs/media-buy/advanced-topics/agentic-execution-engine.mdx +++ b/docs/media-buy/advanced-topics/agentic-execution-engine.mdx @@ -422,4 +422,4 @@ AXE is designed for ad serving latency requirements: - **[Targeting](/docs/media-buy/advanced-topics/targeting)** - Brief-based targeting and geographic overlays - **[Signals Protocol](/docs/signals/overview)** - Signal discovery and activation - **[Universal Macros](/docs/creative/universal-macros)** - Creative-level AXE integration -- **[Orchestrator Design](/docs/building/implementation/orchestrator-design)** - Building orchestration platforms +- **[Orchestrator Design](/docs/building/operating/orchestrator-design)** - Building orchestration platforms diff --git a/docs/media-buy/advanced-topics/index.mdx b/docs/media-buy/advanced-topics/index.mdx index 8b8dc7d0b1..eed521feae 100644 --- a/docs/media-buy/advanced-topics/index.mdx +++ b/docs/media-buy/advanced-topics/index.mdx @@ -36,7 +36,7 @@ Enterprise-grade security features for multi-tenant environments: ### Implementation Architecture Deep technical details for implementers: -- **[Orchestrator Design](/docs/building/implementation/orchestrator-design)** - Technical architecture for AdCP orchestrators +- **[Orchestrator Design](/docs/building/operating/orchestrator-design)** - Technical architecture for AdCP orchestrators ## Development & Testing @@ -118,4 +118,4 @@ Detailed understanding of system performance: For practical application of these advanced concepts: - **Review [Sandbox Mode](/docs/media-buy/advanced-topics/sandbox)** for development best practices -- **Explore [Orchestrator Design](/docs/building/implementation/orchestrator-design)** for architecture guidance \ No newline at end of file +- **Explore [Orchestrator Design](/docs/building/operating/orchestrator-design)** for architecture guidance \ No newline at end of file diff --git a/docs/media-buy/commerce-media.mdx b/docs/media-buy/commerce-media.mdx index 189771efdf..099ffc4e99 100644 --- a/docs/media-buy/commerce-media.mdx +++ b/docs/media-buy/commerce-media.mdx @@ -40,7 +40,7 @@ The table below maps familiar retail media concepts to their AdCP equivalents. | Retail media concept | AdCP equivalent | Reference | |---|---|---| | Retailer / retail media network | Sales agent (MCP server) | [`adagents.json`](/docs/media-buy/advanced-topics/accounts-and-security) | -| Advertiser account with retailer | `account_id` + `list_accounts` | [Accounts & Agents](/docs/building/integration/accounts-and-agents) | +| Advertiser account with retailer | `account_id` + `list_accounts` | [Accounts & Agents](/docs/building/by-layer/L2/accounts-and-agents) | | Brand's product catalog | `brand.product_catalog` | [Brand identity](/docs/brand-protocol/brand-json) | | GTIN / SKU selection for promotion | Catalog selectors (`ids`, `gtins`, `tags`) on `Catalog` | [Catalogs](/docs/creative/catalogs) | | Sponsored product listing | Product with catalog-rendered creative | [Creative Formats](/docs/creative/formats) | @@ -55,7 +55,7 @@ The table below maps familiar retail media concepts to their AdCP equivalents. | Real-time inventory / in-stock | Inventory catalog via `sync_catalogs` | [Catalogs](/docs/creative/catalogs) | | Proximity / catchment targeting | Store catchment areas (isochrone, radius, GeoJSON) | [Catalogs — Catchment areas](/docs/creative/catalogs#catchment-areas) | -Each retailer is a separate sales agent. Their media offerings are modeled as products. The buyer's brand identity carries the product catalog for SKU-level creative rendering. Account relationships between brands and retailers are managed via `list_accounts` and `account` on media buys — see [Accounts & Agents](/docs/building/integration/accounts-and-agents). +Each retailer is a separate sales agent. Their media offerings are modeled as products. The buyer's brand identity carries the product catalog for SKU-level creative rendering. Account relationships between brands and retailers are managed via `list_accounts` and `account` on media buys — see [Accounts & Agents](/docs/building/by-layer/L2/accounts-and-agents). ## The product spectrum @@ -397,7 +397,7 @@ The feed contains GTINs, titles, prices, and images — everything needed to ren ### Sync catalogs to the account -Before creating media buys, sync the brand's data feeds to the retailer's account via `sync_catalogs`. This builds account state that creatives and targeting reference at serve time. See [Account state](/docs/building/integration/account-state) for how this fits the broader setup sequence. +Before creating media buys, sync the brand's data feeds to the retailer's account via `sync_catalogs`. This builds account state that creatives and targeting reference at serve time. See [Account state](/docs/building/by-layer/L2/account-state) for how this fits the broader setup sequence. ```json { @@ -684,8 +684,8 @@ An agentic storefront changes the economics. Instead of building a platform that ## Related documentation -- [Account state](/docs/building/integration/account-state) — How catalogs, event sources, and campaigns build on the account -- [Accounts & Agents](/docs/building/integration/accounts-and-agents) — Account setup and billing relationships +- [Account state](/docs/building/by-layer/L2/account-state) — How catalogs, event sources, and campaigns build on the account +- [Accounts & Agents](/docs/building/by-layer/L2/accounts-and-agents) — Account setup and billing relationships - [Media Channel Taxonomy](/docs/reference/media-channel-taxonomy) — `retail_media` channel definition - [Media Products](/docs/media-buy/product-discovery/media-products) — Product model reference - [Catalogs](/docs/creative/catalogs) — Product, inventory, store, and promotion feeds diff --git a/docs/media-buy/media-buys/index.mdx b/docs/media-buy/media-buys/index.mdx index 862cce01a3..928cea6162 100644 --- a/docs/media-buy/media-buys/index.mdx +++ b/docs/media-buy/media-buys/index.mdx @@ -469,9 +469,9 @@ Media buy operations use a unified status system with predictable timing: ## Error Handling -For comprehensive error handling guidance including pending vs error states, response patterns, and recovery strategies, see [Error Handling](/docs/building/implementation/error-handling). +For comprehensive error handling guidance including pending vs error states, response patterns, and recovery strategies, see [Error Handling](/docs/building/by-layer/L3/error-handling). -Media buy specific error codes are documented in each task specification and the [Error Handling Reference](/docs/building/implementation/error-handling). +Media buy specific error codes are documented in each task specification and the [Error Handling Reference](/docs/building/by-layer/L3/error-handling). ## Asynchronous Operations and Human-in-the-Loop @@ -608,4 +608,4 @@ Data-driven campaign improvement leveraging comprehensive analytics: - **[Product Discovery](/docs/media-buy/product-discovery/)** - Finding inventory for media buys - **[Task Reference](/docs/media-buy/task-reference/)** - Complete API documentation - **[Creatives](/docs/media-buy/creatives/)** - Creative asset management -- **[Orchestrator Design Guide](/docs/building/implementation/orchestrator-design)** - Implementation best practices +- **[Orchestrator Design Guide](/docs/building/operating/orchestrator-design)** - Implementation best practices diff --git a/docs/media-buy/media-buys/optimization-reporting.mdx b/docs/media-buy/media-buys/optimization-reporting.mdx index bd4506daec..1641b60c4a 100644 --- a/docs/media-buy/media-buys/optimization-reporting.mdx +++ b/docs/media-buy/media-buys/optimization-reporting.mdx @@ -252,7 +252,7 @@ Configure reporting webhooks when creating a media buy using the `reporting_webh - **Bearer tokens**: Simple, good for development (Authorization header) - **HMAC-SHA256**: Production-recommended, prevents replay attacks (signature headers) - Credentials exchanged out-of-band during publisher onboarding -- See [Security](/docs/building/implementation/security) for implementation details +- See [Security](/docs/building/by-layer/L1/security) for implementation details #### Supported Frequencies @@ -752,7 +752,7 @@ Publishers MUST scrub personally identifiable information (PII) from all webhook #### Webhook Health Monitoring -Webhook delivery status is tracked through **AdCP's global task management system** (see [Task Lifecycle](/docs/building/implementation/task-lifecycle)). +Webhook delivery status is tracked through **AdCP's global task management system** (see [Task Lifecycle](/docs/building/by-layer/L3/task-lifecycle)). When a media buy is created with `reporting_webhook` configured, the publisher creates an ongoing task for webhook delivery. Buyers can monitor webhook health using standard task queries. @@ -1007,7 +1007,7 @@ Each file contains one media buy delivery per line (JSONL), row (CSV/Parquet/ORC ### Security considerations for offline delivery -Offline files sit at rest for `file_retention_days`, so a misconfigured IAM policy leaks historical reporting across tenants. The [general security controls](/docs/building/implementation/security) apply; the offline-specific requirements: +Offline files sit at rest for `file_retention_days`, so a misconfigured IAM policy leaks historical reporting across tenants. The [general security controls](/docs/building/by-layer/L1/security) apply; the offline-specific requirements: - **Scope access at the IAM layer, not by obscurity.** Buyer read access MUST be scoped to `{bucket}/{prefix}/*` (S3 bucket policy condition, GCS conditional IAM binding on `resource.name.startsWith(...)`, or Azure SAS scoped to the prefix). A bucket-wide read grant is non-compliant even when the seller only writes under one prefix per account. - **Scope listing as well as reads.** Prefix scoping MUST cover both object-level operations (`s3:GetObject`) and listing (`s3:ListBucket` with an `s3:prefix` condition). A policy that scopes `GetObject` to the prefix but leaves `ListBucket` unscoped lets a buyer enumerate other tenants' prefix names — a cross-tenant isolation failure even without read access to their objects. The same applies to GCS `storage.objects.list` and Azure `list` SAS permissions. @@ -1015,7 +1015,7 @@ Offline files sit at rest for `file_retention_days`, so a misconfigured IAM poli PII scrubbing requirements (see [above](#pii-scrubbing-for-gdpr-ccpa)) apply to offline files identically — scrub at the collection layer, not at delivery, because the files accumulate at rest. -`setup_instructions` is a seller-provided URL. It is operator-facing documentation, not agent-consumable content. Buyer agents MUST NOT auto-fetch the URL; they SHOULD surface it to a human operator. If an implementation chooses to fetch it (for example, to preview the target before showing it to the operator), apply [webhook URL SSRF validation](/docs/building/implementation/security#webhook-url-validation-ssrf), and the fetched content MUST NOT be passed into an LLM context without indirect-prompt-injection guarding — seller-controlled text in this field can contain instructions to rotate credentials, change billing, or alter downstream agent behavior. +`setup_instructions` is a seller-provided URL. It is operator-facing documentation, not agent-consumable content. Buyer agents MUST NOT auto-fetch the URL; they SHOULD surface it to a human operator. If an implementation chooses to fetch it (for example, to preview the target before showing it to the operator), apply [webhook URL SSRF validation](/docs/building/by-layer/L1/security#webhook-url-validation-ssrf), and the fetched content MUST NOT be passed into an LLM context without indirect-prompt-injection guarding — seller-controlled text in this field can contain instructions to rotate credentials, change billing, or alter downstream agent behavior. ## Data Reconciliation @@ -1171,7 +1171,7 @@ Reporting webhooks follow AdCP's standard webhook reliability patterns: - **Best-effort ordering**: Notifications may arrive out of order - **Timeout and retry**: Limited retry attempts on delivery failure -See [Webhooks](/docs/building/implementation/webhooks) for detailed implementation guidance. +See [Webhooks](/docs/building/by-layer/L3/webhooks) for detailed implementation guidance. ## Optimization Strategies diff --git a/docs/media-buy/product-discovery/refinement.mdx b/docs/media-buy/product-discovery/refinement.mdx index d2a85a42ce..b6d8bb4dff 100644 --- a/docs/media-buy/product-discovery/refinement.mdx +++ b/docs/media-buy/product-discovery/refinement.mdx @@ -316,4 +316,4 @@ The [Media Buy Specification](/docs/media-buy/specification#get_products) define - [`get_products` task reference](/docs/media-buy/task-reference/get_products#refinement) — API reference with request/response schemas - [Media Products](/docs/media-buy/product-discovery/media-products) — product model and proposal structure - [Media Buy Specification](/docs/media-buy/specification#get_products) — normative requirements -- [Orchestrator Design](/docs/building/implementation/orchestrator-design) — building buyer-side agents +- [Orchestrator Design](/docs/building/operating/orchestrator-design) — building buyer-side agents diff --git a/docs/media-buy/specification.mdx b/docs/media-buy/specification.mdx index eccd1b4b1f..7c6ce67052 100644 --- a/docs/media-buy/specification.mdx +++ b/docs/media-buy/specification.mdx @@ -456,7 +456,7 @@ Manage first-party CRM audiences on a seller account. Upload hashed customer lis ## Error Handling -Sales agents MUST return errors using the [standard AdCP error schema](/docs/building/implementation/error-handling). +Sales agents MUST return errors using the [standard AdCP error schema](/docs/building/by-layer/L3/error-handling). Common error codes: diff --git a/docs/media-buy/task-reference/create_media_buy.mdx b/docs/media-buy/task-reference/create_media_buy.mdx index 67d5e03797..5f1e05d580 100644 --- a/docs/media-buy/task-reference/create_media_buy.mdx +++ b/docs/media-buy/task-reference/create_media_buy.mdx @@ -157,7 +157,7 @@ npx @adcp/sdk@latest \ | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Required for billing and policy evaluation. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Required for billing and policy evaluation. | | `proposal_id` | string | No* | ID of a committed proposal from `get_products` to execute. Alternative to providing packages. Draft proposals must be finalized first; sellers reject draft proposal execution with `PROPOSAL_NOT_COMMITTED`. | | `total_budget` | TotalBudget | No* | Total budget when executing a proposal. Publisher applies allocation percentages. | | `packages` | Package[] | No* | Array of package configurations (see below). Required when not using proposal_id. | @@ -165,7 +165,7 @@ npx @adcp/sdk@latest \ | `start_time` | string | Yes | `"asap"` or ISO 8601 date-time. For new media buys, concrete date-times must not be in the past. | | `end_time` | string | Yes | ISO 8601 date-time (UTC unless timezone specified) | | `paused` | boolean | No | Create the media buy with delivery held. When true and the buy would otherwise be active, `media_buy_status` is `paused`. Setup blockers still take precedence: missing creatives yield `pending_creatives`, and future flights yield `pending_start`; the hold becomes visible as `paused` after those blockers clear. | -| `invoice_recipient` | [BusinessEntity](/docs/building/integration/accounts-and-agents#billing-entity-and-invoice-recipient) | No | Override the account's default billing entity for this buy. The seller MUST validate the recipient is authorized and include it in `check_governance` when governance agents are configured. | +| `invoice_recipient` | [BusinessEntity](/docs/building/by-layer/L2/accounts-and-agents#billing-entity-and-invoice-recipient) | No | Override the account's default billing entity for this buy. The seller MUST validate the recipient is authorized and include it in `check_governance` when governance agents are configured. | | `po_number` | string | No | Purchase order number | | `idempotency_key` | string | No | Unique key for safe retries. If a request with the same key and account has already been processed, the seller returns the existing media buy. MUST be unique per (seller, request) pair. Min 16 chars. | | `context` | object | No | Opaque correlation data echoed unchanged in the response. Use for internal tracking, trace IDs, or other caller-specific identifiers. | @@ -215,7 +215,7 @@ When executing a proposal, `proposal_status` on the returned proposal determines | Field | Description | |-------|-------------| | `media_buy_id` | Seller's unique identifier | -| `account` | Resolved account billed for this media buy, echoed as a full [Account](/docs/building/integration/accounts-and-agents#account-references) object (includes `account_id`, `name`, `status`, and the resolved `brand`/`operator`). When the request used implicit resolution (`brand` + `operator`), this confirms the account the seller resolved. Optional. | +| `account` | Resolved account billed for this media buy, echoed as a full [Account](/docs/building/by-layer/L2/accounts-and-agents#account-references) object (includes `account_id`, `name`, `status`, and the resolved `brand`/`operator`). When the request used implicit resolution (`brand` + `operator`), this confirms the account the seller resolved. Optional. | | `confirmed_at` | ISO 8601 timestamp when the seller committed to the media buy. Stable after it is set. May be `null` in deferred/manual approval flows until seller commitment occurs. | | `creative_deadline` | ISO 8601 timestamp for creative upload deadline | | `revision` | Initial media-buy revision. Use this value as the `revision` token on the next `update_media_buy` call intended to change state. | @@ -1210,7 +1210,7 @@ This task can complete instantly or take days depending on complexity and approv | `input-required` | Needs your input | Read message, respond with info | | `failed` | Error occurred | Handle the error | -**Note:** For the complete status list see [Task Lifecycle](/docs/building/implementation/task-lifecycle). +**Note:** For the complete status list see [Task Lifecycle](/docs/building/by-layer/L3/task-lifecycle). @@ -1561,7 +1561,7 @@ await a2a.send({ -For complete async handling patterns, see [Async Operations](/docs/building/implementation/async-operations). +For complete async handling patterns, see [Async Operations](/docs/building/by-layer/L3/async-operations). ## Usage Notes diff --git a/docs/media-buy/task-reference/get_media_buy_delivery.mdx b/docs/media-buy/task-reference/get_media_buy_delivery.mdx index 2ebb679bf5..a338526e35 100644 --- a/docs/media-buy/task-reference/get_media_buy_delivery.mdx +++ b/docs/media-buy/task-reference/get_media_buy_delivery.mdx @@ -21,7 +21,7 @@ Retrieve comprehensive delivery metrics and performance data for media buy repor | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Only returns media buys belonging to this account. When omitted, returns data across all accessible accounts. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Only returns media buys belonging to this account. When omitted, returns data across all accessible accounts. | | `media_buy_ids` | string[] | No* | Array of media buy IDs to retrieve | | `status_filter` | string \| string[] | No | Status filter: `"pending_creatives"`, `"pending_start"`, `"active"`, `"paused"`, `"completed"`. Defaults to `["active"]` when omitted. | | `start_date` | string | No | Report start date (YYYY-MM-DD), inclusive. Omit for campaign lifetime data. Only accepted when product supports `date_range`. | @@ -953,5 +953,5 @@ After retrieving delivery data: ## Learn More - [Media Buy Lifecycle](/docs/media-buy/media-buys/) - Complete campaign workflow -- [Async Operations](/docs/building/implementation/async-operations) - Async patterns and status handling +- [Async Operations](/docs/building/by-layer/L3/async-operations) - Async patterns and status handling - [Performance Optimization](/docs/media-buy/media-buys/optimization-reporting) - Using delivery data for optimization diff --git a/docs/media-buy/task-reference/get_media_buys.mdx b/docs/media-buy/task-reference/get_media_buys.mdx index 2ce8221869..e1ae9346c2 100644 --- a/docs/media-buy/task-reference/get_media_buys.mdx +++ b/docs/media-buy/task-reference/get_media_buys.mdx @@ -25,7 +25,7 @@ Sellers that need to partition inventory away from a caller MUST do so at the ** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. When omitted, returns data across all accessible accounts. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. When omitted, returns data across all accessible accounts. | | `media_buy_ids` | string[] | No* | Array of media buy IDs to retrieve | | `status_filter` | string \| string[] | No | Status filter: `"pending_creatives"`, `"pending_start"`, `"active"`, `"paused"`, `"completed"`, `"rejected"`, `"canceled"`. Defaults to `["active"]` only when `media_buy_ids` is omitted. | | `include_snapshot` | boolean | No | When true, include near-real-time delivery snapshots for each package. Defaults to `false`. | diff --git a/docs/media-buy/task-reference/get_products.mdx b/docs/media-buy/task-reference/get_products.mdx index b01a125ea4..22ad581e73 100644 --- a/docs/media-buy/task-reference/get_products.mdx +++ b/docs/media-buy/task-reference/get_products.mdx @@ -1309,7 +1309,7 @@ asyncio.run(compare_auth()) - **Without credentials**: Returns limited public product results, no pricing, no custom offerings - **With credentials**: Returns complete product results with pricing and custom products -See [Authentication Guide](/docs/building/integration/authentication) for details. +See [Authentication Guide](/docs/building/by-layer/L2/authentication) for details. ## Asynchronous Operations @@ -1646,7 +1646,7 @@ Response (200 OK): | `submitted` | Custom curation queued | Poll `get_task_status` (legacy `tasks/get`) with `task_id`; also wait for webhook notification if `push_notification_config` / A2A `configuration.pushNotificationConfig` was accepted | | `failed` | Search couldn't complete | Check error message, adjust brief | -**Note:** For the complete status list see [Task Lifecycle](/docs/building/implementation/task-lifecycle). +**Note:** For the complete status list see [Task Lifecycle](/docs/building/by-layer/L3/task-lifecycle). **Most searches complete immediately.** Async processing is only needed for complex scenarios or when the system needs your input. diff --git a/docs/media-buy/task-reference/index.mdx b/docs/media-buy/task-reference/index.mdx index c872418140..98dfd94692 100644 --- a/docs/media-buy/task-reference/index.mdx +++ b/docs/media-buy/task-reference/index.mdx @@ -110,7 +110,7 @@ All tasks include JSON schema definitions for requests and responses: - **Request Schemas**: `/schemas/v3/media-buy/[task-name]-request.json` - **Response Schemas**: `/schemas/v3/media-buy/[task-name]-response.json` -**Task Management**: For tracking async operations across all AdCP domains, see [Task Lifecycle](/docs/building/implementation/task-lifecycle). +**Task Management**: For tracking async operations across all AdCP domains, see [Task Lifecycle](/docs/building/by-layer/L3/task-lifecycle). Schemas are accessible at runtime via the documentation server for validation and tooling. diff --git a/docs/media-buy/task-reference/sync_audiences.mdx b/docs/media-buy/task-reference/sync_audiences.mdx index bd7395f048..2207793eda 100644 --- a/docs/media-buy/task-reference/sync_audiences.mdx +++ b/docs/media-buy/task-reference/sync_audiences.mdx @@ -116,7 +116,7 @@ asyncio.run(main()) | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. | | `audiences` | [Audience](#audience-object)[] | No | Audiences to sync. When omitted, the call is discovery-only and returns all existing audiences without modification. | | `delete_missing` | boolean | No | When true, buyer-managed audiences on the account not in this request are removed (default: false). Does not affect seller-managed audiences. Do not combine with an omitted `audiences` array or all buyer-managed audiences will be deleted. | @@ -534,7 +534,7 @@ Two distinct async patterns — match the right one to the seller's behavior: Poll `tasks/get` or wait for the webhook. The completion artifact carries the `audiences` array with per-item `action`/`status` results; operation-level failures surface as `status: "failed"` on the task. -**See:** [Webhooks](/docs/building/implementation/webhooks) for webhook configuration. +**See:** [Webhooks](/docs/building/by-layer/L3/webhooks) for webhook configuration. ## Hashing Requirements diff --git a/docs/media-buy/task-reference/sync_catalogs.mdx b/docs/media-buy/task-reference/sync_catalogs.mdx index a134ba975a..3b9983dec1 100644 --- a/docs/media-buy/task-reference/sync_catalogs.mdx +++ b/docs/media-buy/task-reference/sync_catalogs.mdx @@ -28,7 +28,7 @@ sequenceDiagram Note over B,S: Buyer can now reference synced catalogs in creatives ``` -This task sits between format discovery and creative submission in the [account state setup sequence](/docs/building/integration/account-state): +This task sits between format discovery and creative submission in the [account state setup sequence](/docs/building/by-layer/L2/account-state): 1. `list_creative_formats` — check `catalog` asset types in each format's `assets` array to know what feeds to sync 2. **`sync_catalogs`** — push the required feeds to the account @@ -59,7 +59,7 @@ Sync a product feed: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | Conditional | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Required when the agent has multiple accounts. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Conditional | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. Required when the agent has multiple accounts. | | `catalogs` | Catalog[] | No | Catalog feeds to sync (max 50). Omit for discovery mode. | | `catalog_ids` | string[] | No | Limit sync scope to specific catalog IDs. Others on the account are unaffected. | | `delete_missing` | boolean | No | When true, buyer-managed catalogs not in this sync are removed. Does not affect seller-managed catalogs. Requires `catalogs` to be present. Default: false. | @@ -263,6 +263,6 @@ Configure `push_notification_config` on the request to receive webhook notificat ## Next steps - [Catalogs](/docs/creative/catalogs) — Complete documentation on catalog types, sourcing, and format requirements -- [Account state](/docs/building/integration/account-state) — How catalogs fit into the account setup sequence +- [Account state](/docs/building/by-layer/L2/account-state) — How catalogs fit into the account setup sequence - [sync_creatives](/docs/creative/task-reference/sync_creatives) — Submit creatives that reference synced catalogs - [list_creative_formats](/docs/creative/task-reference/list_creative_formats) — Discover format catalog requirements diff --git a/docs/media-buy/task-reference/sync_event_sources.mdx b/docs/media-buy/task-reference/sync_event_sources.mdx index 1840fe4c93..77b992fde4 100644 --- a/docs/media-buy/task-reference/sync_event_sources.mdx +++ b/docs/media-buy/task-reference/sync_event_sources.mdx @@ -90,7 +90,7 @@ asyncio.run(main()) | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Yes | Account reference. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }` if the seller supports implicit resolution. | | `event_sources` | [EventSource](/docs/media-buy/conversion-tracking/#event-source)[] | No | Event sources to sync. When omitted, the call is discovery-only and returns all existing event sources without modification. | | `delete_missing` | boolean | No | When true, buyer-managed event sources on the account not in this request are removed (default: false) | diff --git a/docs/media-buy/task-reference/update_media_buy.mdx b/docs/media-buy/task-reference/update_media_buy.mdx index 92cc06cbe2..6421e2bd12 100644 --- a/docs/media-buy/task-reference/update_media_buy.mdx +++ b/docs/media-buy/task-reference/update_media_buy.mdx @@ -187,7 +187,7 @@ asyncio.run(create_and_pause_campaign()) | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `account` | [account-ref](/docs/building/integration/accounts-and-agents#account-references) | Yes | Account that owns this media buy. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }`. Required for governance checks and account resolution. | +| `account` | [account-ref](/docs/building/by-layer/L2/accounts-and-agents#account-references) | Yes | Account that owns this media buy. Pass `{ "account_id": "..." }` or `{ "brand": {...}, "operator": "..." }`. Required for governance checks and account resolution. | | `media_buy_id` | string | Yes | Seller's media buy identifier to update | | `revision` | integer | No | Expected current revision for optimistic concurrency. Seller rejects with `CONFLICT` on mismatch. Obtain from `get_media_buys` or the most recent response. | | `start_time` | string | No | Updated campaign start time | @@ -198,7 +198,7 @@ asyncio.run(create_and_pause_campaign()) | `packages` | PackageUpdate[] | No | Package-level updates (see below) | | `reporting_webhook` | object | No | Update reporting webhook configuration (see below) | | `idempotency_key` | string | No | Unique key for safe retries. If an update with the same key has already been processed, the seller returns the original response. MUST be unique per (seller, request) pair. Min 16 chars. | -| `invoice_recipient` | [BusinessEntity](/docs/building/integration/accounts-and-agents#billing-entity-and-invoice-recipient) | No | Override who receives the invoice for this buy. The seller MUST validate authorization and include in `check_governance` when governance agents are configured. | +| `invoice_recipient` | [BusinessEntity](/docs/building/by-layer/L2/accounts-and-agents#billing-entity-and-invoice-recipient) | No | Override who receives the invoice for this buy. The seller MUST validate authorization and include in `check_governance` when governance agents are configured. | | `new_packages` | PackageRequest[] | No | New packages to add to this media buy. Same shape as `create_media_buy` packages. Only supported by sellers that advertise `add_packages` in `valid_actions`. | | `push_notification_config` | object | No | Webhook for async operation notifications | @@ -881,7 +881,7 @@ AdCP tasks work across multiple protocols (MCP, A2A, REST). Each protocol handle - **Updates**: Protocol-specific mechanisms - **Long-running tasks**: Different timeout and notification patterns -See [Async Operations](/docs/building/implementation/async-operations) for protocol-specific async patterns and examples. +See [Async Operations](/docs/building/by-layer/L3/async-operations) for protocol-specific async patterns and examples. ## Best Practices @@ -917,7 +917,7 @@ Check `affected_packages` in response to confirm changes were applied correctly. When a buyer's account has governance agents configured, sellers MUST call [`check_governance`](/docs/governance/campaign/tasks/check_governance) with `media_buy_id`, `planned_delivery`, and `phase: "modification"` before confirming an update. The governance agent validates change magnitude, budget reallocation, and new parameters against the campaign plan. -See the [seller integration guide](/docs/building/implementation/seller-integration#execution-checks) for the full execution check workflow and code example. +See the [seller integration guide](/docs/building/operating/seller-integration#execution-checks) for the full execution check workflow and code example. ## Next Steps @@ -933,5 +933,5 @@ After updating a media buy: - [Media Buy Lifecycle](/docs/media-buy/media-buys/) - Complete campaign workflow - [Targeting](/docs/media-buy/advanced-topics/targeting) - Targeting overlays and restrictions -- [Async Operations](/docs/building/implementation/async-operations) - Async patterns and status checking +- [Async Operations](/docs/building/by-layer/L3/async-operations) - Async patterns and status checking - [create_media_buy](/docs/media-buy/task-reference/create_media_buy) - Initial campaign creation diff --git a/docs/protocol/architecture.mdx b/docs/protocol/architecture.mdx index 826f892a35..243066a046 100644 --- a/docs/protocol/architecture.mdx +++ b/docs/protocol/architecture.mdx @@ -111,7 +111,7 @@ AdCP is a multi-instance protocol. A single buyer's workflow with an agent may b ### Normative requirements -State keyed by a `(brand, account)` tuple MUST survive across agent process instances. This includes but is not limited to accounts, catalogs, creatives, audiences, event sources, governance configuration, active campaigns, proposals, insertion-order approval records, signal activations, sponsored-intelligence sessions, async task records, and idempotency-key cache entries. Implementations MUST NOT use in-process memory as the primary store for any `(brand, account)`-scoped state that a subsequent call can read back. In-process storage does not satisfy this requirement. For the canonical (non-exhaustive) catalog of state domains, see [Account state](/docs/building/integration/account-state). +State keyed by a `(brand, account)` tuple MUST survive across agent process instances. This includes but is not limited to accounts, catalogs, creatives, audiences, event sources, governance configuration, active campaigns, proposals, insertion-order approval records, signal activations, sponsored-intelligence sessions, async task records, and idempotency-key cache entries. Implementations MUST NOT use in-process memory as the primary store for any `(brand, account)`-scoped state that a subsequent call can read back. In-process storage does not satisfy this requirement. For the canonical (non-exhaustive) catalog of state domains, see [Account state](/docs/building/by-layer/L2/account-state). **Acceptable storage:** Postgres, Redis, DynamoDB, or any shared store that persists across process restarts and is reachable from every replica. **Not acceptable:** module-level variables, per-process Maps or dicts, single-node file storage, or sticky-session routing that masks the absence of shared state. @@ -119,4 +119,4 @@ Within a single `(brand, account)` context, implementations MUST support read-yo **Sandbox exemption.** Sandbox accounts are allowed to carry ephemeral state that does not persist across process restarts (see [Sandbox mode](/docs/media-buy/advanced-topics/sandbox)). Within a single sandbox session, read-your-writes across replicas still applies. -Implementations may prove this invariant by architecture (managed serverless + shared datastore), by multi-instance compliance testing, or by their own verification; the protocol cares about the invariant, not the methodology. See [Validate your agent — Verifying cross-instance state](/docs/building/validate-your-agent#verifying-cross-instance-state). +Implementations may prove this invariant by architecture (managed serverless + shared datastore), by multi-instance compliance testing, or by their own verification; the protocol cares about the invariant, not the methodology. See [Validate your agent — Verifying cross-instance state](/docs/building/verification/validate-your-agent#verifying-cross-instance-state). diff --git a/docs/protocol/design-principles.mdx b/docs/protocol/design-principles.mdx index 61ed89dee8..4ef5bdec9e 100644 --- a/docs/protocol/design-principles.mdx +++ b/docs/protocol/design-principles.mdx @@ -107,7 +107,7 @@ AdCP defines what fields exist and what guarantees the protocol makes about them - *Capabilities are declared, not gated.* `check_governance` is a seam, not an enforcer. A seller that hasn't configured a governance agent will not call it; the protocol doesn't prevent a non-conformant seller from transacting. Schema-level enforcement exists but is rare and named (`fair_housing`, `fair_lending`, `fair_employment` in 3.0); the default is exposure, not coercion. - *Async is the default; sync is the optimization.* Every mutating task has `*-async-response-{submitted,working,input-required}.json` siblings. A protocol that pretends every operation is synchronous and atomic is one that breaks the moment a real workflow lands. -- *Human review is architectural, not exceptional.* Any mutation can be taken async for human approval via the [task lifecycle](/docs/building/implementation/task-lifecycle); campaign governance provides a declarative buyer-side review channel. HITL composes with everything else — audit logs, governance checks, async responses — rather than being a special case bolted onto certain tasks. +- *Human review is architectural, not exceptional.* Any mutation can be taken async for human approval via the [task lifecycle](/docs/building/by-layer/L3/task-lifecycle); campaign governance provides a declarative buyer-side review channel. HITL composes with everything else — audit logs, governance checks, async responses — rather than being a special case bolted onto certain tasks. A related invariant lives at the account boundary: **account ownership, not creation surface, determines visibility.** Buys created outside AdCP still belong to the account they fall under, and surface in account-scoped queries. This prevents the shadow-ledger pattern that breaks every "API on top of an ad server." diff --git a/docs/protocol/get_adcp_capabilities.mdx b/docs/protocol/get_adcp_capabilities.mdx index d14f31cfdd..05d546d415 100644 --- a/docs/protocol/get_adcp_capabilities.mdx +++ b/docs/protocol/get_adcp_capabilities.mdx @@ -170,7 +170,7 @@ Account and authentication capabilities. All sellers should declare this section For sandbox, the path follows the account namespace: account-id namespaces discover pre-existing test accounts via `list_accounts` or out-of-band setup; buyer-declared accounts declare sandbox via `sync_accounts` with `sandbox: true`. -See [Accounts and Agents](/docs/building/integration/accounts-and-agents#what-sellers-declare) for full workflows and [seller patterns](/docs/building/integration/accounts-and-agents#seller-patterns) for common combinations of auth model and billing support. +See [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents#what-sellers-declare) for full workflows and [seller patterns](/docs/building/by-layer/L2/accounts-and-agents#seller-patterns) for common combinations of auth model and billing support. ### media_buy @@ -544,13 +544,13 @@ Compliance testing is sandbox-only at the deployment level — production deploy ### webhook_signing -Declares a seller's webhook-signing posture. Any seller whose capability surface advertises mutating-webhook emission — including but not limited to `media_buy.reporting_delivery_methods` containing `webhook`, `media_buy.content_standards.supports_webhook_delivery: true`, or `wholesale_feed_webhooks.supported: true` — MUST include this block with `supported: true`. A seller that emits no webhooks at all MAY omit the block entirely; the absence of both mutating-webhook emission in other capabilities and this block is an unambiguous "does not emit webhooks" posture. Buyers read the block at onboarding to determine which algorithms to expect per the [AdCP webhook-signing profile](/docs/building/implementation/security#webhook-callbacks). Buyers integrating with a seller that advertises mutating-webhook emission while advertising `supported: false` or omitting this block MUST fail onboarding with a user-actionable error; silent integration with a non-signing-but-webhook-emitting seller is unsafe for any mutating-webhook use case. +Declares a seller's webhook-signing posture. Any seller whose capability surface advertises mutating-webhook emission — including but not limited to `media_buy.reporting_delivery_methods` containing `webhook`, `media_buy.content_standards.supports_webhook_delivery: true`, or `wholesale_feed_webhooks.supported: true` — MUST include this block with `supported: true`. A seller that emits no webhooks at all MAY omit the block entirely; the absence of both mutating-webhook emission in other capabilities and this block is an unambiguous "does not emit webhooks" posture. Buyers read the block at onboarding to determine which algorithms to expect per the [AdCP webhook-signing profile](/docs/building/by-layer/L1/security#webhook-callbacks). Buyers integrating with a seller that advertises mutating-webhook emission while advertising `supported: false` or omitting this block MUST fail onboarding with a user-actionable error; silent integration with a non-signing-but-webhook-emitting seller is unsafe for any mutating-webhook use case. | Field | Type | Description | |-------|------|-------------| | `supported` | boolean | **Required when the seller advertises mutating-webhook emission elsewhere in its capability surface.** `true` iff the seller signs outbound webhooks. `false` means the seller emits webhooks but does not sign them; buyers MUST fail onboarding. Sellers that emit no webhooks SHOULD omit the entire block rather than set `supported: false` — `false` is reserved for the unsafe posture of unsigned-webhook emission, not absence-of-webhooks. | | `profile` | string | **Required when `supported: true`.** The profile version string. Currently `"adcp/webhook-signing/v1"`. Future versions bump the string. | -| `algorithms` | string[] | **Required when `supported: true`.** Subset of `["ed25519", "ecdsa-p256-sha256"]` — the algorithms this seller will sign webhooks with. Matches the webhook-signing verifier allowlist (see [Verifier checklist for webhooks](/docs/building/implementation/security#webhook-callbacks), step 4). Buyers MUST be prepared to verify any algorithm listed AND MUST reject onboarding with a user-actionable error if an advertised algorithm is outside this enumerated set — a seller advertising an out-of-set algorithm (e.g., `hs256`) is either misconfigured or signalling a non-conforming profile. | +| `algorithms` | string[] | **Required when `supported: true`.** Subset of `["ed25519", "ecdsa-p256-sha256"]` — the algorithms this seller will sign webhooks with. Matches the webhook-signing verifier allowlist (see [Verifier checklist for webhooks](/docs/building/by-layer/L1/security#webhook-callbacks), step 4). Buyers MUST be prepared to verify any algorithm listed AND MUST reject onboarding with a user-actionable error if an advertised algorithm is outside this enumerated set — a seller advertising an out-of-set algorithm (e.g., `hs256`) is either misconfigured or signalling a non-conforming profile. | | `legacy_hmac_fallback` | boolean | **Required when `supported: true`.** `true` iff the seller supports the legacy HMAC-SHA256 scheme when the buyer populates `push_notification_config.authentication.credentials` or `accounts[].notification_configs[].authentication.credentials`. `false` is the recommended posture in 3.x — the HMAC scheme is removed in AdCP 4.0. | **Example:** @@ -576,7 +576,7 @@ Array of extension namespaces this agent supports. Buyers can expect meaningful |-------|------|-------------| | `extensions_supported` | string[] | Extension namespaces (e.g., `["iab_tcf", "iab_gpp"]`) | -Extension schemas are published in the [AdCP extension registry](/docs/building/integration/context-sessions#extensions). When an agent declares support for an extension, buyers know to look for and process `ext.{namespace}` data in responses. +Extension schemas are published in the [AdCP extension registry](/docs/building/by-layer/L2/context-sessions#extensions). When an agent declares support for an extension, buyers know to look for and process `ext.{namespace}` data in responses. **Example:** ```json @@ -1109,14 +1109,14 @@ Route requests to appropriate API versions based on `adcp.major_versions`. After discovering capabilities: -1. **Set up accounts**: Follow the auth model from `account.require_operator_auth` — see [Accounts and Agents](/docs/building/integration/accounts-and-agents#what-sellers-declare) +1. **Set up accounts**: Follow the auth model from `account.require_operator_auth` — see [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents#what-sellers-declare) 2. **Filter products**: Use [`get_products`](/docs/media-buy/task-reference/get_products) with capability-aware filters 3. **Validate properties**: Fetch publisher `adagents.json` files for property definitions 4. **Create buys**: Use [`create_media_buy`](/docs/media-buy/task-reference/create_media_buy) with supported features ## Learn More -- [Accounts and Agents](/docs/building/integration/accounts-and-agents) - Auth models, account setup, billing +- [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents) - Auth models, account setup, billing - [adagents.json Specification](/docs/governance/property/adagents) - Publisher authorization files - [Product Filters](/docs/media-buy/task-reference/get_products#filters) - Capability-aware filtering - [Content Standards](/docs/governance/content-standards) - Brand safety configuration diff --git a/docs/protocol/required-tasks.mdx b/docs/protocol/required-tasks.mdx index db69c70569..c2ef489242 100644 --- a/docs/protocol/required-tasks.mdx +++ b/docs/protocol/required-tasks.mdx @@ -47,7 +47,7 @@ AdCP task lifecycle state is application-layer state, not MCP-native or A2A-nati Sales agents MUST also support at least one transport (MCP or A2A) and declare `media_buy` in `supported_protocols`. -**Reference**: [Media Buy Specification](/docs/media-buy/specification) · [Seller integration guide](/docs/building/implementation/seller-integration) +**Reference**: [Media Buy Specification](/docs/media-buy/specification) · [Seller integration guide](/docs/building/operating/seller-integration) ### Orchestrator (buyer) diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index 36b925d763..e673ec9a86 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -10,7 +10,7 @@ Pick your path. Buyers call the public test agent in 5 minutes. Publishers and s Buyer side. The rest of this page walks through calling the public test agent — no signup, copy-pasteable curl. - + Publisher or seller side. Stand up an agent buyers can call. @@ -171,7 +171,7 @@ Replay the same request (same key, same payload) and the seller returns the orig { "idempotency": { "supported": true, "replay_ttl_seconds": 86400 } } ``` -See the [Security guide](/docs/building/implementation/security) for the full retry model, including `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_EXPIRED`, and UUID v4 guidance for AdCP Verified agents. +See the [Security guide](/docs/building/by-layer/L1/security) for the full retry model, including `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_EXPIRED`, and UUID v4 guidance for AdCP Verified agents. **Response** (IDs will differ on each call): @@ -264,7 +264,7 @@ app.post('/webhooks/adcp/*', async (req, res) => { }); ``` -See the [Security guide](/docs/building/implementation/security) and [Webhooks guide](/docs/building/implementation/webhooks) for the full verification profile — required headers, covered components, nonce and date windows, and the negative-vector suite the compliance runner exercises. +See the [Security guide](/docs/building/by-layer/L1/security) and [Webhooks guide](/docs/building/by-layer/L3/webhooks) for the full verification profile — required headers, covered components, nonce and date windows, and the negative-vector suite the compliance runner exercises. ## Using the client library diff --git a/docs/reference/glossary.mdx b/docs/reference/glossary.mdx index 24bd57da76..09b6646975 100644 --- a/docs/reference/glossary.mdx +++ b/docs/reference/glossary.mdx @@ -8,7 +8,7 @@ description: "AdCP glossary: definitions of agents, accounts, audiences, signals ## A **Account** -A billing relationship between a buyer and a seller. The account determines rate cards, payment terms, and billing entity. An agent may have access to multiple accounts (e.g., an agency managing accounts for different clients). See [Accounts and Agents](/docs/building/integration/accounts-and-agents). +A billing relationship between a buyer and a seller. The account determines rate cards, payment terms, and billing entity. An agent may have access to multiple accounts (e.g., an agency managing accounts for different clients). See [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents). **Account Type** Classification of MCP session credentials as either "platform" (aggregator) or "customer" (direct advertiser/agency). @@ -44,7 +44,7 @@ Deprecated. The original real-time execution layer for impression-time targeting The member organization that stewards the Ad Context Protocol (AdCP) and related open standards for AI-powered advertising. **Agent** (AdCP Context) -The authenticated entity making API calls—may be a brand's internal team, an agency's trading desk, or an automated buying system. Identified by the authentication token. Distinct from "Sales Agent" (the MCP server exposing inventory) and "AI Agent" (the AI assistant). See [Accounts and Agents](/docs/building/integration/accounts-and-agents). +The authenticated entity making API calls—may be a brand's internal team, an agency's trading desk, or an automated buying system. Identified by the authentication token. Distinct from "Sales Agent" (the MCP server exposing inventory) and "AI Agent" (the AI assistant). See [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents). ## B @@ -162,10 +162,10 @@ Protocol feature allowing publishers to require manual approval for operations. TMP operation that evaluates user eligibility against package criteria using an opaque user token. Returns a boolean `eligible` flag and optional `intent_score` per package. Carries no page context. The buyer computes eligibility from frequency caps, audience membership, and other signals; the reasons are opaque to the publisher. See [Trusted Match Protocol](/docs/trusted-match). **Idempotency** -The property that repeating the same operation produces the same result as running it once, with no extra side effects. Every mutating AdCP request carries a required `idempotency_key`; on retry with the same key and payload, the seller returns the cached response with `replayed: true` instead of re-executing. This is what lets an agent safely retry a `create_media_buy` after a network timeout without creating two buys. See the [Security Model](/docs/building/understanding/security-model#layer-3-idempotency--at-most-once-execution) for the narrative and [Security: Request Safety](/docs/building/implementation/security#idempotency) for the normative rules. +The property that repeating the same operation produces the same result as running it once, with no extra side effects. Every mutating AdCP request carries a required `idempotency_key`; on retry with the same key and payload, the seller returns the cached response with `replayed: true` instead of re-executing. This is what lets an agent safely retry a `create_media_buy` after a network timeout without creating two buys. See the [Security Model](/docs/building/concepts/security-model#layer-3-idempotency--at-most-once-execution) for the narrative and [Security: Request Safety](/docs/building/by-layer/L1/security#idempotency) for the normative rules. **Idempotency Key** -A unique, unguessable identifier (UUID v4 or equivalent CSPRNG output) attached to every mutating AdCP request. Scoped per `(authenticated agent, account)`. The seller uses it as the cache key for at-most-once execution within the declared `replay_ttl_seconds` window (minimum 1 hour, recommended 24 hours, maximum 7 days). Same key + same payload = replay; same key + different payload = `IDEMPOTENCY_CONFLICT`. See [Security: Request Safety](/docs/building/implementation/security#idempotency). +A unique, unguessable identifier (UUID v4 or equivalent CSPRNG output) attached to every mutating AdCP request. Scoped per `(authenticated agent, account)`. The seller uses it as the cache key for at-most-once execution within the declared `replay_ttl_seconds` window (minimum 1 hour, recommended 24 hours, maximum 7 days). Same key + same payload = replay; same key + different payload = `IDEMPOTENCY_CONFLICT`. See [Security: Request Safety](/docs/building/by-layer/L1/security#idempotency). **Impressions** (Media Buy Protocol) The number of times an ad is displayed, used for pricing and delivery tracking. @@ -346,7 +346,7 @@ The data type of a signal's values: `binary` (user matches or doesn't), `categor The measurement type for signal size: individuals, devices, or households. **Specialism** -A specific capability claim an agent declares in `get_adcp_capabilities.specialisms`. Each specialism has a wire ID in `kebab-case` (e.g. `sales-guaranteed`, `property-lists`) and a matching storyboard bundle published at `/compliance/{version}/specialisms/{id}/`. The AAO compliance runner executes the matching storyboards to verify the claim. See [Compliance Catalog](/docs/building/compliance-catalog) for the list of specialism IDs; claim one by adding it to your `get_adcp_capabilities.specialisms` array, then run [Validate Your Agent](/docs/building/validate-your-agent) to see how the runner maps it to storyboards. +A specific capability claim an agent declares in `get_adcp_capabilities.specialisms`. Each specialism has a wire ID in `kebab-case` (e.g. `sales-guaranteed`, `property-lists`) and a matching storyboard bundle published at `/compliance/{version}/specialisms/{id}/`. The AAO compliance runner executes the matching storyboards to verify the claim. See [Compliance Catalog](/docs/building/verification/compliance-catalog) for the list of specialism IDs; claim one by adding it to your `get_adcp_capabilities.specialisms` array, then run [Validate Your Agent](/docs/building/verification/validate-your-agent) to see how the runner maps it to storyboards. **Sponsored Intelligence (SI)** An open standard for conversational brand experiences in AI assistants. Like VAST defines video ad serving, SI defines how to serve and interact with brand agent endpoints. SI handles the engagement; the Agentic Commerce Protocol (ACP) handles transactions. See [SI Chat Protocol](/docs/sponsored-intelligence/si-chat-protocol) for details. @@ -355,7 +355,7 @@ An open standard for conversational brand experiences in AI assistants. Like VAS A type of decisioning platform that helps publishers sell advertising inventory programmatically. SSPs connect to multiple demand sources and make ad selection decisions. Examples: Index Exchange, OpenX, PubMatic, Magnite. **SSRF (Server-Side Request Forgery)** -A class of attack where an adversary supplies a URL that tricks an agent into making an HTTP request to an address it shouldn't — typically an internal service, a cloud metadata endpoint (e.g., `169.254.169.254`), or a localhost port. Every URL an AdCP counterparty supplies (webhook callbacks, TMP provider endpoints, governance `jwks_uri`, reporting buckets, `adagents.json` `authoritative_location`) is a potential vector. Defense is implemented in code via a 6-point check: HTTPS-only, reserved-IP deny list, IP pinning against DNS rebinding, no redirects, response size and timeout caps, suppressed error detail. See the [Security Model](/docs/building/understanding/security-model) for the narrative and [Security: Webhook URL validation](/docs/building/implementation/security#webhook-url-validation-ssrf) for the normative rules. +A class of attack where an adversary supplies a URL that tricks an agent into making an HTTP request to an address it shouldn't — typically an internal service, a cloud metadata endpoint (e.g., `169.254.169.254`), or a localhost port. Every URL an AdCP counterparty supplies (webhook callbacks, TMP provider endpoints, governance `jwks_uri`, reporting buckets, `adagents.json` `authoritative_location`) is a potential vector. Defense is implemented in code via a 6-point check: HTTPS-only, reserved-IP deny list, IP pinning against DNS rebinding, no redirects, response size and timeout caps, suppressed error detail. See the [Security Model](/docs/building/concepts/security-model) for the narrative and [Security: Webhook URL validation](/docs/building/by-layer/L1/security#webhook-url-validation-ssrf) for the normative rules. **Storyboard** A compliance test bundle that verifies a protocol baseline or [specialism](#specialism) claim. Each storyboard is a YAML file under `/compliance/{version}/` that declares an `id`, phases of test steps, sample requests, and validations the agent must pass. Storyboards live in three buckets: `universal/` (applies to every agent), `protocols/{protocol}/` (one baseline per supported protocol), and `specialisms/{id}/` (one per specialism claim). diff --git a/docs/reference/known-limitations.mdx b/docs/reference/known-limitations.mdx index 7e49583728..4341f8f9aa 100644 --- a/docs/reference/known-limitations.mdx +++ b/docs/reference/known-limitations.mdx @@ -19,7 +19,7 @@ Surfaces shipped in 3.x but not yet frozen are listed separately — see [Experi - **No protocol-level PII transport.** The `hashed_email` and `hashed_phone` fields in `sync_audiences` require SHA-256 hashing on the buyer side — the schemas do not accept cleartext for those fields. Other identifier types exist for non-PII spaces. If you need cleartext PII on the wire, AdCP is not the right carrier. - **Hashed identifiers are pseudonymous, not anonymous.** SHA-256 hashes of email and phone remain pseudonymous identifiers under GDPR and CPRA and inherit the regulatory treatment of the underlying PII. AdCP does not claim de-identification. - **No protocol-level data-residency mechanism.** Residency is a configuration and contract property of individual agents; the protocol does not carry a normative residency tag. -- **No protocol guarantee about LLM prompt-injection defense.** That is an operator concern on every LLM-powered agent in the loop. See the [Security Model — threats specific to agentic advertising](/docs/building/understanding/security-model#threats-specific-to-agentic-advertising). +- **No protocol guarantee about LLM prompt-injection defense.** That is an operator concern on every LLM-powered agent in the loop. See the [Security Model — threats specific to agentic advertising](/docs/building/concepts/security-model#threats-specific-to-agentic-advertising). - **Structural privacy applies only to TMP.** The Trusted Match Protocol enforces privacy structurally (separated code paths, schema prohibitions). Every other domain relies on contractual confidentiality or per-session consent. See [Privacy posture across domains](/docs/protocol/architecture#privacy-posture-across-domains). - **No jurisdictionally-aware consent signal on the wire.** AdCP does not carry a normative consent tag (e.g., IAB TCF, GPP, or equivalents used to express compliance with regimes like Quebec's Law 25, Japan's APPI, or Brazil's LGPD). Lawful-basis determination, consent capture, and jurisdictional routing remain the responsibility of each party acting as controller or processor in its own stack, governed by the DPAs between them. A structured cross-agent consent signal is a candidate for future work. - **No consent-scope propagation across protocol boundaries.** A signal activated under one consent scope (e.g., `sync_audiences` from a CRM with first-party advertising consent) can be referenced downstream — re-targeted, attached to a different campaign, or composed with other signals — without a protocol-level mechanism enforcing scope alignment. Each party verifies scope compatibility off-protocol via DPAs and operational controls. Tracked for 3.1 in [#2540](https://github.com/adcontextprotocol/adcp/issues/2540). @@ -52,7 +52,7 @@ Surfaces shipped in 3.x but not yet frozen are listed separately — see [Experi ## Conformance and testing -- **Reference test vectors are partial.** [Conformance](/docs/building/conformance) is defined by the storyboard suite, and the suite publishes request-signing and canonicalization vectors today — but a broader corpus of reference test vectors is tracked in [#2383](https://github.com/adcontextprotocol/adcp/issues/2383). +- **Reference test vectors are partial.** [Conformance](/docs/building/verification/conformance) is defined by the storyboard suite, and the suite publishes request-signing and canonicalization vectors today — but a broader corpus of reference test vectors is tracked in [#2383](https://github.com/adcontextprotocol/adcp/issues/2383). - **AdCP Verified is self-attested in 3.0; the formal program launches with 3.1.** Today, agents publish their own signed `runner-output.json` — reproducible and re-runnable by any verifying party, but not AAO-audited. The training agent and official SDKs are being brought to full storyboard compliance over the 3.0 → 3.1 window on a 4–6 week cadence (training agent is at 32/55 clean today). When they pass cleanly and the ambiguous-storyboard work is done, AAO will run submitted agents against the canonical storyboard suite and maintain a public registry of Verified agents. The compliance runner and storyboards are themselves software at 3.0 — storyboard bugs, coverage gaps, and encoded-spec-intent ambiguities are legitimate GitHub issues alongside implementation bugs. - **No automated enforcement of platform agnosticism** beyond the `check:platform-agnostic` lint scanning property names. A richer check covering schema semantics is future work. - **No latency or response-time SLA.** The protocol has no normative expectations for how quickly an agent must respond (unlike OpenRTB's per-auction `tmax`). Buyers and sellers negotiate timing through the commercial relationship or through task-specific [accountability terms](/docs/media-buy/advanced-topics/accountability). A structured SLA declaration is deferred. @@ -76,7 +76,7 @@ Think of AdCP as specifying the locks on the doors. The operator still owns the ## Related -- [Security Model](/docs/building/understanding/security-model) — the threat model and layered defense +- [Security Model](/docs/building/concepts/security-model) — the threat model and layered defense - [Privacy Considerations](/docs/reference/privacy-considerations) — cross-protocol privacy entry point - [Experimental Status](/docs/reference/experimental-status) — surfaces shipped in 3.x but not yet frozen - [Versioning & Governance](/docs/reference/versioning) — cadence, support windows, and how limitations become follow-ups diff --git a/docs/reference/migration/index.mdx b/docs/reference/migration/index.mdx index 1a922f70d4..7410b34e0d 100644 --- a/docs/reference/migration/index.mdx +++ b/docs/reference/migration/index.mdx @@ -55,12 +55,12 @@ Each row is a breaking change. **Effort** indicates the typical work involved: | Products | `buying_mode` required on every `get_products` request | New requirement | [get_products reference](/docs/media-buy/task-reference/get_products) | | Media buy status | `pending_activation` → `pending_start` | Rename | [Media buys](/docs/media-buy/media-buys) | | Media buy status | `pending_creatives` added (no creatives assigned yet) | New requirement | [Media buys](/docs/media-buy/media-buys) | -| Task status | Legacy `task_status` and `response_status` fields MUST NOT be emitted alongside v3 `status` — remove both | Remove | [Task lifecycle](/docs/building/implementation/task-lifecycle) | +| Task status | Legacy `task_status` and `response_status` fields MUST NOT be emitted alongside v3 `status` — remove both | Remove | [Task lifecycle](/docs/building/by-layer/L3/task-lifecycle) | | Capabilities | `compliance_testing` capability block on `get_adcp_capabilities` | Additive | [Capability discovery](/docs/protocol/get_adcp_capabilities#compliance_testing) | -| Idempotency | `idempotency_key` required on all mutating requests (UUID v4) | New requirement | [Security § Idempotency](/docs/building/implementation/security) | -| Request signing | RFC 9421 Ed25519 signing profile (optional in 3.0, mandatory under AdCP Verified) | Additive | [Security § Request signing](/docs/building/implementation/security) | -| Webhook signing | Unified on RFC 9421 profile, baseline-required for sellers; HMAC fallback deprecated (removed in 4.0) | New requirement | [Webhooks](/docs/building/implementation/webhooks) | -| Webhook idempotency | `idempotency_key` required on every webhook payload | New requirement | [Webhooks § Reliability](/docs/building/implementation/webhooks) | +| Idempotency | `idempotency_key` required on all mutating requests (UUID v4) | New requirement | [Security § Idempotency](/docs/building/by-layer/L1/security) | +| Request signing | RFC 9421 Ed25519 signing profile (optional in 3.0, mandatory under AdCP Verified) | Additive | [Security § Request signing](/docs/building/by-layer/L1/security) | +| Webhook signing | Unified on RFC 9421 profile, baseline-required for sellers; HMAC fallback deprecated (removed in 4.0) | New requirement | [Webhooks](/docs/building/by-layer/L3/webhooks) | +| Webhook idempotency | `idempotency_key` required on every webhook payload | New requirement | [Webhooks § Reliability](/docs/building/by-layer/L3/webhooks) | | Governance | `governance_context` is a signed JWS verified via governance agent JWKS | Restructure | [Governance](/docs/governance/campaign) | | IO approval | `MediaBuy.pending_approval` removed — approval is a task-layer object | Restructure | [Media buy lifecycle](/docs/media-buy/media-buys) | | Regulatory invariants | GDPR Art 22 / EU AI Act Annex III enforced via schema `if/then` | New requirement | [Governance § Annex III obligations](/docs/governance/annex-iii-obligations) | diff --git a/docs/reference/migration/media-buy-status.mdx b/docs/reference/migration/media-buy-status.mdx index a709c6ea31..3e91009397 100644 --- a/docs/reference/migration/media-buy-status.mdx +++ b/docs/reference/migration/media-buy-status.mdx @@ -89,4 +89,4 @@ const buyLifecycleStatus = mediaBuy.media_buy_status ?? mediaBuy.status; - [create_media_buy reference](/docs/media-buy/task-reference/create_media_buy) — canonical response examples - [Media buy lifecycle](/docs/media-buy/media-buys/lifecycle) — the MediaBuyStatus state machine -- [Envelope task-status](/docs/building/implementation/task-lifecycle) — TaskStatus semantics +- [Envelope task-status](/docs/building/by-layer/L3/task-lifecycle) — TaskStatus semantics diff --git a/docs/reference/migration/prerelease-upgrades.mdx b/docs/reference/migration/prerelease-upgrades.mdx index 251b00692d..aa2c6e06c7 100644 --- a/docs/reference/migration/prerelease-upgrades.mdx +++ b/docs/reference/migration/prerelease-upgrades.mdx @@ -35,7 +35,7 @@ If you adopted a prerelease version, review the relevant section below before up | Geo capability fields | `supported_geo_levels`, `supported_metro_systems`, `supported_postal_systems` (from #2143) | Removed — use typed objects (`geo_countries`, `geo_regions`, `geo_metros`, `geo_postal_areas`) | If you adopted the flat array shape from #2143, revert to typed geo objects with `additionalProperties: false`. Schema: `protocol/get-adcp-capabilities-response.json`. | | `comply_test_controller` schema | oneOf union | Flat object with `scenario` discriminant and if/then validation | Update request builders to use the flat schema with `scenario` field instead of oneOf variants. | | Compliance testing surface | An interim rc.4 build accepted `"compliance_testing"` as a `supported_protocols` value | Removed before GA. Compliance testing is declared via a top-level `compliance_testing: { scenarios: [...] }` capability block, not via `supported_protocols`. | Remove `"compliance_testing"` from `supported_protocols` if present. Agents implementing `comply_test_controller` add a top-level `compliance_testing: { scenarios: [...] }` block instead. | -| Specialism IDs | `broadcast-platform`, `social-platform`, `property-governance`, `collection-governance` | Renamed/merged: `sales-broadcast-tv`, `sales-social`, `inventory-lists` (merges property + collection governance) | Update specialism claims in `get_adcp_capabilities.specialisms`. See [Compliance Catalog](/docs/building/compliance-catalog). | +| Specialism IDs | `broadcast-platform`, `social-platform`, `property-governance`, `collection-governance` | Renamed/merged: `sales-broadcast-tv`, `sales-social`, `inventory-lists` (merges property + collection governance) | Update specialism claims in `get_adcp_capabilities.specialisms`. See [Compliance Catalog](/docs/building/verification/compliance-catalog). | | `audience-sync` parent protocol | Under `governance` | Moved to `media-buy` | If claiming `audience-sync`, add `media_buy` to `supported_protocols`. | | Sponsored Intelligence scope | `sponsored_intelligence` as a specialism | Promoted to full protocol in `supported_protocols` | Move from `specialisms` to `supported_protocols`. | @@ -182,7 +182,7 @@ All request and response schemas across governance, collection, property, sponso - **GOVERNANCE_DENIED error** — New correctable error code for governance-rejected operations. - **context/ext fields** — Optional `context` and `ext` on all request/response schemas across governance, collection, property, SI, and content-standards protocols. - **Compliance testing capability** — Agents include a `compliance_testing: { scenarios: [...] }` block in `get_adcp_capabilities` declaring which `comply_test_controller` scenarios they support. The block's presence is the signal — compliance testing is NOT a `supported_protocols` value. Storyboard runners use the block to determine whether deterministic testing steps can be validated. -- **Specialisms + compliance catalog** — Storyboards ship in the protocol at `/compliance/{version}/` (universal + protocols + specialisms + test-kits). New `specialisms` field on `get_adcp_capabilities` with 19 values across 6 protocols. Per-version protocol tarball at `/protocol/{version}.tgz`. See the [Compliance Catalog](/docs/building/compliance-catalog). +- **Specialisms + compliance catalog** — Storyboards ship in the protocol at `/compliance/{version}/` (universal + protocols + specialisms + test-kits). New `specialisms` field on `get_adcp_capabilities` with 19 values across 6 protocols. Per-version protocol tarball at `/protocol/{version}.tgz`. See the [Compliance Catalog](/docs/building/verification/compliance-catalog). - **Structured measurement terms** — `measurement_terms` on products and media buys for billing vendor, IVT threshold, and viewability floor negotiation. `cancellation_policy` on guaranteed products. `viewability-standard` enum. `TERMS_REJECTED` error code. - **Unified vendor pricing** — `pricing_options[]` on `list_creatives`, `build_creative`, `get_creative_features`, and `property-list`. Shared `vendor-pricing-option.json` schema. - **Per-request version declaration** — `adcp_major_version` on all v3 request schemas. `VERSION_UNSUPPORTED` error code. Multi-version sellers supporting v2 clients must detect v2 payloads by structural cues, not by this field (v2 schemas do not have it). diff --git a/docs/reference/migration/v3-readiness.mdx b/docs/reference/migration/v3-readiness.mdx index 3194da9d8d..4a7f23564c 100644 --- a/docs/reference/migration/v3-readiness.mdx +++ b/docs/reference/migration/v3-readiness.mdx @@ -119,7 +119,7 @@ Buyers pass brand identity as a reference (`{ domain, brand_id }`) instead of an v3 removes `buyer_ref`, `buyer_campaign_ref`, and `campaign_ref` from all requests and responses. Seller-assigned `media_buy_id` and `package_id` are now the only canonical identifiers. -If your agent relied on `buyer_ref` for deduplication, use the new `idempotency_key` field instead. `idempotency_key` (UUID v4) is **required** on every mutating request — agents MUST reject requests that omit it with `INVALID_REQUEST`, and MUST return `IDEMPOTENCY_CONFLICT` when a key is reused with a different payload. See the [idempotency implementation guide](/docs/building/implementation/security#idempotency) for normative semantics. +If your agent relied on `buyer_ref` for deduplication, use the new `idempotency_key` field instead. `idempotency_key` (UUID v4) is **required** on every mutating request — agents MUST reject requests that omit it with `INVALID_REQUEST`, and MUST return `IDEMPOTENCY_CONFLICT` when a key is reused with a different payload. See the [idempotency implementation guide](/docs/building/by-layer/L1/security#idempotency) for normative semantics. If your agent used `buyer_ref` for internal tracking or correlation (e.g. mapping to campaign IDs, session traces, or UI state), use the `context` field instead. `context` is an opaque object echoed unchanged in every response and webhook — agents must never parse or act on it. For `create_media_buy` package correlation, put per-package tracking in `packages[i].context` (for example `context.buyer_ref`), not deprecated top-level `buyer_ref`; 3.1+ sellers MUST echo `product_id` on explicit package responses, and package context remains the fallback for legacy sellers that do not. diff --git a/docs/reference/privacy-considerations.mdx b/docs/reference/privacy-considerations.mdx index 5fb45b71de..a699ea94cf 100644 --- a/docs/reference/privacy-considerations.mdx +++ b/docs/reference/privacy-considerations.mdx @@ -61,15 +61,15 @@ Where two facts combined would create a privacy harm (e.g., identity + context a ### Transport -All AdCP traffic is over HTTPS (see [Security — Identity](/docs/building/understanding/security-model#layer-1-identity--who-is-actually-calling)). Signed requests (RFC 9421) are normative in 3.1. Transport security is a baseline assumption; the protocol builds on top of it. +All AdCP traffic is over HTTPS (see [Security — Identity](/docs/building/concepts/security-model#layer-1-identity--who-is-actually-calling)). Signed requests (RFC 9421) are normative in 3.1. Transport security is a baseline assumption; the protocol builds on top of it. ### Residency -Residency is not carried in the protocol. An agent's residency posture is a configuration and a contract property — implementers MUST document it, and operators MUST configure it to meet EU / UK / other regional requirements where applicable. See the [Security Model — data handling and subprocessors checklist](/docs/building/understanding/security-model#data-handling-and-subprocessors). +Residency is not carried in the protocol. An agent's residency posture is a configuration and a contract property — implementers MUST document it, and operators MUST configure it to meet EU / UK / other regional requirements where applicable. See the [Security Model — data handling and subprocessors checklist](/docs/building/concepts/security-model#data-handling-and-subprocessors). ### Retention -The protocol describes cache retention for idempotency (see [Layer 3: Idempotency](/docs/building/understanding/security-model#layer-3-idempotency--at-most-once-execution)) and audit-log retention for governance (see [Layer 5: Auditability](/docs/building/understanding/security-model#layer-5-auditability--the-trail-survives-the-transaction)). Retention of other data — creative assets, campaign state, LLM prompts, conversation logs — is the operator's responsibility. +The protocol describes cache retention for idempotency (see [Layer 3: Idempotency](/docs/building/concepts/security-model#layer-3-idempotency--at-most-once-execution)) and audit-log retention for governance (see [Layer 5: Auditability](/docs/building/concepts/security-model#layer-5-auditability--the-trail-survives-the-transaction)). Retention of other data — creative assets, campaign state, LLM prompts, conversation logs — is the operator's responsibility. ### Processor / controller roles @@ -86,9 +86,9 @@ Operators MUST document their role for each data flow and carry a DPA with each ### Subprocessors and LLM providers -Every LLM-powered agent has subprocessors: the LLM provider itself, plus any retrieval services, embeddings stores, or tool integrations. The DPA with each provider must be explicit about whether prompts, brand assets, first-party signals, or creative metadata may be retained or used for model training. See the [Security Model — data handling checklist](/docs/building/understanding/security-model#data-handling-and-subprocessors). +Every LLM-powered agent has subprocessors: the LLM provider itself, plus any retrieval services, embeddings stores, or tool integrations. The DPA with each provider must be explicit about whether prompts, brand assets, first-party signals, or creative metadata may be retained or used for model training. See the [Security Model — data handling checklist](/docs/building/concepts/security-model#data-handling-and-subprocessors). -LLM subprocessors also introduce an **integrity** risk, not only a confidentiality one: untrusted text in briefs, creative metadata, or tool outputs can carry prompt-injection payloads that cause the agent to leak credentials, issue unauthorized tool calls, or tamper with outputs. See [Threats specific to agentic advertising](/docs/building/understanding/security-model#threats-specific-to-agentic-advertising). This is out of scope for the protocol but in scope for every operator. +LLM subprocessors also introduce an **integrity** risk, not only a confidentiality one: untrusted text in briefs, creative metadata, or tool outputs can carry prompt-injection payloads that cause the agent to leak credentials, issue unauthorized tool calls, or tamper with outputs. See [Threats specific to agentic advertising](/docs/building/concepts/security-model#threats-specific-to-agentic-advertising). This is out of scope for the protocol but in scope for every operator. ## Boundaries implementers must handle @@ -110,7 +110,7 @@ What AdCP provides instead is the set of protocol-level inputs a DPO needs to de - **What each protocol carries and prohibits** — the [Privacy posture by domain](#privacy-posture-by-domain) summary above, plus the deep references linked from each domain. - **Controller / processor allocation** — the [Processor / controller roles](#processor--controller-roles) section above. Operators still MUST document their role per data flow and carry a DPA with each counterparty. - **Structural separation (TMP only)** — [TMP Privacy Architecture](/docs/trusted-match/privacy-architecture), including TEE attestation when deployed. -- **Threat model and operational controls** — the [Security Model](/docs/building/understanding/security-model), including the [data handling and subprocessors checklist](/docs/building/understanding/security-model#data-handling-and-subprocessors). +- **Threat model and operational controls** — the [Security Model](/docs/building/concepts/security-model), including the [data handling and subprocessors checklist](/docs/building/concepts/security-model#data-handling-and-subprocessors). - **LLM-provider subprocessor considerations** — the [Subprocessors and LLM providers](#subprocessors-and-llm-providers) section above, which covers both confidentiality (retention, training) and integrity (prompt injection). - **Explicit non-goals** — [Known Limitations](/docs/reference/known-limitations), which names what the protocol does not do (no protocol-level PII transport, no residency mechanism, no breach-notification SLA, etc.) so the deployer knows which controls they own. @@ -119,7 +119,7 @@ Residency, retention, consent capture, data-subject rights workflows, cross-bord ## Related references - **[TMP Privacy Architecture](/docs/trusted-match/privacy-architecture)** — the structural separation model, with TEE attestation details -- **[Security Model](/docs/building/understanding/security-model)** — threat model, layered defense, deployment checklist -- **[Security (implementation reference)](/docs/building/implementation/security)** — normative rules for auth, idempotency, SSRF, governance verification +- **[Security Model](/docs/building/concepts/security-model)** — threat model, layered defense, deployment checklist +- **[Security (implementation reference)](/docs/building/by-layer/L1/security)** — normative rules for auth, idempotency, SSRF, governance verification - **[Privacy posture across domains](/docs/protocol/architecture#privacy-posture-across-domains)** — the summary table - **[Known Limitations](/docs/reference/known-limitations)** — what the protocol does not do on privacy diff --git a/docs/reference/release-notes.mdx b/docs/reference/release-notes.mdx index a21f826c86..d796f35d7b 100644 --- a/docs/reference/release-notes.mdx +++ b/docs/reference/release-notes.mdx @@ -391,7 +391,7 @@ For the full per-PR change list, see [CHANGELOG.md § 3.0.5](https://github.com/ | A 3.0-conformant production agent | Nothing. Stable schemas remain wire-compatible with 3.0.0. | | An SDK author | Switch from parsing `Recovery: X` prose out of `enumDescriptions` to consuming the structured `enumMetadata` block. The build-time lint guarantees structured/prose parity, so the prose path can stay as a fallback while you migrate. | | An SDK consumer | Bump `ADCP_VERSION` to `3.0.4`. Pick up `/schemas/3.0.4/manifest.json` for one-stop tool/error/specialism enumeration. | -| Implementing a buyer agent | Read the new `AUTH_REQUIRED` sub-cases in [error-handling.mdx](/docs/building/implementation/error-handling) — the wire code stays the same but you SHOULD NOT auto-retry when credentials were attached and rejected (terminal case). 3.1 will split this into separate enum values via #3739. | +| Implementing a buyer agent | Read the new `AUTH_REQUIRED` sub-cases in [error-handling.mdx](/docs/building/by-layer/L3/error-handling) — the wire code stays the same but you SHOULD NOT auto-retry when credentials were attached and rejected (terminal case). 3.1 will split this into separate enum values via #3739. | | Returning multi-field validation errors | Optionally populate `core/error.json`'s new top-level `issues[]` array (each entry: RFC 6901 pointer, message, JSON Schema keyword). Pre-3.1 consumers reading only `field` get the first failure; 3.1+ consumers prefer `issues`. | ### `manifest.json` + structured `enumMetadata` (#3725, #3738) @@ -612,7 +612,7 @@ For the full per-PR change list, see [CHANGELOG.md § 3.0.1](https://github.com/ See [Security implementation guide](/docs/building/by-layer/L1/security) for the threat model, `adcp_use` JWK taxonomy, and per-primitive verification paths. -2. **Specialisms, compliance storyboards, and AdCP Verified** — Trust primitives define the bar; storyboards test that an agent actually meets it; AdCP Verified certifies the result. Storyboards move into the protocol at `/compliance/{version}/` (universal + protocols + specialisms + test-kits). Every agent runs `/compliance/{version}/universal/security.yaml` regardless of claims — unauth rejection, API key enforcement, OAuth discovery per RFC 9728, audience binding, and (when signing is claimed) the `signed_requests` and `signed_webhooks` runner harnesses. Runner output is a structured, verifiable `runner-output.json` with a hash chain over the test-kit corpus. Cross-instance state persistence is required. New `specialisms` field on `get_adcp_capabilities` lets agents claim narrow capability specialisms across 6 protocols (media-buy, creative, signals, governance, brand, sponsored_intelligence). `sponsored_intelligence` is promoted from specialism to full protocol. `broadcast-platform` → `sales-broadcast-tv`, `social-platform` → `sales-social`. `property-governance` + `collection-governance` split into sibling `property-lists` and `collection-lists` specialisms. Compliance taxonomy renames `domains` → `protocols`; `audience-sync` reclassified from `governance` to `media-buy`. Per-version protocol tarball at `/protocol/{version}.tgz`. The formal AdCP Verified program launches with **3.1** once reference implementations (training agent, SDKs) and ambiguous-storyboard work reach full compliance on a 4–6 week cadence; 3.0 Verified is self-attested via published runner output. See the [Compliance Catalog](/docs/building/compliance-catalog) and [What's new in v3](/docs/reference/whats-new-in-v3#specialisms-and-storyboard-driven-compliance) for the rationale and timeline. (#2176, #2300, #2304, #2332, #2336, #2350, #2352, #2363, #2381) +2. **Specialisms, compliance storyboards, and AdCP Verified** — Trust primitives define the bar; storyboards test that an agent actually meets it; AdCP Verified certifies the result. Storyboards move into the protocol at `/compliance/{version}/` (universal + protocols + specialisms + test-kits). Every agent runs `/compliance/{version}/universal/security.yaml` regardless of claims — unauth rejection, API key enforcement, OAuth discovery per RFC 9728, audience binding, and (when signing is claimed) the `signed_requests` and `signed_webhooks` runner harnesses. Runner output is a structured, verifiable `runner-output.json` with a hash chain over the test-kit corpus. Cross-instance state persistence is required. New `specialisms` field on `get_adcp_capabilities` lets agents claim narrow capability specialisms across 6 protocols (media-buy, creative, signals, governance, brand, sponsored_intelligence). `sponsored_intelligence` is promoted from specialism to full protocol. `broadcast-platform` → `sales-broadcast-tv`, `social-platform` → `sales-social`. `property-governance` + `collection-governance` split into sibling `property-lists` and `collection-lists` specialisms. Compliance taxonomy renames `domains` → `protocols`; `audience-sync` reclassified from `governance` to `media-buy`. Per-version protocol tarball at `/protocol/{version}.tgz`. The formal AdCP Verified program launches with **3.1** once reference implementations (training agent, SDKs) and ambiguous-storyboard work reach full compliance on a 4–6 week cadence; 3.0 Verified is self-attested via published runner output. See the [Compliance Catalog](/docs/building/verification/compliance-catalog) and [What's new in v3](/docs/reference/whats-new-in-v3#specialisms-and-storyboard-driven-compliance) for the rationale and timeline. (#2176, #2300, #2304, #2332, #2336, #2350, #2352, #2363, #2381) 3. **Broadcast TV Support** — Linear TV sellers can now fully participate in AdCP. Ad-ID identifiers on creative assets and manifests. Broadcast spot formats for :15, :30, and :60 spots. `agency_estimate_number` on media buys and packages. Measurement windows (Live, C3, C7) on reporting capabilities. Delivery data completeness flags (`is_final`, `measurement_window`) for provisional vs. closed numbers. Broadcast forecast schema adds `measurement_source` and `guaranteed_impressions`. `station_id` and `facility_id` identifier types. (#2046, #1853, #1912) diff --git a/docs/reference/schema-extensions.mdx b/docs/reference/schema-extensions.mdx index e7153e3acb..ff68206725 100644 --- a/docs/reference/schema-extensions.mdx +++ b/docs/reference/schema-extensions.mdx @@ -7,7 +7,7 @@ description: "Reference for AdCP-specific `x-` prefixed schema annotations." AdCP schemas carry several `x-` prefixed annotation keywords that supplement the JSON Schema vocabulary. JSON Schema validators ignore unknown `x-` keywords per [draft-07 §6](https://json-schema.org/draft-07/schema), so adding these keys is wire-compatible with any conforming validator. -This page is the canonical reference for those annotations. Codegen consumers (TypeScript / Python / Go type generators), the storyboard runner, and the AdCP SDK family read these annotations programmatically; verifiers MAY read them but the normative behavior they describe is also documented in the relevant section of [security.mdx](/docs/building/implementation/security) or the field's own description. +This page is the canonical reference for those annotations. Codegen consumers (TypeScript / Python / Go type generators), the storyboard runner, and the AdCP SDK family read these annotations programmatically; verifiers MAY read them but the normative behavior they describe is also documented in the relevant section of [security.mdx](/docs/building/by-layer/L1/security) or the field's own description. ## `x-status` @@ -73,8 +73,8 @@ Representative usage: | Field | Sub-keys used | Rule | |---|---|---| -| `identity.brand_json_url` | `trust_root`, `required_when`, `schema_required_when`, `verifier_constraints`, `distinct_from` | Trust-root pointer for signing-key discovery; required-when tied to signing posture; schema-required in 4.0; distinct from `sponsored_intelligence.brand_url`. See [security.mdx §Discovering an agent's signing keys](/docs/building/implementation/security#discovering-an-agents-signing-keys-via-brand_json_url). | -| `identity.key_origins` | `verifier_constraints` (`purpose_anchoring`) | Every purpose listed MUST have a corresponding signing posture declared elsewhere on the response. Cross-field rule. See [security.mdx §Origin separation](/docs/building/implementation/security#origin-separation). | +| `identity.brand_json_url` | `trust_root`, `required_when`, `schema_required_when`, `verifier_constraints`, `distinct_from` | Trust-root pointer for signing-key discovery; required-when tied to signing posture; schema-required in 4.0; distinct from `sponsored_intelligence.brand_url`. See [security.mdx §Discovering an agent's signing keys](/docs/building/by-layer/L1/security#discovering-an-agents-signing-keys-via-brand_json_url). | +| `identity.key_origins` | `verifier_constraints` (`purpose_anchoring`) | Every purpose listed MUST have a corresponding signing posture declared elsewhere on the response. Cross-field rule. See [security.mdx §Origin separation](/docs/building/by-layer/L1/security#origin-separation). | | `request_signing.required_for` | `subset_of` | Every operation listed MUST also appear in `supported_for` — an operation can't be required without being supported. | | `request_signing.warn_for` | `disjoint_with`, `subset_of` | An operation MUST NOT appear in both `warn_for` and `required_for`. Every operation listed MUST also appear in `supported_for`. | | `webhook_signing.supported` | `verifier_constraints` (`must_equal_when`) | When the seller advertises mutating-webhook emission (`media_buy.reporting_delivery_methods` includes `webhook` OR `media_buy.content_standards.supports_webhook_delivery: true`), `supported` MUST be `true`. Closes a downgrade vector. | diff --git a/docs/reference/test-vectors/index.mdx b/docs/reference/test-vectors/index.mdx index b0f69af068..d741f50182 100644 --- a/docs/reference/test-vectors/index.mdx +++ b/docs/reference/test-vectors/index.mdx @@ -10,11 +10,11 @@ description: "Machine-readable fixtures SDKs and implementations diff against to ## What these are -Reference test vectors are machine-readable JSON fixtures pinned to specific wire-format rules in the spec. An SDK whose output matches a vector's `expected_*` field byte-for-byte has agreed with the reference on that rule's wire format — not a conformance claim (only [storyboards](/docs/building/conformance) decide that), but a necessary precondition for interop. An SDK that diverges has an interop bug, even if its own tests pass. +Reference test vectors are machine-readable JSON fixtures pinned to specific wire-format rules in the spec. An SDK whose output matches a vector's `expected_*` field byte-for-byte has agreed with the reference on that rule's wire format — not a conformance claim (only [storyboards](/docs/building/verification/conformance) decide that), but a necessary precondition for interop. An SDK that diverges has an interop bug, even if its own tests pass. -Vectors complement [storyboards](/docs/building/conformance). Storyboards exercise an agent end-to-end to produce a pass/fail verdict; vectors exercise a library in isolation against frozen inputs. A vector tells a signer "this 9421 request MUST produce this signature base"; a storyboard tells an agent "when the buyer sends this request, you MUST respond with a result shaped like this." Most conformant stacks need both — vectors catch canonicalization drift inside a library; storyboards catch behavior drift at the wire. +Vectors complement [storyboards](/docs/building/verification/conformance). Storyboards exercise an agent end-to-end to produce a pass/fail verdict; vectors exercise a library in isolation against frozen inputs. A vector tells a signer "this 9421 request MUST produce this signature base"; a storyboard tells an agent "when the buyer sends this request, you MUST respond with a result shaped like this." Most conformant stacks need both — vectors catch canonicalization drift inside a library; storyboards catch behavior drift at the wire. -Vectors are not the conformance specification — the [storyboards](/docs/building/conformance) are. Vectors are reference inputs the storyboards and SDK unit tests consume. +Vectors are not the conformance specification — the [storyboards](/docs/building/verification/conformance) are. Vectors are reference inputs the storyboards and SDK unit tests consume. ## Versioning @@ -37,7 +37,7 @@ SDKs SHOULD fetch versioned paths where available and record the version under t | [`mcp-response-extraction`](https://github.com/adcontextprotocol/adcp/blob/main/static/test-vectors/mcp-response-extraction.json) | Client extraction of the AdCP payload from MCP `tools/call` envelopes | `static/test-vectors/mcp-response-extraction.json` | [`/test-vectors/mcp-response-extraction.json`](https://adcontextprotocol.org/test-vectors/mcp-response-extraction.json) | | [`a2a-response-extraction`](https://github.com/adcontextprotocol/adcp/blob/main/static/test-vectors/a2a-response-extraction.json) | Client extraction of the AdCP payload from A2A task statuses and artifacts | `static/test-vectors/a2a-response-extraction.json` | [`/test-vectors/a2a-response-extraction.json`](https://adcontextprotocol.org/test-vectors/a2a-response-extraction.json) | | [`webhook-payload-extraction`](https://github.com/adcontextprotocol/adcp/blob/main/static/test-vectors/webhook-payload-extraction.json) | Receiver-side format detection and payload extraction for inbound AdCP webhooks | `static/test-vectors/webhook-payload-extraction.json` | [`/test-vectors/webhook-payload-extraction.json`](https://adcontextprotocol.org/test-vectors/webhook-payload-extraction.json) | -| [`webhook-hmac-sha256`](https://github.com/adcontextprotocol/adcp/blob/main/static/test-vectors/webhook-hmac-sha256.json) *(legacy)* | HMAC-SHA-256 signature computation and byte-equality invariants for the legacy HMAC webhook profile. Deprecated in 3.x, removed in 4.0 per [Webhook callbacks](/docs/building/implementation/webhooks#legacy-hmac-sha256-fallback-deprecated); new integrations use `webhook-signing` | `static/test-vectors/webhook-hmac-sha256.json` | [`/test-vectors/webhook-hmac-sha256.json`](https://adcontextprotocol.org/test-vectors/webhook-hmac-sha256.json) | +| [`webhook-hmac-sha256`](https://github.com/adcontextprotocol/adcp/blob/main/static/test-vectors/webhook-hmac-sha256.json) *(legacy)* | HMAC-SHA-256 signature computation and byte-equality invariants for the legacy HMAC webhook profile. Deprecated in 3.x, removed in 4.0 per [Webhook callbacks](/docs/building/by-layer/L3/webhooks#legacy-hmac-sha256-fallback-deprecated); new integrations use `webhook-signing` | `static/test-vectors/webhook-hmac-sha256.json` | [`/test-vectors/webhook-hmac-sha256.json`](https://adcontextprotocol.org/test-vectors/webhook-hmac-sha256.json) | **Start here**: every set's `README.md` in the source column documents file layout, key material, preconditions (e.g., runner state required for replay vectors), and how to wire the set into an SDK test loop. The README in the source tree is authoritative; the index on this page is a catalog, not an integration guide. diff --git a/docs/reference/url-canonicalization.mdx b/docs/reference/url-canonicalization.mdx index e1d7d83d22..90c7738f3b 100644 --- a/docs/reference/url-canonicalization.mdx +++ b/docs/reference/url-canonicalization.mdx @@ -4,7 +4,7 @@ description: "The canonicalization rules AdCP uses everywhere two URLs are compa "og:title": "AdCP — URL Canonicalization" --- -AdCP compares URLs as identifiers in several places: the request-signing profile's `@target-uri`, `authorized_agents[].url` entries in `adagents.json`, `seller_agent.agent_url` on TMP `AvailablePackage`, `agent_url` in `format-id` and `ProviderEntry`, and any other registry where a URL is a primary key. A single canonicalization algorithm governs all of these so two byte-different-but-semantically-equal URLs compare equal regardless of which surface is doing the lookup. This page is the authoritative home of that algorithm; the [request-signing profile](/docs/building/implementation/security#signed-requests-transport-layer) cites it and adds transport-specific extensions. +AdCP compares URLs as identifiers in several places: the request-signing profile's `@target-uri`, `authorized_agents[].url` entries in `adagents.json`, `seller_agent.agent_url` on TMP `AvailablePackage`, `agent_url` in `format-id` and `ProviderEntry`, and any other registry where a URL is a primary key. A single canonicalization algorithm governs all of these so two byte-different-but-semantically-equal URLs compare equal regardless of which surface is doing the lookup. This page is the authoritative home of that algorithm; the [request-signing profile](/docs/building/by-layer/L1/security#signed-requests-transport-layer) cites it and adds transport-specific extensions. ## Algorithm @@ -36,7 +36,7 @@ After all eight steps, comparison is byte-for-byte. Implementations MUST NOT app | Surface | Comparison | Reference | |---|---|---| -| Request signing | `@target-uri` canonical output signed and verified | [Signed Requests (Transport Layer)](/docs/building/implementation/security#signed-requests-transport-layer) | +| Request signing | `@target-uri` canonical output signed and verified | [Signed Requests (Transport Layer)](/docs/building/by-layer/L1/security#signed-requests-transport-layer) | | TMP seller authorization | `seller_agent.agent_url` vs `authorized_agents[].url` | [TMP Sync-Time Validation](/docs/trusted-match/specification#sync-time-validation) | | TMP provider resolution | `ProviderEntry.agent_url` vs router's registered provider endpoint | [TMP Product Integration](/docs/trusted-match/specification#product-integration) | | `adagents.json` lookups | Any caller asking "is this agent authorized for this property?" | [adagents.json schema](https://adcontextprotocol.org/schemas/v3/adagents.json) | @@ -47,7 +47,7 @@ After all eight steps, comparison is byte-for-byte. Implementations MUST NOT app ## Signing profile extensions -The [request-signing profile](/docs/building/implementation/security#signed-requests-transport-layer) layers transport-specific rules on top of this algorithm: +The [request-signing profile](/docs/building/by-layer/L1/security#signed-requests-transport-layer) layers transport-specific rules on top of this algorithm: - `@authority` is derived from the canonicalized authority and compared against the HTTP/2 `:authority` pseudo-header (or the as-received HTTP/1.1 `Host` header) after the same canonicalization. Non-signing callers derive `@authority` from the URL alone. - Malformed authorities are rejected with `request_target_uri_malformed` on the signing path; non-signing callers use their own authorization-failure code (e.g., `seller_not_authorized` for TMP). diff --git a/docs/reference/versioning.mdx b/docs/reference/versioning.mdx index a5945d36b4..45d2854634 100644 --- a/docs/reference/versioning.mdx +++ b/docs/reference/versioning.mdx @@ -257,7 +257,7 @@ AdCP distinguishes three levels of schema extension. The rules below apply to ev | Surface | Who may extend | How | |---|---|---| | **Core fields** defined by the protocol | Working group, via a release | Proposed in a working group, accepted through the normal release process. Never extended inline by an implementer. | -| **`ext.{namespace}`** on any request or response object | Anyone, by declaring a namespace in `extensions_supported` | Namespaced, out-of-band, does not affect baseline interop. Namespaces SHOULD be registered in the [extension registry](/docs/building/integration/context-sessions#extensions). | +| **`ext.{namespace}`** on any request or response object | Anyone, by declaring a namespace in `extensions_supported` | Namespaced, out-of-band, does not affect baseline interop. Namespaces SHOULD be registered in the [extension registry](/docs/building/by-layer/L2/context-sessions#extensions). | | **`additionalProperties: true`** on containers that allow it | Anyone | Additive fields at the declared location. MUST NOT shadow or redefine a core field. Readers MUST ignore unknown fields rather than erroring. When an additional field collides in name with a core field defined on a later release, readers MUST prefer the core field. | **What MUST NOT happen:** diff --git a/docs/reference/whats-new-in-v3.mdx b/docs/reference/whats-new-in-v3.mdx index 0ca4653b68..3336155cd1 100644 --- a/docs/reference/whats-new-in-v3.mdx +++ b/docs/reference/whats-new-in-v3.mdx @@ -94,7 +94,7 @@ The compliance runner and the storyboards are themselves software shipping at 3. **Why self-attested and not audited at 3.0:** the reference implementations AAO operates — the training agent and the `@adcp/sdk` / Python / Go SDKs — aren't fully clean against the 3.0 storyboard suite yet. The training agent currently passes 32 of 55 applicable storyboards; SDK coverage is similar. We are working those pass rates to 100% over the 3.0 → 3.1 window on a 4–6 week cadence. When the reference implementations pass cleanly and the remaining spec ambiguities are resolved, **the formal AdCP Verified program launches with 3.1** — agents will be able to submit runner output for independent re-execution by AAO, with a public registry of verified agents. Self-attestation in 3.0 is the bridge, not the end state. - + Full index of domains and specialisms with status flags and storyboard sources. @@ -199,7 +199,7 @@ Publishers can return **proposals** alongside products — structured media plan ### Accounts -**Migrating from v2?** Accounts are entirely new in v3 — there is no v2 equivalent to migrate from. Start with [Accounts and Agents](/docs/building/integration/accounts-and-agents) for the setup guide. +**Migrating from v2?** Accounts are entirely new in v3 — there is no v2 equivalent to migrate from. Start with [Accounts and Agents](/docs/building/by-layer/L2/accounts-and-agents) for the setup guide. Formal billing relationships between buyers and sellers via `sync_accounts`. @@ -209,7 +209,7 @@ Formal billing relationships between buyers and sellers via `sync_accounts`. | Entity | Question | How identified | |--------|----------|----------------| | **Brand** | Whose products are advertised? | House domain + brand_id via `brand.json` | -| **Account** | Who gets billed? | [Account reference](/docs/building/integration/accounts-and-agents#account-references) — `account_id` from `list_accounts` or natural key | +| **Account** | Who gets billed? | [Account reference](/docs/building/by-layer/L2/accounts-and-agents#account-references) — `account_id` from `list_accounts` or natural key | | **Operator** | Who operates on the brand's behalf? | Domain (e.g., `acmeagency.example.com`) | | **Agent** | What software places buys? | Authenticated session | @@ -323,7 +323,7 @@ For the exhaustive rc.2 change list, see the [Release Notes](/docs/reference/rel ### Specialisms and compliance catalog -Storyboards move into the protocol at `/compliance/{version}/` with a new `specialisms` field on `get_adcp_capabilities`. 21 specialisms roll up to 6 domains; four 3.1 archetypes ship with `status: preview`. See the [Compliance Catalog](/docs/building/compliance-catalog). Renames: `broadcast-platform` → `sales-broadcast-tv`, `social-platform` → `sales-social`. Merge: `property-governance` + `collection-governance` → `inventory-lists`. Promotion: `sponsored_intelligence` specialism → full protocol. +Storyboards move into the protocol at `/compliance/{version}/` with a new `specialisms` field on `get_adcp_capabilities`. 21 specialisms roll up to 6 domains; four 3.1 archetypes ship with `status: preview`. See the [Compliance Catalog](/docs/building/verification/compliance-catalog). Renames: `broadcast-platform` → `sales-broadcast-tv`, `social-platform` → `sales-social`. Merge: `property-governance` + `collection-governance` → `inventory-lists`. Promotion: `sponsored_intelligence` specialism → full protocol. ### Capabilities model simplification diff --git a/docs/signals/ecosystem.mdx b/docs/signals/ecosystem.mdx index fb9211c433..973dd75fc1 100644 --- a/docs/signals/ecosystem.mdx +++ b/docs/signals/ecosystem.mdx @@ -283,7 +283,7 @@ Your first-party purchase data (category buyers, loyalty tiers, basket value, ne - [Commerce media guide](/docs/media-buy/commerce-media) — maps retail concepts to AdCP - [Data provider guide](/docs/signals/data-providers) — how to publish your signal definitions - [Conversion tracking](/docs/media-buy/conversion-tracking/index) — closed-loop measurement with `sync_event_sources` and `log_event` -- [Seller integration guide](/docs/building/implementation/seller-integration) — building your sales agent +- [Seller integration guide](/docs/building/operating/seller-integration) — building your sales agent --- @@ -507,7 +507,7 @@ To participate as a destination platform, you'd implement the receiving side: ac **Next steps**: - [Platform/intermediary track](/docs/learning/tracks/platform) — MCP server architecture - [Signals specification](/docs/signals/specification) — destination and deployment model -- [Industry landscape](/docs/building/understanding/industry-landscape) — how AdCP fits alongside other standards +- [Industry landscape](/docs/building/concepts/industry-landscape) — how AdCP fits alongside other standards - [Working group](/docs/community/working-group) — help shape clean room integration patterns --- diff --git a/docs/signals/specification.mdx b/docs/signals/specification.mdx index 68d5fdd6b3..e7f09e887f 100644 --- a/docs/signals/specification.mdx +++ b/docs/signals/specification.mdx @@ -65,7 +65,7 @@ Every signal request involves two roles: same response as "agent does not exist." Distinguishing "exists but unauthorized" from "does not exist" would enable cross-tenant enumeration of private agents. See the uniform-response MUST in - [error-handling.mdx](/docs/building/implementation/error-handling) for the full + [error-handling.mdx](/docs/building/by-layer/L3/error-handling) for the full set of observable channels that MUST match on both paths. - Signal agents MUST NOT expose private signals across accounts @@ -163,9 +163,9 @@ Activate a signal for use on a decisioning platform. `activate_signal` is requir ## Error Handling -Signal agents MUST return errors using the [standard AdCP error schema](/docs/building/implementation/error-handling). +Signal agents MUST return errors using the [standard AdCP error schema](/docs/building/by-layer/L3/error-handling). -Signal agents MUST use Signals Protocol error codes as defined in the [Error Handling Reference](/docs/building/implementation/error-handling). +Signal agents MUST use Signals Protocol error codes as defined in the [Error Handling Reference](/docs/building/by-layer/L3/error-handling). ## Security Considerations diff --git a/docs/signals/tasks/activate_signal.mdx b/docs/signals/tasks/activate_signal.mdx index befc664daa..f0d5dd85cd 100644 --- a/docs/signals/tasks/activate_signal.mdx +++ b/docs/signals/tasks/activate_signal.mdx @@ -21,11 +21,11 @@ The `activate_signal` task handles the entire activation lifecycle, including: | Parameter | Type | Required | Description | |-----------|------|----------|-------------| -| `idempotency_key` | string | Yes | Client-generated unique key for this request. Prevents duplicate activations on retries. MUST be unique per (seller, request) pair. Min 16 chars. See [Idempotency](/docs/building/implementation/security#idempotency) for normative semantics. | +| `idempotency_key` | string | Yes | Client-generated unique key for this request. Prevents duplicate activations on retries. MUST be unique per (seller, request) pair. Min 16 chars. See [Idempotency](/docs/building/by-layer/L1/security#idempotency) for normative semantics. | | `signal_agent_segment_id` | string | Yes | Opaque signal handle from `get_signals` for the signal to activate | | `action` | string | No | `"activate"` (default) or `"deactivate"`. Deactivating removes segments from downstream platforms for data governance compliance (GDPR, CCPA). | | `destinations` | Destination[] | Yes | Target destination(s) for activation (see Destination Object below) | -| `account` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references) | No | Account for this activation. Associates with a commercial relationship established via `sync_accounts`. | +| `account` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account for this activation. Associates with a commercial relationship established via `sync_accounts`. | | `pricing_option_id` | string | Yes (if signal has pricing options) | The pricing option selected from `pricing_options` in the [`get_signals`](/docs/signals/tasks/get_signals) response. Records the buyer's pricing commitment at activation time. Pass this same value in subsequent `report_usage` calls. | ### Destination Object @@ -356,7 +356,7 @@ Authorization: Bearer secret-token } ``` -See **[Webhooks](/docs/building/implementation/webhooks)** for complete details on webhook configuration and reliability. +See **[Webhooks](/docs/building/by-layer/L3/webhooks)** for complete details on webhook configuration and reliability. ## Scenarios diff --git a/docs/signals/tasks/get_signals.mdx b/docs/signals/tasks/get_signals.mdx index 9b74d35763..9712736f6a 100644 --- a/docs/signals/tasks/get_signals.mdx +++ b/docs/signals/tasks/get_signals.mdx @@ -22,7 +22,7 @@ The `get_signals` task returns both signal metadata and real-time deployment sta | `signal_spec` | string | Conditional | Natural language description of the desired signals. Required when `discovery_mode` is `"brief"` and both `signal_refs` and legacy `signal_ids` are absent. MUST NOT be provided when `discovery_mode` is `"wholesale"`. | | `signal_refs` | SignalRef[] | Conditional | Specific signals to look up by reference. Required when `discovery_mode` is `"brief"` and `signal_spec` is absent. MUST NOT be provided when `discovery_mode` is `"wholesale"`. | | `signal_ids` | SignalID[] | Conditional | **Deprecated.** Use `signal_refs` instead. Legacy specific-signal lookup for older clients. MUST NOT be provided when `discovery_mode` is `"wholesale"`. | -| `account` | [AccountRef](/docs/building/integration/accounts-and-agents#account-references) | No | Account for this request. When provided, the signals agent returns per-account pricing options if configured. In wholesale mode, this is the rate-card scope; when omitted the agent returns default rate-card pricing or omits `pricing_options` entirely. | +| `account` | [AccountRef](/docs/building/by-layer/L2/accounts-and-agents#account-references) | No | Account for this request. When provided, the signals agent returns per-account pricing options if configured. In wholesale mode, this is the rate-card scope; when omitted the agent returns default rate-card pricing or omits `pricing_options` entirely. | | `destinations` | Destination[] | No | Filter signals to those activatable on specific agents/platforms. When omitted, returns all signals available on the current agent. See Destination Object below. | | `countries` | string[] | No | Countries where signals will be used (ISO 3166-1 alpha-2 codes) | | `filters` | Filters | No | Filters to refine results (see Filters Object below). In wholesale mode, filters constrain the enumerated signals feed (e.g., `filters.data_providers: ["acme-data"]` returns only that provider's signals). | diff --git a/docs/sponsored-intelligence/specification.mdx b/docs/sponsored-intelligence/specification.mdx index eef6e80536..c080aeb80a 100644 --- a/docs/sponsored-intelligence/specification.mdx +++ b/docs/sponsored-intelligence/specification.mdx @@ -512,7 +512,7 @@ SI uses both standard AdCP error codes and SI-specific codes: |------|-------------| | `SESSION_NOT_FOUND` | Session ID is invalid, expired, or does not exist | | `SESSION_TERMINATED` | Session has been terminated and cannot accept further messages | -| `REFERENCE_NOT_FOUND` | Generic fallback when the referenced SI offering, proposal, or other resource does not exist or is not accessible. Returned uniformly for both cases — see [Uniform response for inaccessible references](/docs/building/implementation/error-handling#standard-error-codes) | +| `REFERENCE_NOT_FOUND` | Generic fallback when the referenced SI offering, proposal, or other resource does not exist or is not accessible. Returned uniformly for both cases — see [Uniform response for inaccessible references](/docs/building/by-layer/L3/error-handling#standard-error-codes) | | `RATE_LIMITED` | Too many requests | | `SERVICE_UNAVAILABLE` | Brand agent is temporarily unavailable | diff --git a/docs/sponsored-intelligence/tasks/si_initiate_session.mdx b/docs/sponsored-intelligence/tasks/si_initiate_session.mdx index c0fbe2d71c..0f76bdffef 100644 --- a/docs/sponsored-intelligence/tasks/si_initiate_session.mdx +++ b/docs/sponsored-intelligence/tasks/si_initiate_session.mdx @@ -22,7 +22,7 @@ Start a conversational session with a brand agent. The host platform invokes thi | `supported_capabilities` | object | No | What the host platform supports | | `offering_token` | string | No | Token from `si_get_offering` for correlation | | `sponsored_context_receipt` | object | No | Host receipt for sponsored context accepted before session initiation | -| `context` | object | No | Opaque correlation data echoed unchanged in the response (see [application context](/docs/building/integration/context-sessions#application-context-context)) | +| `context` | object | No | Opaque correlation data echoed unchanged in the response (see [application context](/docs/building/by-layer/L2/context-sessions#application-context-context)) | ### Offering Token diff --git a/docs/trust.mdx b/docs/trust.mdx index b34a977d9e..fd00f69809 100644 --- a/docs/trust.mdx +++ b/docs/trust.mdx @@ -81,7 +81,7 @@ First: **signed requests are normative in 3.1, not 3.0.** AdCP 3.0 allows bearer Second: **signing keys are not yet anchored in a key-transparency log.** In 3.x, RFC 9421 buyer keys, governance JWS keys, and agent signing keys are ultimately rooted in each counterparty's own infrastructure — an attacker controlling a counterparty's CDN, DNS, or `/.well-known` path can serve attacker-controlled keys. TLS does not close this gap. AdCP 3.x delivers trust-on-first-use with continuity (multi-source cross-check, publication-delay windows, out-of-band rotation signalling) — detectably raising the bar, but not cryptographically closing it. A key-transparency layer is a 4.0 deliverable. See [Known Limitations — Authentication and Identity](/docs/reference/known-limitations#authentication-and-identity) for the full description. -→ [Security Model](/docs/building/understanding/security-model) · [Security implementation reference](/docs/building/implementation/security) +→ [Security Model](/docs/building/concepts/security-model) · [Security implementation reference](/docs/building/by-layer/L1/security) --- diff --git a/docs/trusted-match/specification.mdx b/docs/trusted-match/specification.mdx index 12adcd6f3d..a04d8b342e 100644 --- a/docs/trusted-match/specification.mdx +++ b/docs/trusted-match/specification.mdx @@ -352,7 +352,7 @@ State transitions are immediate in static configuration (reload the config) and ### Provider registration security -**Endpoint URL validation (SSRF).** Both static configuration and dynamic registration MUST validate provider `endpoint` URLs against the canonical [Webhook URL validation (SSRF)](/docs/building/implementation/security#webhook-url-validation-ssrf) rules — HTTPS only in production, reserved IPv4 and IPv6 ranges rejected (including `::ffff:0:0/96` IPv4-mapped bypasses and the `169.254.169.254` / `fd00:ec2::254` cloud metadata addresses), no redirects. Because a router calls the provider on every request, DNS rebinding is the primary risk: routers MUST either pin the TCP connection to the IP that passed validation or re-validate the socket's post-handshake peer address before sending the request body. Re-resolving DNS without pinning is not sufficient. +**Endpoint URL validation (SSRF).** Both static configuration and dynamic registration MUST validate provider `endpoint` URLs against the canonical [Webhook URL validation (SSRF)](/docs/building/by-layer/L1/security#webhook-url-validation-ssrf) rules — HTTPS only in production, reserved IPv4 and IPv6 ranges rejected (including `::ffff:0:0/96` IPv4-mapped bypasses and the `169.254.169.254` / `fd00:ec2::254` cloud metadata addresses), no redirects. Because a router calls the provider on every request, DNS rebinding is the primary risk: routers MUST either pin the TCP connection to the IP that passed validation or re-validate the socket's post-handshake peer address before sending the request body. Re-resolving DNS without pinning is not sufficient. **Dynamic registration authentication.** The dynamic registration API is a privileged surface; unauthenticated registration lets an attacker point publisher traffic at arbitrary HTTPS endpoints. Routers exposing dynamic registration MUST authenticate callers (mTLS or short-lived OAuth 2.0 tokens; static API keys only with IP allow-listing) and SHOULD apply per-agent rate limits on mutations and a cap on total registered providers per publisher to bound registration-storm abuse. @@ -425,7 +425,7 @@ The canonical seller identity in AdCP is the agent URL declared in the property Providers SHOULD validate `seller_agent.agent_url` against the property publisher's adagents.json at sync time: -1. For each property the package may serve, fetch `/.well-known/adagents.json` on the property domain. If the file contains an `authoritative_location` pointer, follow it at most one hop to a same-scheme HTTPS URL; do not chain further. Both the initial fetch and the `authoritative_location` hop MUST apply the [Webhook URL validation (SSRF)](/docs/building/implementation/security#webhook-url-validation-ssrf) rules — HTTPS-only, reserved IPv4 and IPv6 ranges rejected (including `::ffff:0:0/96` IPv4-mapped bypasses and the `169.254.169.254` / `fd00:ec2::254` cloud metadata addresses), no transparent redirects, and the TCP connection pinned to the validated IP. The inbound-fetch rules referenced for [Provider registration security](#provider-registration-security) apply equally to this outbound fetch. +1. For each property the package may serve, fetch `/.well-known/adagents.json` on the property domain. If the file contains an `authoritative_location` pointer, follow it at most one hop to a same-scheme HTTPS URL; do not chain further. Both the initial fetch and the `authoritative_location` hop MUST apply the [Webhook URL validation (SSRF)](/docs/building/by-layer/L1/security#webhook-url-validation-ssrf) rules — HTTPS-only, reserved IPv4 and IPv6 ranges rejected (including `::ffff:0:0/96` IPv4-mapped bypasses and the `169.254.169.254` / `fd00:ec2::254` cloud metadata addresses), no transparent redirects, and the TCP connection pinned to the validated IP. The inbound-fetch rules referenced for [Provider registration security](#provider-registration-security) apply equally to this outbound fetch. 2. Confirm that `seller_agent.agent_url` appears in `authorized_agents[].url` and that any `property_ids`, `collections`, `placement_ids`, `placement_tags`, `countries`, `effective_from`, and `effective_until` constraints on that entry permit the package's scope. The URL comparison uses the [AdCP URL canonicalization rules](/docs/reference/url-canonicalization) — canonicalize both values before matching, never byte-equality. Reject `seller_agent.agent_url` values that do not use the `https://` scheme with `seller_not_authorized`; non-HTTPS seller URLs have no transport-integrity guarantee and cannot be trusted as an authorization key. 3. On mismatch, reject the sync operation for that `AvailablePackage` with an `error` response using `code: seller_not_authorized`. Other packages in the same sync batch are unaffected. The exact wire shape of the sync error is deployment-specific; `code` is the machine-readable reason.