Overview
Building a buyer agent or testing AdCP behavior? Start with Get products
across storefronts. It
returns a bounded canonical product/proposal page, can query named or all
connected storefronts, and optionally screens and refines proposals from
buyer instructions. Use the Discover Products compatibility flow below when
you need grouped pagination, summary/budget context, browse/SSE, or an
existing
discoveryId workflow. It projects the same raw fan-out and optional
screen; it does not invoke a separate ranking brain.1
Connect private storefronts (optional)
For storefronts that gate inventory, register per-source credentials first — see the Storefront object guide.
2
Run discovery
POST /api/v2/buyer/discovery/discover-products with a brief. Returns a
discoveryId plus product groups, agent proposals, and budget context.3
Browse and refine
Page through results with
GET /api/v2/buyer/discovery/{id}/discover-products
or iterate by sending refine instructions back to the same discoveryId.4
Pick products or apply a proposal
Add specific products with
POST /api/v2/buyer/discovery/{id}/products or
apply a full proposal with POST /api/v2/buyer/discovery/{id}/apply-proposal.5
Promote to a campaign
Call
create_media_buys to stage or execute several qualified selections
at once. Supply an existing campaign or let the operation create the DRAFT
campaign cart. auto-select-products remains available for performance
campaigns.discoveryId or get_products.ext.interchange.execution_id. You can re-open
it and refine results without losing context. The DRAFT campaign is the durable
shopping cart: it owns selected proposals/products and every media buy. Legacy
session-selection endpoints project selections through the same reconciliation
path for compatibility.
Progressive delivery
Discovery fans out to many sellers, and they answer at very different speeds — warmed catalogs in milliseconds, live agents in tens of seconds. By default the response waits for everyone (bounded bywaitMode/waitSeconds). Pass
progressive: true and sellers’ answers arrive as they land instead: the first
response returns within a couple of seconds with whoever has answered,
resultsComplete: false, and a pendingAgents list; you then poll
Browse products with
sinceRevision to receive only newly landed seller groups until
resultsComplete is true. Every progressive response includes a guidance
string spelling out the exact next call, so agent clients need no special
handling. The complete worked sequence is in
Discover products → Progressive delivery.
In Interchange chat, Murph prefers get_products for new canonical
product/proposal exploration and uses quick replacement snapshots while sellers
answer. Murph uses discover_products when the buyer explicitly asks for the
legacy grouped/session presentation or continues an existing discoveryId
workflow. It does not call both surfaces by default.
Storefront agents in discovery
Discovery fans out to both third-party sales agents and Scope3 storefront agents. A storefront agent hassalesAgentId: "storefront-{platform_id}", where platform_id is the storefront’s public platformId slug, and represents the storefront as a buyer-facing route for product discovery and media-buy execution. That ID identifies the storefront surface; it is not a source ID or underlying source agent ID.
Buyers call the same discovery endpoint for all agents. They do not need to distinguish between storefronts that compose products from raw inventory and storefronts that passthrough to an upstream inventory source. Composition storefronts return products assembled from active inventory sources and active operating instructions. Passthrough storefronts proxy get_products to an active source and apply storefront metadata and buyer-instruction overlays before results are returned. Buyer instructions are resolved from operator domain, brand domain, and optional country. Use storefrontIds or storefrontNames when you want to restrict discovery to specific storefronts.
Public buyer discovery only includes Storefronts that have passed marketplace
review and are listed. A Storefront can be live for known transactions while it
is still pending review, but it will not appear in public discovery results or
buyer marketplace browsing until an admin lists it.
Murph account analysis for adapter storefronts
Operators can ask Murph to runanalyze_account for adapter-routed
storefronts with delegated provider credentials. The tool analyzes a connected
advertising account through the storefront adapter and can render an
interactive account-analysis viewer in compatible MCP clients.
Inputs:
The response includes an
analysis object returned by the adapter, plus a
recommendations[] array for the operator. Adapter implementations may include
findings, metrics, account health signals, and other provider-specific details
inside analysis.
analyze_account is read-only but requires the storefront to be adapter-routed
and connected with delegated provider auth. Without a stored delegated
credential, Murph returns an auth-required response that includes the provider
OAuth setup path. Cross-account targeting is restricted to SuperAdmins; normal
storefront operators can analyze only their own storefront.
Public vs private storefronts
Storefronts fall into two visibility tiers:
Public discovery is also gated by marketplace review: pending-review and hidden
Storefronts are omitted from public buyer discovery even if they are otherwise
live. Private storefronts gate inventory behind per-source authentication.
Scope3 speaks to all sources - public and private - over the Ad Context
Protocol (ADCP); the difference is just whether the source requires the buyer
to present credentials before products are returned. The buyer never needs an
AAO key directly: AAO registry and compliance signals are handled server-side by
Scope3.
Step 1: Connect private storefronts (optional)
If you only need public inventory, skip ahead to Step 2. To unlock private storefronts, register credentials for the relevant inventory source. Three auth types are supported (API key, OAuth, JWT) — the source declares which it requires. Full walkthrough lives in the Storefront object guide; the short version:/api/v2/storefront/oauth/callback
so AI agents and back-end clients don’t need to handle redirects themselves.
Step 2: Run discovery
POST /api/v2/buyer/discovery/discover-products is the main entry point. You
can pass a brief inline or seed the request from an existing campaign with
campaignId.
Request
Response
discoveryId.
Persist the returned discoveryId — every subsequent call references it.
Discovery fans out across all reachable agents in parallel. Slow agents do
not block fast ones; agents that fail or are skipped are surfaced under
agentResults only when you pass debug: true.Agents whose advertised channel coverage does not overlap with the requested
channels are skipped before fanout (no round-trip), and appear in
agentResults with a skipReason like
Agent does not sell requested channels (supports: display, ctv; requested: social).
For agents that respond with an error, skipReason carries the
human-readable rejection text from the agent (e.g. "We do not support the list of channels you specified"); prefer it over error when surfacing the
reason in a UI. skipReason is agent-controlled content, sanitize before
rendering as HTML.Step 3: Page through results
Use the GET endpoint to browse the same session without spending another LLM-enriched discovery call. Filters narrow the cached result set in place.groupLimit, groupOffset,
productsPerGroup, productOffset, publisherDomain, pricingModel,
storefrontIds, storefrontNames, debug.
Refining results
Iterate on a previous response by sendingrefine instructions back to the
same discoveryId. Refinements come in three scopes:
refinementApplied
(matched by position) with status: "applied" | "partial" | "unable" and an
optional explanation.
You can include screening on the same request. Interchange first applies the
explicit seller refinement, then runs the refined proposals through the same
managed screening and bounded autonomous-refinement loop used by multi-storefront
get_products. Discover returns the accepted snapshot in its existing grouped
response shape. Screened Discover calls are terminal; use buyer get_products
when you need progressive screened replacement pages while sellers are still
responding.
A proposal-scoped finalize asks the seller to commit the draft plan: the
seller re-validates that every product in the proposal is still available at
current pricing, then answers status: "applied" with the commitment window
(the committed proposal’s expires_at). A committed proposal is a price and
composition commitment — not an inventory hold — and can be executed directly
by passing its proposal_id and a total_budget to create_media_buy
before it expires. Each committed proposal executes at most once; a proposal
whose products have changed since the draft answers status: "unable" with
the reason, and you can re-run discovery for a fresh plan.
Step 4: View specific products
Add products you want to evaluate to the session. Each selection records theproductId, the salesAgentId it came from, and the group it was discovered
in. Optionally pin a budget allocation, pricing option, or bid.
bidPrice (read it from the product’s
pricingOptions[].rate or floorPrice in the discovery response).
List the current session selection at any time:
Step 5: Apply a proposal
When an agent returns a proposal, you can accept its full allocation in one call instead of adding products one at a time.
The response echoes the applied proposal, the budget actually distributed, the
products that were added, and any products from the proposal that could not be
matched back to the discovery results (
productsSkipped).
Auto-select on a campaign
For agentic / hands-off flows, attach an existing campaign and let Scope3 pick products for you. This wraps discovery + selection in a single call against the campaign’s existing brief, flight dates, and budget.refine directives accepted by discover-products:
discoveryId so you can drop into the
manual flow at any point to inspect or adjust the selection.
Best practices
- Briefs
- Pagination & polling
- Source credentials
- Refinement loops
- Lead with the outcome, not just the demographic. Agents score against campaign objective + creative + audience together.
- Include guardrails that matter: brand-safety needs, format
constraints (
16:9,:30s), exclusions. - Keep briefs under ~500 characters when possible — long briefs are auto-summarized for LLM enrichment but lose nuance.
Related
- Campaigns guide — promote a discovery selection into a live media buy
- Storefronts — connect, refresh, and manage credentials per inventory source
- Buyer storefronts — register against operator-hosted storefronts
- Buyer API reference — full endpoint and schema reference