Skip to main content

Reporting API

Build flat, paginated reports with selectable metrics, UTC time grains, filters, and up to three breakdown columns. There are two Reporting APIs with the same request shape and response contract:

Channel Reporting V2Publisher Reporting V2
Who it's forDiscoBeat channel operators reporting across all their publishersA single publisher reporting on its own performance
Base URLhttps://api.disconetwork.comhttps://merchant.disconetwork.com/api
EndpointGET /discobeat/reporting/v2/report/GET /analysis/publisher-reporting/v2/report/
AuthenticationX-API-Key header with a Channel management secret keyX-API-Key header with a Publisher Reporting secret key
ScopeThe channel assigned to the key (no channel ID parameter is accepted)The publisher assigned to the key

Secret keys use the disco_sk_live_… prefix. Send requests from server-side code only, and ask your Disco contact for a key and the metrics enabled for you. Both APIs accept GET only.

Quickstart​

curl -G -H "X-API-Key: disco_sk_live_..." \
--data-urlencode "from=2026-07-18" \
--data-urlencode "to=2026-07-20" \
--data-urlencode "time_grain=day" \
--data-urlencode "group_by=publisher,page_type" \
--data-urlencode "metrics=impressions,clicks,conversions,channel_payout,ctr,cvr" \
--data-urlencode "sort_order=asc" \
"https://api.disconetwork.com/discobeat/reporting/v2/report/"

Import a Postman collection or OpenAPI spec and set the api_key variable to your key: Channel: Postman collection · OpenAPI spec · Publisher: Postman collection · OpenAPI spec

Shared contract​

Everything in this section applies to both APIs.

Dates and periods​

RuleContract
Date pairfrom and to are optional together; supplying only one returns 400
No datesNon-hourly requests use the latest 7 UTC dates in the reporting window
No hourly datesHourly requests use up to 3 UTC dates in the hourly reporting window
Query boundariesfrom and to are inclusive UTC calendar dates; to cannot be in the future
Response boundariesperiod_start is inclusive; period_end is exclusive
WeeksUTC weeks begin Monday; edge periods are clipped to the query
MonthsUTC calendar months; edge periods are clipped to the query

Time grains (time_grain, default total): total (one period for all matching activity), day, week (Monday-based), month, hour (maximum 3 inclusive dates).

Response shape​

FieldValue
dataPaginated flat rows with period, grouping, and selected metric fields
summarySelected metrics totalled across all matching rows, not just the page
paginationoffset, limit, total, has_more
metatimezone, data_through (latest available data period, shown by its UTC start time), request_id

data_through is the start of the latest available data period, not a refresh time. It's null when unavailable.

Rows are sorted by period_start in descending order by default, and sorting always precedes pagination (sort_order: desc latest-first, asc oldest-first; grouping values stay ascending). To page through results, add data.length to offset while pagination.has_more is true. A request with no matching activity returns 200 with empty data and zero-valued summary metrics.

Value rules and limits​

RuleContract
Zero denominatorCalculated metric is 0
Ratio precision4 decimal places (decimals, not percentages)
Monetary precision2 decimal places
Non-hourly rangeMust fit available reporting history
GroupingsUp to 3 unique values, on every time grain; multiple groupings return one row per observed combination
FiltersUp to 250 values per filter; a filtered dimension appears in data only when it's also in group_by
Result rows10,000 before pagination (REPORT_ROW_LIMIT_EXCEEDED)

Errors​

Status or codeCondition
400 validationMalformed or unknown parameters, unpaired dates, empty lists, duplicate or unsupported metrics or groupings
METRIC_NOT_AVAILABLEA requested metric isn't enabled for you; the response lists unsupported_metrics and allowed_metrics. Contact Disco to enable it
REPORTING_DATA_UNAVAILABLENo reporting data is available for your channel or publisher
DATE_RANGE_OUTSIDE_AVAILABLE_WINDOWDates are outside available history; the response may include available_window
REPORT_ROW_LIMIT_EXCEEDEDResult exceeds 10,000 rows before pagination
REPORTING_SOURCE_ROW_LIMIT_EXCEEDEDHistorical request is too large to process; shorten the date range or use fewer breakdowns
401Missing, invalid, public, revoked, or expired secret key
405Any method other than GET
400 application/json
{
"code": "METRIC_NOT_AVAILABLE",
"unsupported_metrics": ["channel_payout"],
"allowed_metrics": ["impressions", "clicks", "ctr"]
}

Channel Reporting V2​

GET https://api.disconetwork.com/discobeat/reporting/v2/report/

ParameterTypeDetails
from / todateInclusive UTC dates, YYYY-MM-DD, optional together (see Dates and periods)
metricslistComma-separated metric columns, in response order. Defaults to your channel's enabled metric set
time_grainstringtotal (default), day, week, month, hour
group_bylistUp to three of publisher, page_type, widget_type, widget_id. publisher adds publisher_id and publisher_name columns
sort_orderstringdesc (default) or asc
sort_bystringperiod_start (default), a selected metric, or a selected grouping field. Use publisher_name for the publisher grouping
sort_directionstringasc or desc. Defaults to sort_order
publisher_idslistFilter by publisher UUIDs, max 250; filters don't add columns
page_typeslistFilter by page types, max 250. MODAL activity is excluded
widget_typeslistFilter by widget types, max 250
offset / limitintegerPagination; limit 1 to 250, default 50

Measured metrics: impressions, clicks, conversions, channel_payout, revenue_with_email, revenue_without_email, feed_loads, widget_displays, viewable_widget_displays, order_revenue_amount, attributed_ad_spend_amount, billable_ad_spend_amount.

Calculated metrics:

MetricFormulaDefinition
ctrclicks / impressionsClick-through rate
cvrconversions / clicksChannel conversion rate
rplchannel_payout / feed_loadsPayout per feed load
attributed_cpaattributed_ad_spend_amount / conversionsAttributed cost per acquisition

A documented metric may not be enabled for every channel; conversions are Disco-attributed, so totals may differ from your own systems.

200 application/json (group_by=publisher,page_type · time_grain=day)
{
"data": [
{
"period_start": "2026-07-18T00:00:00Z",
"period_end": "2026-07-19T00:00:00Z",
"publisher_id": "9aa17f8c-7746-4218-9025-83d38c406179",
"publisher_name": "Example Publisher",
"page_type": "ORDER_TRACKING",
"impressions": 4584,
"clicks": 180,
"conversions": 46,
"channel_payout": 189.90,
"ctr": 0.0393,
"cvr": 0.2556
}
],
"summary": {
"impressions": 225072,
"clicks": 8928,
"conversions": 2234,
"channel_payout": 6546.24,
"ctr": 0.0397,
"cvr": 0.2502
},
"pagination": { "offset": 0, "limit": 50, "total": 36, "has_more": false },
"meta": {
"timezone": "UTC",
"data_through": "2026-07-20T00:00:00Z",
"request_id": "7e9fe348-7558-4e28-b8c6-b26ea44899eb"
}
}

Publisher Reporting V2​

GET https://merchant.disconetwork.com/api/analysis/publisher-reporting/v2/report/

For a single publisher reporting on its own performance, authenticated with a Publisher Reporting secret key.

ParameterTypeDetails
from / todateInclusive UTC dates, YYYY-MM-DD, optional together (see Dates and periods)
metricslistComma-separated metric columns, in response order. Defaults to all Publisher Reporting V2 metrics
time_grainstringtotal (default), day, week, month, hour
group_bylistUp to three of page_type, widget_type, widget_id
sort_orderstringdesc (default) or asc
page_typeslistFilter by page types, max 250. ORDER_TRACKING and MODAL are excluded
widget_typeslistFilter by widget types, max 250
offset / limitintegerPagination; limit 1 to 10,000, default 50

Measured metrics: publisher_payout, widget_loads, widget_displays, viewable_widget_displays, impressions, clicks, conversions.

Calculated metrics:

MetricFormulaDefinition
ctrclicks / impressionsClick-through rate
cvrconversions / widget_displaysPublisher conversion rate
curl -G -H "X-API-Key: disco_sk_live_..." \
--data-urlencode "from=2026-07-18" \
--data-urlencode "to=2026-07-20" \
--data-urlencode "time_grain=day" \
--data-urlencode "group_by=page_type,widget_type" \
--data-urlencode "metrics=publisher_payout,widget_loads,widget_displays,impressions,clicks,conversions,ctr,cvr" \
--data-urlencode "page_types=THANK_YOU,ORDER_STATUS" \
"https://merchant.disconetwork.com/api/analysis/publisher-reporting/v2/report/"
200 application/json (group_by=page_type,widget_type · time_grain=day)
{
"data": [
{
"period_start": "2026-07-18T00:00:00Z",
"period_end": "2026-07-19T00:00:00Z",
"page_type": "THANK_YOU",
"widget_type": "SHOPIFY_NATIVE_ESSENTIAL",
"publisher_payout": 20.00,
"widget_loads": 120,
"widget_displays": 100,
"impressions": 50,
"clicks": 5,
"conversions": 2,
"ctr": 0.1000,
"cvr": 0.0200
}
],
"summary": {
"publisher_payout": 61.75,
"widget_loads": 360,
"widget_displays": 300,
"impressions": 150,
"clicks": 15,
"conversions": 6,
"ctr": 0.1000,
"cvr": 0.0200
},
"pagination": { "offset": 0, "limit": 50, "total": 6, "has_more": false },
"meta": {
"timezone": "UTC",
"data_through": "2026-07-20T00:00:00Z",
"request_id": "cd292465-9007-44c3-b12c-773e941003fb"
}
}

Using V1?​

The V1 channel endpoints (/discobeat/reporting/v1/summary/ and /discobeat/reporting/v1/publishers/) keep working for existing integrations, but they're no longer documented here and new integrations should use V2. Contact your Disco representative if you're on V1 and need help migrating.

Need a key or help integrating?

Your Disco representative can issue a secret key and walk through the integration. Download the Channel or Publisher Postman collection to start testing right away.