Overview
Product Discovery is the buyer-side loop for finding inventory across one or more sales agents (publishers, exchanges, content owners). You provide a brief — what you’re trying to accomplish, who you’re targeting, when it runs, and how much you can spend — and Scope3 fans the request out to every agent your seat has access to. The agents return products and (when supported) recommended proposals that allocate budget across those products. The flow:Connect private storefronts (optional)
For storefronts that gate inventory, register per-source credentials first — see the Storefront object guide.
Run discovery
POST /api/buyer/discovery/discover-products with a brief. Returns a
discoveryId plus product groups, agent proposals, and budget context.Browse and refine
Page through results with
GET /api/buyer/discovery/{id}/discover-products
or iterate by sending refine instructions back to the same discoveryId.Pick products or apply a proposal
Add specific products with
POST /api/buyer/discovery/{id}/products or
apply a full proposal with POST /api/buyer/discovery/{id}/apply-proposal.discoveryId. You
can re-open it, refine results, swap products in and out, and replay proposals
without losing context.
Public vs private storefronts
Storefronts fall into two visibility tiers:| Tier | Who can discover | How to access |
|---|---|---|
| Public | Any authenticated buyer | Available by default — no extra setup |
| Private / gated | Buyers with credentials registered for the source | Register credentials per inventory source (API key, OAuth, or JWT) |
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/storefront/oauth/callback
so AI agents and back-end clients don’t need to handle redirects themselves.
Step 2: Run discovery
POST /api/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
| Field | Type | Description |
|---|---|---|
advertiserId | integer | Required. Resolves the brand manifest used to score agent results. |
discoveryId | string | Reuse an existing session. Required when sending refine. |
campaignId | string | Seed brief, flight dates, and budget from a campaign. Inline values override. |
brief | string (≤5000 chars) | Natural-language search context. |
budget | number | Total budget in account currency. Used for budget context + proposals. |
channels | string[] | display, olv, ctv, social, or video (alias for olv). Defaults to ["display","olv","ctv","social"]. |
countries | string[] | ISO 3166-1 alpha-2 country codes. Defaults to brand agent countries. |
flightDates | { startDate, endDate } | ISO 8601 datetimes (e.g. 2026-07-01T00:00:00Z). Filters by agent availability. |
publisherDomain | string | Filter to a single publisher domain. |
pricingModel | string | Filter by AdCP pricing model (cpm, cpcv, etc.). |
salesAgentIds / salesAgentNames | string[] | Restrict to specific agents. |
groupLimit | integer (≤10) | Max product groups per page. Default 10. |
productsPerGroup | integer (≤15) | Max products inside each group. Default 10. |
groupOffset / productOffset | integer | Pagination cursors. |
debug | boolean | Include per-agent ADCP request/response logs in the response. |
refine | array | Refinement directives (see Refining). Requires discoveryId. |
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 are surfaced under
agentResults only
when you pass debug: true.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,
salesAgentIds, salesAgentNames, 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.
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.| Field | Description |
|---|---|
proposalId | Required. ID from the discover-products response. |
totalBudget | Optional. Defaults to proposal.totalBudgetGuidance.recommended. |
replace | When true, clears existing selected products before applying. |
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