Scope3 Measurement API
Measurement sources, records, context, and freshness
Measurement sources, records, context, and freshness
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/scope3-measurement-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Scope3 Buyer Measurement 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: Measurement
description: Measurement sources, records, context, and freshness
paths:
/advertisers/{advertiserId}/measurement-data/sync:
post:
operationId: syncMeasurementData
summary: Sync measurement data
description: Inbound sync_measurement_data endpoint. Advertisers or MMPs call this to provide performance data as an alternative to CAPI. Accepts time-series measurement data keyed by campaign, media buy, package, and/or creative.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SyncMeasurementDataRequest'
responses:
'200':
description: Sync measurement data
content:
application/json:
schema:
$ref: '#/components/schemas/SyncMeasurementDataResponse'
'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'
/advertisers/{advertiserId}/test-cohorts:
get:
operationId: listTestCohorts
summary: List test cohorts
description: List test cohorts for an advertiser.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: query
name: advertiserId
schema:
description: Filter by advertiser ID
example: '12345'
type: string
description: Filter by advertiser ID
- in: query
name: role
schema:
description: Filter by cohort role
type: string
enum:
- TREATMENT
- CONTROL
- OBSERVATION
description: Filter by cohort role
- in: query
name: isActive
schema:
description: Filter by active status
type: boolean
description: Filter by active status
- in: query
name: take
schema:
description: Number of results to return (max 250)
example: 50
default: 50
type: integer
maximum: 250
minimum: 1
description: Number of results to return (max 250)
- in: query
name: skip
schema:
description: Number of results to skip for pagination
example: 0
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
description: Number of results to skip for pagination
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
responses:
'200':
description: List test cohorts
content:
application/json:
schema:
$ref: '#/components/schemas/TestCohortListResponse'
'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: createTestCohort
summary: Create test cohort
description: Create a new test cohort for measurement.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateTestCohortInput'
responses:
'201':
description: Create test cohort
content:
application/json:
schema:
$ref: '#/components/schemas/TestCohortResponse'
'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'
/advertisers/{advertiserId}/test-cohorts/{cohortId}:
get:
operationId: getTestCohort
summary: Get test cohort
description: Get a specific test cohort by ID.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: cohortId
schema:
description: Unique identifier for the test cohort
example: cohort_abc123
type: string
minLength: 1
required: true
description: Unique identifier for the test cohort
responses:
'200':
description: Get test cohort
content:
application/json:
schema:
$ref: '#/components/schemas/TestCohortResponse'
'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'
put:
operationId: updateTestCohort
summary: Update test cohort
description: Update an existing test cohort.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: cohortId
schema:
description: Unique identifier for the test cohort
example: cohort_abc123
type: string
minLength: 1
required: true
description: Unique identifier for the test cohort
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateTestCohortInput'
responses:
'200':
description: Update test cohort
content:
application/json:
schema:
$ref: '#/components/schemas/TestCohortResponse'
'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: deleteTestCohort
summary: Delete test cohort
description: Delete a test cohort.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: cohortId
schema:
description: Unique identifier for the test cohort
example: cohort_abc123
type: string
minLength: 1
required: true
description: Unique identifier for the test cohort
responses:
'204':
description: No content
'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'
/advertisers/{advertiserId}/measurement-config:
get:
operationId: getMeasurementConfig
summary: Get measurement configuration
description: Get the measurement configuration for an advertiser.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
responses:
'200':
description: Get measurement configuration
content:
application/json:
schema:
$ref: '#/components/schemas/MeasurementConfigResponse'
'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'
put:
operationId: updateMeasurementConfig
summary: Update measurement configuration
description: Update the measurement configuration for an advertiser.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateMeasurementConfigInput'
responses:
'200':
description: Update measurement configuration
content:
application/json:
schema:
$ref: '#/components/schemas/MeasurementConfigResponse'
'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'
/advertisers/{advertiserId}/measurement-sources:
get:
operationId: listMeasurementSources
summary: List measurement sources
description: List measurement sources for an advertiser.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: query
name: take
schema:
description: Number of results to return (max 250)
example: 50
default: 50
type: integer
maximum: 250
minimum: 1
description: Number of results to return (max 250)
- in: query
name: skip
schema:
description: Number of results to skip for pagination
example: 0
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
description: Number of results to skip for pagination
- in: query
name: outcomeType
schema:
type: string
- in: query
name: status
schema:
type: string
enum:
- pending
- active
- paused
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
responses:
'200':
description: List measurement sources
'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: createMeasurementSource
summary: Create measurement source
description: Register a measurement data source (e.g. MMM, brand lift study) for an advertiser.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
sourceKey:
type: string
minLength: 1
name:
type: string
minLength: 1
outcomeType:
type: string
minLength: 1
outcomeTypes:
type: array
items:
type: string
granularity:
type: string
minLength: 1
lagWeeks:
default: 1
type: integer
minimum: 0
maximum: 9007199254740991
cadence:
type: string
enum:
- continuous
- daily
- weekly
- biweekly
- monthly
- quarterly
provider:
type: string
minLength: 1
ingestionMethod:
type: string
attributionConfig:
type: object
additionalProperties: {}
signalWeight:
default: 1
type: number
minimum: 0
maximum: 1
status:
default: pending
type: string
enum:
- pending
- active
- paused
notes:
type: string
required:
- sourceKey
- name
- outcomeType
- granularity
- cadence
- provider
responses:
'201':
description: Create measurement source
'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'
/advertisers/{advertiserId}/measurement-sources/{sourceId}:
get:
operationId: getMeasurementSource
summary: Get measurement source
description: Get a specific measurement source by ID.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
- in: path
name: sourceId
schema:
type: string
required: true
responses:
'200':
description: Get measurement source
'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'
patch:
operationId: updateMeasurementSource
summary: Update measurement source
description: Update a measurement source.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
- in: path
name: sourceId
schema:
type: string
required: true
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
minLength: 1
outcomeType:
type: string
minLength: 1
outcomeTypes:
type: array
items:
type: string
granularity:
type: string
minLength: 1
lagWeeks:
default: 1
type: integer
minimum: 0
maximum: 9007199254740991
cadence:
type: string
enum:
- continuous
- daily
- weekly
- biweekly
- monthly
- quarterly
provider:
type: string
minLength: 1
ingestionMethod:
type: string
attributionConfig:
type: object
additionalProperties: {}
signalWeight:
default: 1
type: number
minimum: 0
maximum: 1
status:
default: pending
type: string
enum:
- pending
- active
- paused
notes:
type: string
responses:
'200':
description: Update measurement source
'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'
/advertisers/{advertiserId}/measurement-records:
post:
operationId: uploadMeasurementRecords
summary: Upload measurement records
description: Upload outcome measurement records (sales, brand lift, etc). Upserts on (customer, advertiser, outcome_type, source, geo, time_window).
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
records:
minItems: 1
maxItems: 5000
type: array
items:
type: object
properties:
outcomeType:
type: string
minLength: 1
geo:
type: string
minLength: 1
timeWindowStart:
type: string
format: date
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])))$
timeWindowEnd:
type: string
format: date
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])))$
value:
type: number
baselineValue:
type: number
confidenceInterval:
type: number
source:
type: string
minLength: 1
lagDays:
type: integer
minimum: -9007199254740991
maximum: 9007199254740991
required:
- outcomeType
- geo
- timeWindowStart
- timeWindowEnd
- value
- source
required:
- records
responses:
'201':
description: Upload measurement records
'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'
get:
operationId: listMeasurementRecords
summary: List measurement records
description: List uploaded measurement records with optional filtering by outcome type and geo.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: query
name: take
schema:
description: Number of results to return (max 250)
example: 50
default: 50
type: integer
maximum: 250
minimum: 1
description: Number of results to return (max 250)
- in: query
name: skip
schema:
description: Number of results to skip for pagination
example: 0
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
description: Number of results to skip for pagination
- in: query
name: outcomeType
schema:
type: string
- in: query
name: geo
schema:
type: string
- in: query
name: geos
schema:
type: string
- in: query
name: startDate
schema:
type: string
format: date
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])))$
- in: query
name: endDate
schema:
type: string
format: date
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])))$
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
responses:
'200':
description: List measurement records
'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'
/advertisers/{advertiserId}/context-records:
post:
operationId: uploadContextRecords
summary: Upload context records
description: Upload exogenous context data (promos, weather, competitor activity) for measurement analysis.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: path
name: advertiserId
schema:
description: Unique identifier for the advertiser
example: '12345'
type: string
minLength: 1
required: true
description: Unique identifier for the advertiser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
records:
minItems: 1
maxItems: 5000
type: array
items:
type: object
properties:
geo:
type: string
minLength: 1
timeWindowStart:
type: string
format: date
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])))$
timeWindowEnd:
type: string
format: date
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])))$
promoActive:
default: false
type: boolean
promoType:
type: string
temperatureAvg:
type: number
competitorActivity:
type: object
additionalProperties: {}
seasonalityIndex:
type: number
flightStatus:
default: active
type: string
enum:
- active
- dark
- pre_flight
- post_flight
required:
- geo
- timeWindowStart
- timeWindowEnd
required:
- records
responses:
'201':
description: Upload context records
'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'
/advertisers/{advertiserId}/measurement-freshness:
get:
operationId: getMeasurementFreshness
summary: Check measurement freshness
description: Check for gaps in measurement data coverage relative to flight schedule and measurement source cadence.
tags:
- Measurement
security:
- bearerAuth: []
parameters:
- in: query
name: flightStart
schema:
type: string
format: date
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])))$
required: true
- in: query
name: flightEnd
schema:
type: string
format: date
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])))$
-
# --- truncated at 32 KB (50 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/scope3/refs/heads/main/openapi/scope3-measurement-api-openapi.yml