{
  "info": {
    "name": "Disco Channel Reporting API V2",
    "description": "- Endpoint: `GET /discobeat/reporting/v2/report/`\n- Base URL: `https://api.disconetwork.com`\n- Auth: Channel Management API secret key in `X-API-Key`.\n- Channel scope comes from the key and query parameters cannot override it.\n- Supply `from` and `to` together or omit both.\n- No-date non-hourly reports use the latest seven UTC dates in the reporting window.\n- No-date hourly reports use up to three UTC dates in the hourly reporting window.\n- UTC rules: query dates and `period_start` are inclusive, while `period_end` is exclusive.\n- Weeks start Monday and partial week or month periods are clipped.\n- Non-hourly ranges must fit available reporting history.\n- Hourly ranges allow up to three inclusive dates.\n- 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`, `ctr`, `cvr`, `rpl`, `attributed_cpa`.\n- Omitted metrics use enabled values in the listed order.\n- A documented metric may be disabled and return `METRIC_NOT_AVAILABLE`.\n- Contact Disco when `METRIC_NOT_AVAILABLE` is returned.\n- Formulas: `ctr = clicks / impressions`, `cvr = conversions / clicks`, `rpl = channel_payout / feed_loads`, `attributed_cpa = attributed_ad_spend_amount / conversions`.\n- Calculated metrics use aggregated totals, four decimal places, and `0.0` for zero denominators.\n- Time grains: `total`, `day`, `week`, `month`, `hour`.\n- Group by up to three keys from `publisher`, `page_type`, `widget_type`, and `widget_id`.\n- The `publisher` grouping adds `publisher_id` and `publisher_name`.\n- Filters accept up to 250 publisher IDs, page types, or widget types without adding columns. `MODAL` activity is excluded.\n- Sort defaults to `period_start` in descending order and precedes pagination.\n- Pagination defaults to offset `0` and limit `50`, with a maximum limit of `250`.\n- Results are capped at 10,000 rows and summary covers all matches before pagination.\n- JSON includes `data`, `summary`, `pagination`, and `meta`.\n- `data_through` is the latest available data period, shown by its UTC start time. It is not a refresh time.\n- Empty matches return `200` with empty `data` and zero-valued selected summary metrics.\n- Malformed or unknown parameters, unpaired dates, empty lists, and duplicate or unsupported metrics or groupings return field-keyed `400` errors.\n- `DATE_RANGE_OUTSIDE_AVAILABLE_WINDOW` may include `available_window`.\n- Operational errors: `METRIC_NOT_AVAILABLE`, `REPORTING_DATA_UNAVAILABLE`, `DATE_RANGE_OUTSIDE_AVAILABLE_WINDOW`, `REPORT_ROW_LIMIT_EXCEEDED`, `REPORTING_SOURCE_ROW_LIMIT_EXCEEDED`.\n- Authentication errors return `401` and non-GET methods return `405`.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-API-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.disconetwork.com",
      "type": "string"
    },
    {
      "key": "api_key",
      "value": "",
      "type": "string",
      "description": "Channel Management API secret key."
    },
    {
      "key": "date_from",
      "value": "2026-07-18",
      "type": "string"
    },
    {
      "key": "date_to",
      "value": "2026-07-20",
      "type": "string"
    },
    {
      "key": "publisher_id",
      "value": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Report \u2014 default latest window",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{base_url}}/discobeat/reporting/v2/report/",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "discobeat",
            "reporting",
            "v2",
            "report",
            ""
          ]
        },
        "description": "Returns the default total report for the latest seven UTC dates in the reporting window."
      },
      "response": [
        {
          "name": "200 default report",
          "status": "OK",
          "code": 200,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"data\": [\n    {\n      \"period_start\": \"2026-07-14T00:00:00Z\",\n      \"period_end\": \"2026-07-21T00:00:00Z\",\n      \"impressions\": 84000,\n      \"clicks\": 1680,\n      \"conversions\": 420,\n      \"channel_payout\": 12500.0,\n      \"revenue_with_email\": 9600.0,\n      \"revenue_without_email\": 2900.0,\n      \"feed_loads\": 100000,\n      \"widget_displays\": 95000,\n      \"viewable_widget_displays\": 82000,\n      \"order_revenue_amount\": 63000.0,\n      \"attributed_ad_spend_amount\": 16800.0,\n      \"billable_ad_spend_amount\": 16500.0,\n      \"ctr\": 0.02,\n      \"cvr\": 0.25,\n      \"rpl\": 0.125,\n      \"attributed_cpa\": 40.0\n    }\n  ],\n  \"summary\": {\n    \"impressions\": 84000,\n    \"clicks\": 1680,\n    \"conversions\": 420,\n    \"channel_payout\": 12500.0,\n    \"revenue_with_email\": 9600.0,\n    \"revenue_without_email\": 2900.0,\n    \"feed_loads\": 100000,\n    \"widget_displays\": 95000,\n    \"viewable_widget_displays\": 82000,\n    \"order_revenue_amount\": 63000.0,\n    \"attributed_ad_spend_amount\": 16800.0,\n    \"billable_ad_spend_amount\": 16500.0,\n    \"ctr\": 0.02,\n    \"cvr\": 0.25,\n    \"rpl\": 0.125,\n    \"attributed_cpa\": 40.0\n  },\n  \"pagination\": {\n    \"offset\": 0,\n    \"limit\": 50,\n    \"total\": 1,\n    \"has_more\": false\n  },\n  \"meta\": {\n    \"timezone\": \"UTC\",\n    \"data_through\": \"2026-07-20T00:00:00Z\",\n    \"request_id\": \"736e3ad7-5f9e-426a-b55a-7222963014f8\"\n  }\n}"
        }
      ]
    },
    {
      "name": "Report \u2014 daily by publisher and widget",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{base_url}}/discobeat/reporting/v2/report/?from={{date_from}}&to={{date_to}}&metrics=impressions,clicks,conversions,channel_payout,feed_loads,attributed_ad_spend_amount,ctr,cvr,rpl,attributed_cpa&time_grain=day&group_by=publisher,widget_type&sort_order=desc&sort_by=impressions&sort_direction=desc&page_types=ORDER_TRACKING,THANK_YOU&offset=0&limit=50",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "discobeat",
            "reporting",
            "v2",
            "report",
            ""
          ],
          "query": [
            {
              "key": "from",
              "value": "{{date_from}}",
              "description": "First inclusive UTC date paired with `to`."
            },
            {
              "key": "to",
              "value": "{{date_to}}",
              "description": "Last inclusive UTC date that is not in the future."
            },
            {
              "key": "metrics",
              "value": "impressions,clicks,conversions,channel_payout,feed_loads,attributed_ad_spend_amount,ctr,cvr,rpl,attributed_cpa",
              "description": "Unique comma-separated metrics set response order and may be disabled for this channel."
            },
            {
              "key": "time_grain",
              "value": "day",
              "description": "UTC period grain with `total` as the default."
            },
            {
              "key": "group_by",
              "value": "publisher,widget_type",
              "description": "Accepts up to three unique grouping keys. `publisher` adds `publisher_id` and `publisher_name`."
            },
            {
              "key": "sort_order",
              "value": "desc",
              "description": "Use `desc` for latest first or `asc` for oldest first."
            },
            {
              "key": "sort_by",
              "value": "impressions",
              "description": "Sorts by a selected metric, grouping field, or `period_start`."
            },
            {
              "key": "sort_direction",
              "value": "desc",
              "description": "Uses `asc` or `desc` and defaults to `sort_order`."
            },
            {
              "key": "publisher_ids",
              "value": "{{publisher_id}}",
              "description": "Filters publisher UUIDs without adding columns.",
              "disabled": true
            },
            {
              "key": "page_types",
              "value": "ORDER_TRACKING,THANK_YOU",
              "description": "Filters page types without adding columns. `MODAL` activity is excluded."
            },
            {
              "key": "widget_types",
              "value": "APP_NATIVE_ESSENTIAL",
              "description": "Filters widget types without adding columns.",
              "disabled": true
            },
            {
              "key": "offset",
              "value": "0",
              "description": "Default 0."
            },
            {
              "key": "limit",
              "value": "50",
              "description": "Default 50, maximum 250."
            }
          ]
        },
        "description": "Returns daily publisher and widget rows. Row ratios use row totals and summary ratios use summary totals."
      },
      "response": [
        {
          "name": "200 grouped report",
          "status": "OK",
          "code": 200,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"data\": [\n    {\n      \"period_start\": \"2026-07-18T00:00:00Z\",\n      \"period_end\": \"2026-07-19T00:00:00Z\",\n      \"publisher_id\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\",\n      \"publisher_name\": \"AfterShip Tracking Page\",\n      \"widget_type\": \"APP_NATIVE_ESSENTIAL\",\n      \"impressions\": 42000,\n      \"clicks\": 840,\n      \"conversions\": 210,\n      \"channel_payout\": 6250.0,\n      \"feed_loads\": 50000,\n      \"attributed_ad_spend_amount\": 8400.0,\n      \"ctr\": 0.02,\n      \"cvr\": 0.25,\n      \"rpl\": 0.125,\n      \"attributed_cpa\": 40.0\n    }\n  ],\n  \"summary\": {\n    \"impressions\": 42000,\n    \"clicks\": 840,\n    \"conversions\": 210,\n    \"channel_payout\": 6250.0,\n    \"feed_loads\": 50000,\n    \"attributed_ad_spend_amount\": 8400.0,\n    \"ctr\": 0.02,\n    \"cvr\": 0.25,\n    \"rpl\": 0.125,\n    \"attributed_cpa\": 40.0\n  },\n  \"pagination\": {\n    \"offset\": 0,\n    \"limit\": 50,\n    \"total\": 1,\n    \"has_more\": false\n  },\n  \"meta\": {\n    \"timezone\": \"UTC\",\n    \"data_through\": \"2026-07-20T00:00:00Z\",\n    \"request_id\": \"d719d46e-9540-4c5c-a711-6b4b50c25820\"\n  }\n}"
        }
      ]
    },
    {
      "name": "Report \u2014 hourly with three groupings",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{base_url}}/discobeat/reporting/v2/report/?from={{date_from}}&to={{date_to}}&metrics=impressions,clicks,ctr&time_grain=hour&group_by=page_type,widget_type,widget_id&sort_order=asc&offset=0&limit=250",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "discobeat",
            "reporting",
            "v2",
            "report",
            ""
          ],
          "query": [
            {
              "key": "from",
              "value": "{{date_from}}",
              "description": "First inclusive UTC date within the three-date hourly limit."
            },
            {
              "key": "to",
              "value": "{{date_to}}",
              "description": "Last inclusive UTC date within available hourly history."
            },
            {
              "key": "metrics",
              "value": "impressions,clicks,ctr",
              "description": "Unique comma-separated metrics in response order."
            },
            {
              "key": "time_grain",
              "value": "hour",
              "description": "Uses hourly UTC periods."
            },
            {
              "key": "group_by",
              "value": "page_type,widget_type,widget_id",
              "description": "Hourly reports support up to three groupings."
            },
            {
              "key": "sort_order",
              "value": "asc",
              "description": "Returns oldest periods first."
            },
            {
              "key": "offset",
              "value": "0",
              "description": "Skips zero sorted rows."
            },
            {
              "key": "limit",
              "value": "250",
              "description": "Returns up to 250 rows."
            }
          ]
        },
        "description": "Returns hourly rows for up to three inclusive UTC dates."
      },
      "response": [
        {
          "name": "200 hourly report",
          "status": "OK",
          "code": 200,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\n  \"data\": [\n    {\n      \"period_start\": \"2026-07-20T14:00:00Z\",\n      \"period_end\": \"2026-07-20T15:00:00Z\",\n      \"page_type\": \"ORDER_TRACKING\",\n      \"widget_type\": \"APP_NATIVE_ESSENTIAL\",\n      \"widget_id\": \"tracking-primary\",\n      \"impressions\": 3200,\n      \"clicks\": 64,\n      \"ctr\": 0.02\n    }\n  ],\n  \"summary\": {\n    \"impressions\": 3200,\n    \"clicks\": 64,\n    \"ctr\": 0.02\n  },\n  \"pagination\": {\n    \"offset\": 0,\n    \"limit\": 250,\n    \"total\": 1,\n    \"has_more\": false\n  },\n  \"meta\": {\n    \"timezone\": \"UTC\",\n    \"data_through\": \"2026-07-20T14:00:00Z\",\n    \"request_id\": \"83ca59d3-4bc6-4978-808b-a2d9ea542d28\"\n  }\n}"
        }
      ]
    },
    {
      "name": "Report \u2014 contract error examples",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{base_url}}/discobeat/reporting/v2/report/?from={{date_from}}",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "discobeat",
            "reporting",
            "v2",
            "report",
            ""
          ],
          "query": [
            {
              "key": "from",
              "value": "{{date_from}}",
              "description": "Intentionally unpaired to demonstrate date validation."
            }
          ]
        },
        "description": "Demonstrates paired-date validation with representative contract errors."
      },
      "response": [
        {
          "name": "400 paired dates",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"date_range\":[\"`from` and `to` must be provided together.\"]}"
        },
        {
          "name": "400 METRIC_NOT_AVAILABLE",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"code\":\"METRIC_NOT_AVAILABLE\",\"unsupported_metrics\":[\"billable_ad_spend_amount\"],\"allowed_metrics\":[\"impressions\",\"clicks\",\"conversions\",\"ctr\",\"cvr\"]}"
        },
        {
          "name": "400 REPORTING_DATA_UNAVAILABLE",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"code\":\"REPORTING_DATA_UNAVAILABLE\",\"message\":\"Reporting data is not available yet. Please try again later.\"}"
        },
        {
          "name": "400 DATE_RANGE_OUTSIDE_AVAILABLE_WINDOW",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"code\":\"DATE_RANGE_OUTSIDE_AVAILABLE_WINDOW\",\"message\":\"Reporting data is available from 2026-05-15 through 2026-07-20.\",\"available_window\":{\"from\":\"2026-05-15\",\"to\":\"2026-07-20\"}}"
        },
        {
          "name": "400 REPORT_ROW_LIMIT_EXCEEDED",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"code\":\"REPORT_ROW_LIMIT_EXCEEDED\",\"message\":\"Report exceeds the interactive row limit. Narrow the date range or remove one or more breakdowns.\",\"max_rows\":10000,\"total_rows\":12431}"
        },
        {
          "name": "400 REPORTING_SOURCE_ROW_LIMIT_EXCEEDED",
          "status": "Bad Request",
          "code": 400,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"code\":\"REPORTING_SOURCE_ROW_LIMIT_EXCEEDED\",\"message\":\"The requested historical report is too large. Choose a shorter date range or fewer breakdowns.\",\"max_source_rows\":\"100000\"}"
        },
        {
          "name": "401 invalid key",
          "status": "Unauthorized",
          "code": 401,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"detail\":\"Invalid or expired management API key.\"}"
        },
        {
          "name": "405 method",
          "status": "Method Not Allowed",
          "code": 405,
          "header": [
            {
              "key": "Content-Type",
              "value": "application/json"
            }
          ],
          "body": "{\"detail\":\"Method \\\"POST\\\" not allowed.\"}"
        }
      ]
    }
  ]
}
