Skip to main content
There is no separate merchandising document. Merchandising is what your storefront does — the Merchandising Agent selling on your behalf — not a thing you save. Three Pages steer it, split by what kind of fact each one holds: The Page names and read tools now use the same three nouns. Selling Terms is retired: structured prices and floors moved to Playbook, while approval gates moved to Business Rules. Business Profile is compatibility storage, not a Page and not a Media Kit. “Media Kit” means Product Marketing material used as an input to merchandising; that product is not a V3 noun until its backing store exists. Your saved configuration and version history do not move or reset. In chat and any MCP Apps host, get_discovery_card, get_playbook, and get_business_rules open the portable Pages. The historical media-kit resource URI continues to render the deprecated legacy Business Profile/Media Kit only for saved-conversation compatibility; it is not the Discovery Card Page.
/mcp/v3 remains a gated preview. The get and save_* examples below apply only to that surface; the get_discovery_card, get_playbook, and get_business_rules Pages are available through the current seller MCP surface.

One fact, one owner

Playbook instruction content cannot duplicate structured Playbook pricing, Buyer Discounts, Discovery Card facts, or Business Rules. It may refer to those facts without restating them. A conflicting version is rejected on save rather than left for the agent to reconcile later. Writing “the Nike house gets 12%” into your guidance is the case this catches: the discount is a structured rule with its own field, not a sentence for the agent to interpret. Business Rules separates three decisions. Brief Acceptance decides whether an otherwise matching brief should receive a response; Creative Policy judges submitted creative; and Approval Mechanics decides whether and where human review runs. With mediaBuyApproval: manual and no active policy, every media buy is held for review. Discovery Card channels/countries and Playbook guide what the agent presents and how it sells; neither controls the review gate. A managed seller may separately elect to show Brief Acceptance, Creative Policy, both, or neither as Advertising Policies on the Discovery Card. This disclosure selector belongs to Business Rules because that is where its source text is edited. Approval mode, approvers, routing, per-buyer overrides, and revision notes are never disclosed. For a pass-through storefront, the read-only disclosure comes from upstream AdCP media_buy.portfolio.advertising_policies.
External pass-through storefronts do not get local Business Rules or approval settings. Their channels and countries come from the upstream agent’s get_adcp_capabilities portfolio; both are read-only. Missing declarations stay unknown and do not match filtered searches.

Reading singleton nouns and the storefront projection

playbook and business_rules are singletons — exactly one per storefront — so get identifies them by kind alone. Discovery Card is not a noun; request it as a projection of the storefront:
include: ["versions"] adds the full version history for playbook and business_rules (an array of { version, isActive, notes, createdAt }); omit it and get returns only what is currently active. There is no separate “list versions” tool — version history is an include, the same way source diagnostics are. The history is deliberately a summary: it carries no content, because a storefront with dozens of 50,000-character versions would return an unusable response. To read one version in full, name it:
That returns selectedVersion with the version’s content, its notes, its ownershipIssues, and a restorable flag. restorable: false means the version restates a fact owned by another canonical surface and would be rejected if you saved it back unchanged; the create-and-activate section below explains why, and what to do about it. version is only served for kind: "playbook". include: ["discounts"] adds the playbook’s brand and operator house discount rules. If a read fails, the key is omitted and an unavailableIncludes entry names it — “no discounts are configured” and “the discount read failed” mean opposite things for what your buyers are paying, so the response never lets you confuse them. include: ["approvalRouting"] on business_rules adds who receives each kind of review work — see Approval routing.

Discovery Card — what buyers see

save_storefront writes the local description and, for a managed storefront, the buyer-visible channels and ISO countries. Pass-through storefronts read channels and countries from get_adcp_capabilities; those fields are read-only locally.
Name, logo, colors, and website are resolved from the verified operator domain and brand.json; link or correct that identity instead of forking it on the card. Open the Page with:

playbook — how you sell

save_playbook has three independent halves you can send together or apart: content (posture and packaging guidance, versioned), pricing (your value-anchor facts), and discounts (your brand and operator rate-card rules).
ownershipIssues identifies any line in the active guidance that duplicates structured Playbook pricing, Buyer Discounts, Discovery Card facts, or Business Rules. pricing.facts replaces the whole list — a fact you don’t repeat in the request is removed, the same “whole document” semantics as content.

Discounts are per rule, not a whole list

discounts is the exception, and the difference is deliberate. A house discount is keyed by (houseDomain, scope) and changes what a real buyer pays on their next buy, so a rule you don’t mention is left exactly as it was. Removing one means naming it:
  • A rule for a (houseDomain, scope) pair that doesn’t exist yet is created; one that does is updated. Sending a rule that already matches is a no-op and says so.
  • Omitting notes keeps the note you already wrote. Send null to clear it.
  • remove needs both halves of the key, because nike.com can carry a brand discount and an operator discount at once and they are different rules.
  • Naming the same pair in rules and remove is rejected rather than resolved for you.
Each rule is applied independently. If one fails the response reports exactly which one, keeps the rest, and tells you to retry only the failure — the rows are individually keyed, so a retry repeats nothing that already succeeded. Deciding whether to create or update a rule means knowing whether it already exists, so if your current rules can only be read in part, that question has no safe answer. In that case the affected declaration is refused rather than guessed: you get “this pair could not be confirmed either way” instead of a create that might collide with a live rule, or a “nothing to remove” that would tell you a discount is gone while it keeps applying. Rules the partial read did show are still updated and removed normally. The content half of the same call is never rolled back for a discounts failure, and vice versa: they are separate writes, and the response names what landed.

Which discount a buyer actually gets

The rules you author and the discount a buy receives are different things. search will resolve one for you:
results is your authored rules, unchanged. resolution is derived: the corporate chain the domain resolved up (converse.com → nike.com), the hierarchy coverage, and the nearest rule that keys on each axis. It always carries caveats, because a real buy resolves its brand and its operator separately and takes the larger of the two — one domain’s chain cannot decide it. When the hierarchy can’t be resolved, you get unavailable and your authored rows rather than a confident “no discount applies”.

business_rules — what you accept

save_business_rules also has independent versioned policy sections and two approval gates. Structured policy writes always send both sections, so an omitted field can never erase the other section accidentally.

Turning off human review

Moving creativeApproval or mediaBuyApproval to auto needs acknowledgeNoHumanReview: true on the same call:
Leave it out and the save fails with a validation error rather than a silent no-op:
auto removes human review; it does not remove the product-discovery policy boundary. A confident policy conflict returns no products, while an unavailable qualifier fails open. Once a buyer passes discovery, create_media_buy preserves the established auto-forward contract. With mediaBuyApproval: manual, the submitted buy is evaluated again: clearly on-policy buys auto-forward, while uncertain results, evaluator errors, and deterministic hard findings queue for an operator. Live auto-rejection requires a separate seller opt-in or versioned rollout.

Every save is create-and-activate

playbook.content and business_rules.content are versioned and immutable. Saving one creates a new version and makes it active in the same call — the response’s createdVersion and replacedVersion tell you what happened, and there is no activate flag on the save. A version you save has full effect immediately; there’s no draft state where it exists but hasn’t taken effect.

Rolling back: two routes, and the agent only has one of them

There is no activation field or activate_* tool on /mcp/v3, by design. An agent rolls back the way it writes anything else — by saving the earlier content again, which mints a new version carrying it. History stays append-only, and the restored content is re-checked against the current ownership rules on the way in. The Business Rules Page has the other route: it lists every immutable version and can reactivate one directly, behind a two-step confirmation, without minting anything. Use it when you want the version count and history left exactly as they are. Open it with get_business_rules, or on /mcp/v3 with open_page and page: "business_rules". Either way, decisions already recorded keep the policy they were made under. Changing which version is active changes what happens next; it does not retroactively re-judge a creative or media buy someone already approved. playbook works the same way: save the earlier content again to roll back. For the playbook that is a two-step journey, and both steps are reads you can make:
1

Read the version you want back

get({ kind: "playbook", version: 2 }) returns that version’s full content plus a restorable flag.
2

Save that content again

save_playbook({ content: "…" }) mints a new version carrying it, active immediately. Your history keeps both — nothing is overwritten.
restorable: false is worth reading before you try. Playbook content that restates a price, a discount, a market, or an acceptance rule is rejected on save because another canonical surface owns that fact, and an older version written before that check can still contain one. Re-saving it puts it back through the current validator, so a flagged version needs editing before it can go live again. That is not a cost of the re-save route: the older activate call re-runs the same validator and refuses a flagged version too, so the content is unacceptable either way. Edit the flagged lines out and save what’s left. save_playbook and save_business_rules also each take unversioned halves in the same call — pricing and discounts on the playbook, the approval gates on business rules. The parts run in a fixed order — content, then pricing, then discounts — and there is no transaction spanning them. If a part fails, the response tells you exactly where the call stopped:
  • Parts that already succeeded stay applied. A version that was created is live and is not rolled back, and the error still names createdVersion (and replacedVersion) so you know it exists before retrying.
  • Parts that never ran are listed in unattempted, and the message names them. A pricing failure means your discounts were not read, created, changed or removed at all — so the retry guidance says to re-send pricing and discounts, and a content failure means neither of the other two was attempted and nothing is half-applied.
  • Retry only what the response tells you to. Sending content again would mint a second, identical version rather than fixing anything.

Approval routing: who reviews, as opposed to whether anyone reviews

The approval gates decide whether a human reviews. Approval routing decides which human — the named users and roles who receive each kind of review work, the channels they are notified on, and the reminder and escalation clock. It is a third thing, on its own lifecycle: not versioned like the acceptance policy, and not a gate. Read it as an include on business_rules:
An approval kind missing from policies is not unrouted — it falls back to the default org-admin audience. An approver shown with eligible: false is still named in the policy but no longer has an eligible role on the account, which is worth cleaning up. Reading routing requires a storefront admin; a non-admin session gets an approvalRouting entry under unavailableIncludes explaining why, never an empty table that would read as “nobody reviews”.

Routing is changed on the Approvals Page, not by a tool

There is no routing field on save_business_rules, and passing one returns an error naming the Page instead. Choosing an approver changes who can act on your storefront, and that class of change is a human ceremony rather than something an agent writes — the same rule that keeps credentials, access grants, and payout destinations off the agent surface. Open the Page with open_page and page: "approvals"; the routing editor lives there alongside the queues, and only admins can save it. Eligible users’ email addresses are deliberately not returned to the agent. An approver who has never set a name comes back as "name": null rather than falling back to their address — they are still eligible: true, there is just no name safe to show. The Page shows the full directory to the human choosing.

Searching version history and discount rules

playbook and business_rules are singletons, so search doesn’t search them. Discovery Card is a storefront projection rather than a searchable noun. What is list-shaped is the version history and the playbook’s discount rules.
business_rules_version works the same way over acceptance-policy history, and house_discount lists the playbook’s brand and operator rules. Omit kind and search lists every list-shaped object it knows about, playbook_version, business_rules_version, and house_discount included — so a broad question about your setup never silently leaves your discounts out.

v3 Agent Surface

The one-endpoint, noun-shaped surface these tools live on.

Merchandising

The three Pages you use today, and how they map to the platform.

Acceptance policy

How the pre-screen reads your policy, and the three verdicts it returns.

Glossary

Component, Product, and the rest of the vocabulary these nouns build on.