brief or wholesale discovery, use buying_mode: "refine" to iterate on specific products and proposals — adjusting the selection, requesting changes, and exploring alternatives — before committing to a create_media_buy.
The refinement lifecycle
A typical media buying workflow follows this pattern:-
Discover — Call
get_productswithbuying_mode: "brief"or"wholesale"to find matching inventory. The seller returns products (and optionally proposals). -
Refine — Call
get_productswithbuying_mode: "refine"and arefinearray of change requests. Each entry declares a scope and what the buyer is asking for. The seller returns updated products with revised pricing and configurations. - Repeat — Refine as many times as needed. Each call is self-contained and stateless.
-
Buy — When satisfied, execute the final selection via
create_media_buy.
The refine array
Therefine array is a list of change requests. Each entry declares a scope and what the buyer is asking for:
The
refine array requires at least one entry. The seller considers all entries together when composing the response, and replies to each one via refinement_applied.
Product actions
Product-scoped entries declare an explicit action:Request-level direction
Usescope: "request" to describe what you want from the selection as a whole:
refine array may appear in the response if the seller determines they fit the direction.
Precedence: Per-product actions take precedence over request-level direction. If the request-level ask says “less display” but a specific product has action: "include", that product is returned regardless.
Proposal refinement
Reference proposals by ID to request adjustments or remove them:Combining scopes
All scopes work together. A single refinement call can set direction for the selection, act on specific products, and request changes to a proposal:Seller response
When a buyer sends arefine array, the seller responds with refinement_applied — an array matched by position to the buyer’s change requests. Each entry reports whether the ask was fulfilled:
refinement_applied array MUST contain the same number of entries in the same order as the refine array. Entries SHOULD echo scope and id for cross-validation. The entire field is optional — sellers that don’t track per-ask outcomes can omit it.
Common refinement patterns
Find similar products
Usemore_like_this to discover products similar to ones you like. The seller returns the original product plus additional options matching its characteristics:
Adjust filters
Filters on a refine request represent the complete target state, not a delta. Always send the full filter set you want applied:Narrow or expand a proposal
The product entries define which products the seller should consider for the proposal. Combined with proposal entries, this narrows or expands the proposal’s product set:Proposals in refine mode
Sellers MAY return proposals alongside refined products, even when the buyer did not include proposal entries. For example, a buyer refining three products may receive those products back with updated pricing and a proposal suggesting how to combine them. Key points:- Proposals are not guaranteed. Sellers are not required to generate proposals in refine mode. Allocation and campaign optimization are primarily orchestrator (buyer-side agent) responsibilities.
- Signal interest via a request-level ask. Include
{ "scope": "request", "ask": "suggest how to combine these products" }to indicate you’d welcome a proposal. - Unsolicited proposals can be refined or ignored. If a seller returns a proposal you didn’t request, you can refine it in a follow-up call, or simply ignore it and build packages manually via
create_media_buy.
wholesale mode, where the buyer is directing targeting and allocation themselves.
Statelessness
Eachget_products request with buying_mode: "refine" is self-contained. The refine array and filters on each request fully specify the refinement intent. Sales agents MUST NOT depend on transport-level session state (e.g., remembering what was sent in a previous request).
Sellers still maintain their own product and proposal registries — “stateless” means the protocol exchange carries no implicit state between calls.
This design enables:
- Stateless implementations — sellers don’t need to track refinement sessions
- Safe retries — a failed refinement call can be retried with the same parameters
- Parallel exploration — an orchestrator can explore multiple refinement paths simultaneously
Client validation
Orchestrators should validate refinement requests before sending:- Non-empty refine — The
refinearray requires at least one entry. An empty[]is rejected by schema validation. - Valid entries — Each product entry requires
scope,id, andaction(include,omit, ormore_like_this). Each proposal entry requiresscope,id, andaction(includeoromit). Request-level entries requirescopeandask. - Filters are absolute — Send the full filter set you want applied, not a delta from the previous request.
Error handling
Normative requirements
The Media Buy Specification defines the following normative requirements for refinement: Orchestrators:- MUST include
refinewhenbuying_modeis"refine" - MUST NOT include
refinewhenbuying_modeis"brief"or"wholesale" - MUST provide
scope,id, andactionfor each product and proposal entry - MUST NOT include multiple entries for the same product ID or proposal ID in a single
refinearray
- MUST omit products with
action: "omit"from the response - MUST omit proposals with
action: "omit"from the response - MUST return products with
action: "include", with updated pricing - SHOULD fulfill the
askon product entries withaction: "include" - SHOULD return additional products similar to those with
action: "more_like_this", plus the original product - SHOULD consider request-level asks when composing the response — this MAY result in additional products beyond those explicitly referenced. Per-product actions take precedence over request-level direction.
- SHOULD fulfill the
askon proposal entries withaction: "include" - SHOULD include
refinement_appliedin the response when the buyer providesrefine, with one entry per change request matched by position - MAY return proposals even when the buyer did not include proposal entries
See also
get_productstask reference — API reference with request/response schemas- Media Products — product model and proposal structure
- Media Buy Specification — normative requirements
- Orchestrator Design — building buyer-side agents