Create report query plans
/report-query-plansExplain a question: its SQL, plan and estimated cost. Nothing is run and nothing is stored.
Permissions
reports:queryRequires the `query` action on `reports` for the supplied runtime context
Request body
This body is a tagged shape: type is always "RqplanCmdExplain". Send it; more variants can be added, and a caller that switches on it keeps working when they are.
typetype = "RqplanCmdExplain"Ask a dataset a question. With measures, the answer is one row per combination of the dimensions and time buckets; with none, it is one row per record, in the dataset's row columns.
typeenumrequiredRqryCmdRunreportDatasetIdstringrequiredmeasuresarray of stringWhat to add up, by name from the dataset's measures.
dimensionsarray of stringWhat to group by, by name from the dataset's dimensions.
Bucket by time. Absent for a total over all time.
typeenumrequiredRqryTimeSliceAttributesgrainstringrequiredA grain the dataset offers, by name.
typeFrom one date to another, both inclusive, in the question's timezone.
fromstring (date)requiredExample 2026-08-19
tostring (date)requiredExample 2026-08-19
The current period of grain so far.
grainstringrequiredThe last count whole periods of grain before the current one, ending where it starts.
countinteger (int32)requiredExample 42
grainstringrequiredFrom startsAt up to but not including endsAt, exactly: the first and last buckets are cut at the period's ends rather than widened to whole buckets, so a statement cycle that starts at 16:00 starts there. Buckets are still local time in the question's timezone.
periodstringA period the dataset declares in its periods, such as a statement cycle, or absent for bounds the caller names alone.
startsAtstring (date-time)requiredExample 2026-08-19T04:21:07Z
endsAtstring (date-time)requiredExample 2026-08-19T04:21:07Z
The whole period of grain before the current one.
grainstringrequiredcompareRqryComparisonAlso answer for an earlier range, adding a previous column for each measure, and a change column for each but a date.
PreviousPeriodSamePeriodLastYearPreviousBucketUnknownEvery filter must hold. A value is written as text whatever the dimension's kind: 12.50, 2026-09-01.
typeKeeps every row whose value is above this one. Only a dimension whose operators lists Above takes it; a row with no value is not kept.
dimensionstringrequiredvaluestringrequireddimensionstringrequiredKeeps every row whose value is this one or above. Only a dimension whose operators lists AtLeast takes it; a row with no value is not kept.
dimensionstringrequiredvaluestringrequiredKeeps every row whose value is this one or below. Only a dimension whose operators lists AtMost takes it; a row with no value is not kept.
dimensionstringrequiredvaluestringrequiredKeeps every row whose value is below this one. Only a dimension whose operators lists Below takes it; a row with no value is not kept.
dimensionstringrequiredvaluestringrequiredBoth ends inclusive.
dimensionstringrequiredfromstringrequiredtostringrequiredKeeps every row whose value holds this text, ignoring case. Only a dimension whose matchesText is true may be searched, and a search of a column needs a time slice to bound the rows it tests.
dimensionstringrequiredtextstringrequireddimensionstringrequiredvaluestringrequireddimensionstringrequiredvaluesarray of stringKeeps every row whose value is not this one, including a row with no value.
dimensionstringrequiredvaluestringrequiredKeeps every row whose value is none of these, including a row with no value.
dimensionstringrequiredvaluesarray of stringtypedimensionstringrequiredascendingbooleanrequiredExample true
Orders by the measure. A money measure in several currencies, the question grouping by its currency, is ordered by currency first and by amount within each currency, since amounts in different currencies are no one scale.
measurestringrequiredascendingbooleanrequiredExample true
ascendingbooleanrequiredExample true
limitinteger (int32)At most this many rows.
Example 25
pagestringnext from the previous answer, to continue the same row-mode question. It is opaque and forward only, and a question changed in anything but limit refuses it with 400.
segmentsarray of stringNamed filters from the dataset's segments, applied as well as filters.
Every one must hold of a group for it to be kept, tested after grouping. Each names one of measures; a value is a decimal written as text. Absent for none.
typemeasurestringrequiredvaluestringrequiredmeasurestringrequiredvaluestringrequiredmeasurestringrequiredvaluestringrequiredmeasurestringrequiredvaluestringrequiredmeasurestringrequiredvaluestringrequiredKeep only the values of one dimension with the most of a measure, and fold the rest into an Others row.
typeenumrequiredRqryTopAttributesdimensionstringrequiredOne of the question's dimensions, whose values are ranked.
countinteger (int32)requiredHow many values to keep, from 1 to 100, within each combination of the other dimensions.
Example 42
measurestringrequiredOne of the question's measures, largest first, summed over the whole range.
Ask as tenants beneath the caller, as a marketplace views a report as some of its merchants. Every tenant must be one the caller may read, and the answer stays within the caller's own tenants. Absent to ask as the caller.
typeOnly these customers.
customerIdsarray of CustIdrequiredExample cust_9f2Kd8QpLzXw
Only these enterprises.
enterpriseIdsarray of EntIdrequiredExample ent_9f2Kd8QpLzXw
Only these marketplaces.
marketplaceIdsarray of MktpIdrequiredExample mktp_9f2Kd8QpLzXw
Only these merchants.
merchantIdsarray of MchtIdrequiredExample mcht_9f2Kd8QpLzXw
asAtstring (date-time)Read each balance as at this instant: its latest snapshot before it, and every earlier one for a highest or lowest. Only balance measures have a value at an instant, and the question takes no time. Absent for all time.
Example 2026-08-19T04:21:07Z
Lay the answer out as a grid: rows and columns each name some of dimensions, together each of them once. The answer stays one row per cell of the grid, each row saying its level, with a total and, with subtotals, a subtotal per leading row dimension. Absent for none.
typeenumrequiredRqryPivotAttributesrowsarray of stringThe dimensions down the side, outermost first. The time bucket, when there is one, is always the first row key.
columnsarray of stringThe dimensions across the top. Each must have few values: together at most 50.
subtotalsbooleanrequiredAlso answer a subtotal for each leading prefix of rows. The grand total is always answered.
Example true
timezonestringThe timezone the question is answered in, an IANA name such as Australia/Perth or an offset such as +10:00, which keeps no daylight saving: where its buckets start, how its dates, periods and relative ranges are read, and which local day or hour a date part names. Absent for the asker's own, which the dataset's timezone gives: the timezone every active merchant the asker reads keeps, or the dataset's where they keep several.
curl -X POST https://api.tst.au.apgpay.dev/report-query-plans \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "RqplanCmdExplain",
"question": {
"type": "RqryCmdRun",
"reportDatasetId": "string",
"measures": [
"string"
],
"dimensions": [
"string"
],
"time": {
"type": "RqryTimeSliceAttributes",
"grain": "string",
"range": {
"type": "RqryRangeBetween",
"from": "2026-08-19",
"to": "2026-08-19"
},
"compare": "PreviousPeriod"
},
"filters": [
{
"type": "RqryFilterAbove",
"dimension": "string",
"value": "string"
}
],
"sort": [
{
"type": "RqrySortDimension",
"dimension": "string",
"ascending": true
}
],
"limit": 25,
"page": "string",
"segments": [
"string"
],
"measureFilters": [
{
"type": "RqryMeasureFilterAbove",
"measure": "string",
"value": "string"
}
],
"top": {
"type": "RqryTopAttributes",
"dimension": "string",
"count": 42,
"measure": "string"
},
"narrowTo": {
"type": "RqryNarrowCustomers",
"customerIds": [
"cust_9f2Kd8QpLzXw"
]
},
"asAt": "2026-08-19T04:21:07Z",
"pivot": {
"type": "RqryPivotAttributes",
"rows": [
"string"
],
"columns": [
"string"
],
"subtotals": true
},
"timezone": "string"
}
}'Responses
The response is a tagged shape: type is always "RqplanCreateRspAttributes". Switch on it; subtypes can be added, and a client that already reads it will not break.
typetype = "RqplanCreateRspAttributes"The resource that was created.
typeenumrequiredRqplanAttributessqlstringrequiredThe statement as it runs, its values bound as ? parameters.
planstringrequiredrollup, a rollup alone; split, a rollup and then the live view; lambda, the wide table and then the live view; view, the live view alone.
estimatedCostnumber (double)Example 12.5
sourcesarray of stringtimezonestringrequiredThe timezone the question would be answered in, an IANA name or an offset.
The pre-summed table the plan reads, with the grain and timezone it was summed at. Absent for a plan that reads none.
typeenumrequiredRqplanRollupAttributesrelationstringrequiredgrainstringrequiredtimezonestringrequiredThe IANA timezone its buckets were summed in: UTC for the half-hour rollup, which serves every timezone whose offsets are whole half hours.
resolvedSqlstringThe statement with every value written in as a Postgres literal (the tenant scope, range bounds, filter values, timezone and limits), in a read-only transaction that publishes the scope and timezone the views read and is rolled back, ready to paste into psql. Absent when a value has no literal written for it. It holds tenant ids and filter values, so treat it as the data it reads.
The same question as if no cube served it, read straight from its analytics view at the same scope, narrowing and timezone: what the cube saves it. It is explained, never run.
typeThe question read straight from its analytics view, which differs from the plan as run.
sqlstringrequiredThe statement, its values bound as ? parameters.
resolvedSqlstringThe statement with every value written in as a Postgres literal (the tenant scope, range bounds, filter values, timezone and limits), in a read-only transaction that publishes the scope and timezone the views read and is rolled back, ready to paste into psql. Absent when a value has no literal written for it. It holds tenant ids and filter values, so treat it as the data it reads.
estimatedCostnumber (double)Example 12.5
sourcesarray of stringThe question already reads its analytics view alone, so the plan as run is the plan without the cube.
planstringrequiredThe plan as run, view.
{
"type": "RqplanCreateRspAttributes",
"created": {
"type": "RqplanAttributes",
"sql": "string",
"plan": "string",
"estimatedCost": 12.5,
"sources": [
"string"
],
"timezone": "string",
"rollup": {
"type": "RqplanRollupAttributes",
"relation": "string",
"grain": "string",
"timezone": "string"
},
"resolvedSql": "string",
"withoutCube": {
"type": "RqplanWithoutCubeExplained",
"sql": "string",
"resolvedSql": "string",
"estimatedCost": 12.5,
"sources": [
"string"
]
}
}
}Error responses
statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}statusCodeinteger (int32)requiredHTTP status code for this error
errorCodestringrequiredAn APG Pay code providing a brief explanation of the underlying error. Use this if you wish to provide custom behaviour based on the error type.
messagestringrequiredHuman readable description of the error
tracerstringAn unique identifier for the request. Provide this to the support team if you wish to query a particular error.
detailstringOptional additional details for the error.
errorTypeDescriptionstringA description of the category of errors for the given statusCode.
metadataobjectOptional key value list of metadata
{
"statusCode": 100,
"errorCode": "string",
"message": "string",
"tracer": "string",
"detail": "string",
"errorTypeDescription": "string"
}