Skip to main content
buy_products is the buyer-composed purchase path. It creates a MediaBuy from canonical product selections returned by list_products, accepting the published commercial terms as-is. Creative objects and assignments are deliberately absent. Use the creative lifecycle after the MediaBuy has been created. If the buyer needs different commercial terms, request or refine a proposal instead. Per-purchase flight dates, measurement_terms, and performance_standards may be omitted to inherit the published offer. The accepted snapshot resolves and preserves those terms. If this purchase ends a tracked planning cycle, opportunity closes it with accepted_with_seller. Request schema: /schemas/3.2.0-rc.6/media-buy/buy-products-request.json
The root frequency_cap uses one counter across all purchases. A targeting_overlay.frequency_cap inside a purchase instead owns an independent package counter; when both exist, both must permit delivery. Every selected product must advertise aggregate participation through media_buy_support.frequency_cap. Sellers reject an unadvertised aggregate cap or an incompatible product mix atomically with UNSUPPORTED_FEATURE before any mutation, and never clamp it. Buyers send the root field only when the seller advertises aggregate_frequency_capping; root caps are max-impression-only in 3.2. The media-buy daily_budget_cap is a hard aggregate ceiling and does not allocate its value among purchases. A purchase-level budget cap is an optional subordinate ceiling, not a reservation. Every budget cap shares the accepted media-buy budget_cap_timezone; sellers reject undeclared budget-cap scopes with UNSUPPORTED_FEATURE. Success returns the MediaBuy identity and an accepted_proposal snapshot. Its typed commercial_terms preserve the exact feed and pricing versions, product and format selections, catalogs, budgets, targeting, flight, billing, and reporting commitments; terms_digest binds that envelope for governance and audit. The separate purchase_bindings[] maps each zero-based purchase position to its seller-assigned package_id, which SDKs use for later creative assignment without placing execution IDs inside the immutable digest. The seller creates this snapshot even though the buyer did not negotiate first, giving every MediaBuy the same commercial history for later refine_proposals. An optional buyer-supplied name is persisted and echoed on the completed commitment and subsequent get_media_buys reads. It is operational display metadata outside accepted_proposal and is not covered by terms_digest. Each purchase uses request-only ProductPurchaseInput. Its targeting_overlay has three states per dimension: omission inherits the selected product’s configured/default value, a non-null value replaces it, and null explicitly suppresses it. A clear cannot remove inherent product scope. The accepted proposal uses strict ProductPurchase; it records the resolved effective targeting with cleared dimensions omitted and never carries null. A completed purchase MAY include warnings[] for non-blocking observations at commitment, such as a material inventory shortfall forecast. Each warning identifies its package through the returned media_buy_id and purchase_bindings[].package_id; a continuing condition is also readable as an indicator through get_media_buys. The seller may instead return input-required before commitment. Warnings never appear on failed or submitted arms. The accepted snapshot records the published terms the buyer purchased. It does not imply that every direct product is non-guaranteed: discovery mode, buyer composition, and delivery guarantee are independent dimensions.