Skip to main content

Synchronous Reports Quick Start

Some reports can be retrieved synchronously — instead of creating a report, waiting for it to finish, and downloading a file, you request the results directly and receive the rows in the API response, a page at a time. This guide walks through that synchronous workflow.

note

Synchronous reporting is only available to accounts that have access to the synchronous reports functionality, and only report definitions that support the synchronous (SYNC) flow are returned. For file-based (asynchronous) reports, see the Reports Quick Start.

Authentication

All requests are made against the base URL https://insights.bandwidth.com/api. Authenticate each request with a Bearer token:

Authorization: Bearer <token>

HTTP Basic authentication (username:password) is also supported.

The synchronous workflow

The synchronous flow uses the v2 Reporting endpoints (/v2/report-definitions) — these are separate from the /v1/reports endpoints used for the asynchronous, file-based flow in the Reports Quick Start.

  1. List report definitions to discover which synchronous reports you can run and get each report's reportDefinitionId.
  2. Get a report definition to inspect its filters, operators, value types, required parameters, and output fields.
  3. Generate results by posting your query criteria, and page through the response.

Step 1: List report definitions

Use Get Report Definitions to list the synchronous report definitions available to your accounts. Narrow the list with the category, domain, and reportName query parameters, and page through it with the offset and limit query parameters. The page object in the response reports the pagination metadata (pageSize, totalElements, totalPages, pageNumber) for the returned page.

GET /v2/report-definitions?category=USAGE&domain=VOICE

Each item is a full report definition: its id (the reportDefinitionId), category, domain, name, description, the regions it covers, maxMonthsBack, the filters it accepts, the outputFields returned in each result row, and the supportedModes (execution flows) it supports.

{
"links": [],
"data": {
"reportDefinitions": [
{
"id": "6d4f848a-9543-4e18-b580-2621c9525892",
"category": "USAGE",
"domain": "VOICE",
"reportName": "Call Detail Records (CDRs)",
"description": "Call Detail Records (CDRs) provides details for all the Voice calls associated with your account. Data may be delayed by a few hours.",
"regions": ["US", "EU"],
"maxMonthsBack": 12,
"filters": [
{
"filterName": "accountIds",
"validationType": "INTEGER",
"operator": "IN",
"required": true
},
{
"filterName": "callInviteTime",
"validationType": "ISO8601",
"operator": "GREATER_OR_EQUAL",
"required": true
},
{
"filterName": "callInviteTime",
"validationType": "ISO8601",
"operator": "LESSER_OR_EQUAL",
"required": true
},
{
"filterName": "callDirection",
"operator": "EQUAL",
"required": false,
"allowedValues": ["inbound", "outbound"]
}
],
"outputFields": [
{ "fieldName": "customerId", "fieldType": "STRING" },
{ "fieldName": "callDate", "fieldType": "STRING" },
{ "fieldName": "callId", "fieldType": "STRING" },
{ "fieldName": "callStartTime", "fieldType": "STRING" },
{ "fieldName": "duration", "fieldType": "INTEGER" },
{ "fieldName": "result", "fieldType": "STRING" },
{
"fieldName": "destinationPhoneNumber",
"fieldType": "STRING"
},
{ "fieldName": "sourcePhoneNumber", "fieldType": "STRING" }
],
"supportedModes": ["SYNC"]
}
]
},
"page": {
"pageSize": 50,
"totalElements": 1,
"totalPages": 1,
"pageNumber": 0
},
"errors": []
}

Step 2: Get a report definition

Use Get Report Definition with the reportDefinitionId to retrieve the full definition. The response contains everything needed to build a results request: the regions the report covers, its maxMonthsBack, the complete list of filter parameters — each with its supported operators, value type, and whether it is required — and the output fields returned in each result row.

GET /v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892
{
"links": [
{
"rel": "self",
"href": "https://insights.bandwidth.com/api/v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892"
}
],
"data": {
"id": "6d4f848a-9543-4e18-b580-2621c9525892",
"category": "USAGE",
"domain": "VOICE",
"reportName": "Call Detail Records (CDRs)",
"description": "Call Detail Records (CDRs) provides details for all the Voice calls associated with your account. Data may be delayed by a few hours.",
"regions": ["US", "EU"],
"maxMonthsBack": 12,
"filters": [
{
"filterName": "accountIds",
"validationType": "INTEGER",
"operator": "IN",
"required": true
},
{
"filterName": "callInviteTime",
"validationType": "ISO8601",
"operator": "GREATER_OR_EQUAL",
"required": true
},
{
"filterName": "callInviteTime",
"validationType": "ISO8601",
"operator": "LESSER_OR_EQUAL",
"required": true
},
{
"filterName": "callDirection",
"operator": "EQUAL",
"required": false,
"allowedValues": ["inbound", "outbound"]
}
],
"outputFields": [
{ "fieldName": "customerId", "fieldType": "STRING" },
{ "fieldName": "callDate", "fieldType": "STRING" },
{ "fieldName": "callId", "fieldType": "STRING" },
{ "fieldName": "callStartTime", "fieldType": "STRING" },
{ "fieldName": "duration", "fieldType": "INTEGER" },
{ "fieldName": "result", "fieldType": "STRING" },
{ "fieldName": "destinationPhoneNumber", "fieldType": "STRING" },
{ "fieldName": "sourcePhoneNumber", "fieldType": "STRING" }
],
"supportedModes": ["SYNC"]
},
"errors": []
}

Understanding filters

Each entry in filters tells you how to build a criterion for Step 3:

  • filterName — the parameter name to use in the queryCriteria request body.
  • operator — the operator to use for that criterion (for example IN, EQUAL, GREATER_OR_EQUAL, LESSER_OR_EQUAL). A filter can appear more than once with different operators — for example callInviteTime is listed with both GREATER_OR_EQUAL and LESSER_OR_EQUAL, which together let you request a time range (see Step 3).
  • required — when true, the criterion must be supplied. In the example above, accountIds and callInviteTime are required.
  • How the value is validated — a filter is one of two shapes:
    • Enumerated — includes an allowedValues list; the value you supply must be one of those values (e.g. callDirection accepts inbound or outbound).
    • Validation-type — includes a validationType (e.g. INTEGER, ISO8601, STRING) and optionally a validationRegex; the value you supply must match that type/pattern.

Understanding output fields

outputFields describes every field returned in each result row from Step 3. Each entry has a fieldName (the key in the result row) and a fieldType (for example STRING, INTEGER). Use this to know which columns to expect and how to parse them.

If the report covers more than one region (see regions), you must also supply a region criterion when requesting results.

Step 3: Generate report results

Use Generate Report Results to run the report and get its rows synchronously. Supply your filters in the queryCriteria array — each criterion has a parameter, an operator, and a values array. At least one criterion is required. Control paging with pageSize and pageNumber.

POST /v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892/results
{
"queryCriteria": [
{
"parameter": "region",
"operator": "EQUAL",
"values": ["US"]
},
{
"parameter": "accountIds",
"operator": "IN",
"values": ["9900000", "9900001"]
},
{
"parameter": "callInviteTime",
"operator": "GREATER_OR_EQUAL",
"values": ["2026-01-01T00:00:00.000Z"]
},
{
"parameter": "callInviteTime",
"operator": "LESSER_OR_EQUAL",
"values": ["2026-01-31T23:59:59.999Z"]
},
{
"parameter": "callDirection",
"operator": "EQUAL",
"values": ["inbound"]
}
],
"pageSize": 50,
"pageNumber": 0
}

The response returns the result rows in data.results, pagination metadata in page, and HATEOAS links you can follow to page through the full result set.

{
"links": [
{
"rel": "self",
"href": "https://insights.bandwidth.com/api/v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892/results",
"method": "POST"
},
{
"rel": "first",
"href": "https://insights.bandwidth.com/api/v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892/results",
"method": "POST"
},
{
"rel": "last",
"href": "https://insights.bandwidth.com/api/v2/report-definitions/6d4f848a-9543-4e18-b580-2621c9525892/results",
"method": "POST"
}
],
"data": {
"results": [
{
"customerId": "1234567",
"callDate": "2024-01-15",
"callId": "1234567890abcdefghijklmnopqrstuvwxyz",
"callStartTime": "2024-01-15T17:05:48.960Z",
"duration": 120,
"result": "COMPLETED",
"destinationPhoneNumber": "+15554443333",
"sourcePhoneNumber": "+15554442222"
}
]
},
"page": {
"pageSize": 50,
"totalElements": 1,
"totalPages": 1,
"pageNumber": 0
},
"errors": []
}

The fields in each result row vary by report — the exact set is described by the outputFields in the report definition from Step 2.

Paging through results

To retrieve the next page, either follow the pagination links in the response, or repeat the request with an incremented pageNumber. Use page.totalPages and page.totalElements to know how many pages are available.

Next steps