Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/scope3-product-discovery-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
OpenAPI Specification
openapi: 3.2.0
info:
title: Scope3 Buyer Product Discovery API
version: 2.0.0
description: 'REST API for advertisers to manage advertisers, campaigns, and reporting.
## Authentication
All endpoints require a Bearer token in the Authorization header:
```
Authorization: Bearer your-api-key
```
## Base URL
`https://api.interchange.io/api/v2/buyer`
## For AI Agents
AI agents can use the MCP endpoint at `/mcp/v2/buyer` with three tools:
- `initialize`: Start an MCP session
- `api_call`: Make REST API calls
- `ask_about_capability`: Learn about API features'
servers:
- url: https://api.interchange.io/api/v2/buyer
description: Production server
tags:
- name: Product Discovery
description: Discover and select products
paths:
/products/query:
post:
operationId: getMarketplaceProducts
summary: Get products across storefronts
description: Send a canonical AdCP get_products request across selected or all connected storefronts. Omit ext.interchange.screening for unscreened retrieval or provide buyer instructions for managed proposal accept, reject, and refine screening. Provisional responses are replacement snapshots; terminal cursors reference the frozen result.
tags:
- Product Discovery
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GetProductsBody'
responses:
'200':
description: Get products across storefronts
content:
application/json:
schema:
$ref: '#/components/schemas/ProjectedGetProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/media-buys/batch:
post:
operationId: createMediaBuysBatch
summary: Stage or execute products across storefronts
description: Continue from a multi-storefront get_products execution by staging qualified proposals/products on a DRAFT campaign cart, with optional execution through the existing per-storefront media-buy path.
tags:
- Product Discovery
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMediaBuysBatchBody'
responses:
'200':
description: Stage or execute products across storefronts
content:
application/json:
schema:
$ref: '#/components/schemas/CreateMediaBuysBatchResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/discovery/discover-products:
post:
operationId: discoverProducts
summary: Discover products
description: Discover products with automatic session creation. If discoveryId is not provided, a new session is created automatically. Returns discoveryId and discovered products.
tags:
- Product Discovery
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/DiscoverProductsBody'
responses:
'200':
description: Discover products
content:
application/json:
schema:
$ref: '#/components/schemas/DiscoverProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/discovery/{discoveryId}/discover-products:
get:
operationId: browseProducts
summary: Browse products for discovery session
description: Browse available products for an existing discovery session. Returns product suggestions grouped by publisher with pagination support.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: query
name: groupLimit
schema:
description: 'Maximum number of product groups to return (default: 10, max: 10)'
example: 10
default: 10
type: integer
maximum: 10
minimum: 1
description: 'Maximum number of product groups to return (default: 10, max: 10)'
- in: query
name: groupOffset
schema:
description: Number of groups to skip for pagination
example: 0
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
description: Number of groups to skip for pagination
- in: query
name: productsPerGroup
schema:
description: 'Maximum products to return per group (default: 10, max: 15)'
example: 10
default: 10
type: integer
maximum: 15
minimum: 1
description: 'Maximum products to return per group (default: 10, max: 15)'
- in: query
name: productOffset
schema:
description: 'Number of products to skip within each group (default: 0, max: 1000)'
example: 5
default: 0
type: integer
minimum: 0
maximum: 1000
description: 'Number of products to skip within each group (default: 0, max: 1000)'
- in: query
name: publisherDomain
schema:
description: Filter products by publisher domain (exact domain component match)
example: hulu
type: string
minLength: 1
description: Filter products by publisher domain (exact domain component match)
- in: query
name: pricingModel
schema:
description: Filter products by pricing model
example: cpm
type: string
enum:
- cpm
- vcpm
- cpc
- cpcv
- cpv
- cpp
- cpa
- flat_rate
- time
description: Filter products by pricing model
- in: query
name: storefrontIds
schema:
description: Filter products by storefront ID(s) (from `list_storefronts`).
example:
- 42
- 57
anyOf:
- maxItems: 50
type: array
items:
type: integer
maximum: 9007199254740991
minimum: 1
- type: string
description: Filter products by storefront ID(s) (from `list_storefronts`).
- in: query
name: storefrontNames
schema:
description: Filter products by storefront name (case-insensitive substring match).
example:
- Acme
- Acme Exchange
anyOf:
- maxItems: 50
type: array
items:
type: string
maxLength: 255
- type: string
description: Filter products by storefront name (case-insensitive substring match).
- in: query
name: debug
schema:
description: When true, includes detailed ADCP agent request/response debug logs in the response for troubleshooting
anyOf:
- type: boolean
- type: string
description: When true, includes detailed ADCP agent request/response debug logs in the response for troubleshooting
- in: query
name: waitMode
schema:
description: '`quick` waits up to 30 seconds per storefront agent and returns partial results if slow agents miss the window. `long` waits up to 210 seconds per storefront agent; ask the user before using it.'
example: quick
default: quick
type: string
enum:
- quick
- long
description: '`quick` waits up to 30 seconds per storefront agent and returns partial results if slow agents miss the window. `long` waits up to 210 seconds per storefront agent; ask the user before using it.'
- in: query
name: waitSeconds
schema:
description: Optional explicit per-storefront wait in seconds, max 210. Overrides waitMode. Ask the user before setting this above 30.
example: 120
type: integer
maximum: 210
minimum: 1
description: Optional explicit per-storefront wait in seconds, max 210. Overrides waitMode. Ask the user before setting this above 30.
- in: query
name: sinceRevision
schema:
description: 'Progressive polling: return only seller groups that landed after this snapshot revision. Groups use REPLACE semantics — a group may be re-delivered at a later revision when more of its products land; replace it by groupId, never append. The response always carries the current `revision`, `resultsComplete`, and `pendingAgents`; poll again with the returned revision until `resultsComplete` is true, and stop polling after roughly the wait budget if it never turns true (the fan-out may have been interrupted).'
example: 3
type: integer
minimum: 0
maximum: 9007199254740991
description: 'Progressive polling: return only seller groups that landed after this snapshot revision. Groups use REPLACE semantics — a group may be re-delivered at a later revision when more of its products land; replace it by groupId, never append. The response always carries the current `revision`, `resultsComplete`, and `pendingAgents`; poll again with the returned revision until `resultsComplete` is true, and stop polling after roughly the wait budget if it never turns true (the fan-out may have been interrupted).'
- in: path
name: discoveryId
schema:
description: Discovery ID
example: abc123-def456-ghi789
type: string
minLength: 1
required: true
description: Discovery ID
responses:
'200':
description: Browse products for discovery session
content:
application/json:
schema:
$ref: '#/components/schemas/DiscoverProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/discovery/{discoveryId}/products/{productId}/details:
get:
operationId: getProductDetails
summary: Get product details
description: Get the full detail view for a single discovered product — description, pricing, delivery windows, and creative format requirements. Requires the `salesAgentId` the product was discovered through.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: query
name: salesAgentId
schema:
description: Sales agent ID for the product
type: string
minLength: 1
required: true
description: Sales agent ID for the product
- in: path
name: discoveryId
schema:
description: Discovery session id.
type: string
minLength: 1
required: true
description: Discovery session id.
- in: path
name: productId
schema:
description: Discovered product id.
type: string
minLength: 1
required: true
description: Discovered product id.
responses:
'200':
description: Get product details
content:
application/json:
schema:
$ref: '#/components/schemas/DiscoveryProductDetail'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/discovery/{discoveryId}/products:
get:
operationId: getProducts
summary: Get selected products
description: Get the list of products that have been selected in this discovery session.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: path
name: discoveryId
schema:
description: Discovery ID
example: abc123-def456-ghi789
type: string
minLength: 1
required: true
description: Discovery ID
responses:
'200':
description: Get selected products
content:
application/json:
schema:
$ref: '#/components/schemas/SessionProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
post:
operationId: addProducts
summary: Add products to selection
description: Add products to the selection. Products must have been discovered via GET /discovery/{discoveryId}/discover-products first.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: path
name: discoveryId
schema:
description: Discovery ID
example: abc123-def456-ghi789
type: string
minLength: 1
required: true
description: Discovery ID
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AddProductsRequest'
responses:
'200':
description: Add products to selection
content:
application/json:
schema:
$ref: '#/components/schemas/SessionProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
delete:
operationId: removeProducts
summary: Remove products from selection
description: Remove products from the selection.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: path
name: discoveryId
schema:
description: Discovery ID
example: abc123-def456-ghi789
type: string
minLength: 1
required: true
description: Discovery ID
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RemoveProductsRequest'
responses:
'200':
description: Remove products from selection
content:
application/json:
schema:
$ref: '#/components/schemas/SessionProductsResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/discovery/{discoveryId}/apply-proposal:
post:
operationId: applyProposal
summary: Apply a proposal
description: Apply a sales agent proposal to auto-add products with recommended budget allocations. Requires discover-products to have been called first.
tags:
- Product Discovery
security:
- bearerAuth: []
parameters:
- in: path
name: discoveryId
schema:
description: Discovery ID
example: abc123-def456-ghi789
type: string
minLength: 1
required: true
description: Discovery ID
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApplyProposalRequest'
responses:
'200':
description: Apply a proposal
content:
application/json:
schema:
$ref: '#/components/schemas/ApplyProposalResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
schemas:
DiscoveryProductDetail:
type: object
properties:
productId:
type: string
name:
type: string
description:
type: string
channel:
type: string
deliveryType:
type: string
enum:
- guaranteed
- non_guaranteed
salesAgentId:
type: string
salesAgentName:
type: string
storefrontId:
type: string
storefrontName:
type: string
cpm:
type: number
currency:
description: ISO currency code for `cpm`. Absent when unknown.
type: string
required:
- productId
- name
additionalProperties: {}
CreateDiscoveryCampaignBody:
description: Request body for creating a discovery-mode campaign
type: object
properties:
advertiserId:
description: Advertiser ID that will own this campaign
example: 12345
type: integer
maximum: 9007199254740991
minimum: 1
name:
description: Name of the campaign
example: Q1 2025 Campaign
type: string
minLength: 1
maxLength: 255
flightDates:
description: Campaign flight dates
type: object
properties:
startDate:
description: Campaign start date (ISO 8601)
example: '2025-01-15T00:00:00Z'
type: string
format: date-time
pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
endDate:
description: Campaign end date (ISO 8601)
example: '2025-03-31T23:59:59Z'
type: string
format: date-time
pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
required:
- startDate
- endDate
budget:
description: Campaign budget configuration
type: object
properties:
total:
type: number
exclusiveMinimum: 0
currency:
description: Optional ISO 4217 currency. If provided it must match the advertiser's primary currency; otherwise the advertiser's currency is used. Campaigns cannot be created in a currency other than the advertiser's.
type: string
minLength: 3
maxLength: 3
dailyCap:
type: number
exclusiveMinimum: 0
pacing:
type: string
enum:
- EVEN
- ASAP
- FRONTLOADED
required:
- total
brief:
description: Natural language brief for product search context
example: Looking for premium video inventory targeting tech enthusiasts
type: string
maxLength: 5000
constraints:
description: Campaign targeting constraints
type: object
properties:
geo_countries:
type: array
items:
type: string
geo_countries_exclude:
type: array
items:
type: string
geo_regions:
type: array
items:
type: string
geo_regions_exclude:
type: array
items:
type: string
geo_metros:
type: array
items:
type: object
properties:
system:
anyOf:
- type: string
enum:
- nielsen_dma
- type: string
enum:
- uk_itl1
- type: string
enum:
- uk_itl2
- type: string
enum:
- eurostat_nuts2
- type: string
enum:
- custom
values:
type: array
items:
type: string
required:
- system
- values
additionalProperties: {}
geo_metros_exclude:
type: array
items:
type: object
properties:
system:
anyOf:
- type: string
enum:
- nielsen_dma
- type: string
enum:
- uk_itl1
- type: string
enum:
- uk_itl2
- type: string
enum:
- eurostat_nuts2
- type: string
enum:
- custom
values:
type: array
items:
type: string
required:
- system
- values
additionalProperties: {}
geo_postal_areas:
type: array
items:
anyOf:
- type: object
properties:
country:
type: string
pattern: ^[A-Z]{2}$
system:
anyOf:
- type: string
enum:
- postal_code
- type: string
enum:
- zip
- type: string
enum:
- zip_plus_four
- type: string
enum:
- outward
- type: string
enum:
- full
- type: string
enum:
- fsa
- type: string
enum:
- plz
- type: string
enum:
- code_postal
- type: string
enum:
- postcode
- type: string
enum:
- cep
- type: string
enum:
- pin
- type: string
enum:
- custom
- type: string
enum:
- us_zip
- type: string
enum:
- us_zip_plus_four
- type: string
enum:
- gb_outward
- type: string
enum:
- gb_full
- type: string
enum:
- ca_fsa
- type: string
enum:
- ca_full
- type: string
enum:
- de_plz
- type: string
enum:
- fr_code_postal
- type: string
enum:
- au_postcode
- type: string
enum:
- ch_plz
- type: string
enum:
- at_plz
values:
type: array
items:
type: string
required:
- country
- system
- values
additionalProperties: {}
- type: object
properties:
system:
anyOf:
- type: string
enum:
- us_zip
- type: string
enum:
- us_zip_plus_four
- type: string
enum:
- gb_outward
- type: string
enum:
- gb_full
- type: string
enum:
- ca_fsa
- type: string
enum:
- ca_full
- type: string
enum:
- de_plz
- type: string
enum:
- fr_code_postal
- type: string
enum:
- au_postcode
- type: string
enum:
- ch_plz
- type: string
enum:
- at_plz
values:
type: array
items:
type: string
required:
- system
- values
additionalProperties: {}
geo_postal_areas_exclude:
type: array
items:
anyOf:
- type: object
properties:
country:
type: string
pattern: ^[A-Z]{2}$
system:
anyOf:
- type: string
enum:
- postal_code
- type: string
enum:
- zip
- type: string
enum:
- zip_plus_four
- type: string
enum:
- outward
- type: string
enum:
- full
- type: string
enum:
- fsa
- type: string
enum:
- plz
- type: string
enum:
- code_postal
- type: string
enum:
- postcode
- type: string
enum:
- cep
- type: string
enum:
- pin
- type: string
enum:
- custom
- type: string
enum:
- us_zip
- type: string
enum:
- us_zip_plus_four
- type: string
enum:
- gb_outward
- type: string
enum:
- gb_full
- type: string
enum:
- ca_fsa
- type: string
enum:
- ca_full
- type: string
enum:
- de_plz
- type: string
enum:
- fr_code_postal
- type: string
enum:
- au_postcode
- type: string
enum:
- ch_plz
- type: string
enum:
- at_plz
values:
type: array
items:
type: stri
# --- truncated at 32 KB (1110 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/scope3/refs/heads/main/openapi/scope3-product-discovery-api-openapi.yml