Understanding reporting API payloads
Advanced Reporting via the List Report API
This page provides examples of how to construct API requests for complex reporting scenarios using the /api/repositories/{repository}/reporting/list
endpoint. The examples below demonstrate how to retrieve structured data through list-based reports, which allow for greater flexibility and API compatibility than matrix-based formats.
Because reports can contain nested data of arbitrary depth, there is no way to define the exact response structure at the documentation level. Instead, the payload itself contains information on the structure of the report data.
Example: Reporting on Process-to-Application Relationships
The report finds all process objects that have a supporting resource of the type “Application”, and then includes the entire list of objects that support these processes
Report Type: Generic List
Row Filter:
type=ObjectType.PROCESS and isSupportedBy.object.type=ObjectType.RESOURCE and isSupportedBy.object.resourceType.name="Application"
Properties:
isSupportedBy
This report can be run via the Ad-Hoc report endpoint at POST /api/repositories/{repository}/reporting/list
with the following Request Payload
{
"approvedOnly": true,
"filters": [
"type=ObjectType.PROCESS and ancestor.name=\"Supply Chain Operations\" and isSupportedBy.object.type=ObjectType.RESOURCE and isSupportedBy.object.resourceType.name=\"Application\""
],
"properties": ["isSupportedBy"]
}
Response Structure Overview
The response includes two main elements:
heading
: An array describing the structure of each row.body
: An array of rows, where each row is itself an array of values in the same order as defined inheading
.
Sample Heading
[
{ "name": "ID", "type": "Int32" },
{ "name": "name", "type": "NString" },
{
"name": "isSupportedBy",
"type": "IsSupportedBy",
"collectionType": "Set",
"heading": [
{ "name": "ID", "type": "Int32" },
{ "name": "name", "type": "NString" }
]
}
]
Corresponding body element
[
[
1,
"Process 1",
[
[2, "Application 1"],
[3, "Application 2"]
]
],
[
4,
"Process 2",
[
[5, "Application 3"],
[6, "Person 1"]
]
]
]
In the provided example, the heading
defines the structure of each row in the response. The first two entries in the heading
correspond to simple scalar fields: ID
(an integer) and name
(a string). The third entry, isSupportedBy
, is a collection (type Set
) with its own nested heading
, which specifies that each related object also has an ID
and name
. In the body
, each top-level row is an array where the first element (1
, 4
, etc.) maps to the process ID, the second to the process name ("Process 1"
, "Process 2"
), and the third is an array of supporting objects, each of which matches the nested heading by position: [2, "Application 1"]
, [3, "Application 2"]
, etc. This positional mapping ensures the client can reliably interpret the data structure without relying on property names in the payload.
The examples above include a breakdown of how the response heading
and body
arrays align, illustrating how each element in the body
corresponds to the structure defined in the heading
. This mapping can include nested heading
definitions, such as for relationships or collections of objects. This structure allows you to build client-side parsers that can work reliably with known report definitions, and also serves as a foundation for more dynamic reporting tools that can adapt to new or variable report configurations without hardcoding each field.
The report data is returned as arrays rather than named property objects to significantly reduce the payload size, especially for reports with many rows. This design improves performance and bandwidth efficiency when transferring or processing large result sets, which is common in analytical or batch reporting scenarios.
Further Reading
These examples are intended to help developers integrate dynamic reporting features using the list report API. For complex cases or advanced patterns not covered here, feel free to reach out through your support channel.