AggregationExecute
Quick Links
Accounts Accounting Entries Products Customers Sales quotes Sales invoices Suppliers Purchase invoicesDescription
The aggregationExecute operation executes an aggregation based strictly on the definitions returned by aggregationCatalog.
This operation does not require any knowledge of the underlying business queries.
Instead, it relies entirely on the metadata exposed by the catalog.
Most parameters provided to this operation must come from the values returned by aggregationCatalog.
This guarantees:
- valid aggregation parameters
- consistent grouping and filtering
- safe execution without invalid fields
- the ability to build aggregations dynamically without prior API knowledge
Sample of result
Thanks to the Aggregation API, this result is obtained with a single call to aggregationExecute, using only a few parameters:
- an aggregation scope (entityKey =
queryAggregateSalesInvoices) - a date range (dateMin =
2025-01-01, dateMax =2026-12-31) - a grouping (groupByName =
Customer) - an aggregation (aggregationType =
SUM) - a period definition (periodType =
Year) - a comparison flag (compare =
true) - and a Top N limitation (top =
5)
The engine automatically handles:
- period comparison (N / N-1)
- ranking
- grouping
- percentage evolution calculation
The result shows, for each customer in the Top 5, the values for both periods and the percentage evolution.
| Rank | Customer Code | Customer Name | Period N | Period N-1 | Total Net (N) | Total Net (N-1) | Δ % |
|---|---|---|---|---|---|---|---|
| 1 | OPALE | Opale | 2026 | 2025 | 28,570 | 28,970 | 🔻 -1.38% |
| 2 | RUBIS | Rubis sur ongle | 2026 | 2025 | 14,364 | 342 | 🚀 +4100% |
| 3 | CARAT | Carat S.a.r.l | 2026 | 2025 | 12,800 | 24,100 | 🔻 -46.89% |
| 4 | BAGUES | Bague’s en or 13 | 2026 | 2025 | 7,950 | 5,750 | 🔺 +38.26% |
| 5 | DUPOND | Dupond INC | 2026 | 2025 | 7,000 | 7,000 | ➖ 0% |
Functionality
- Execute aggregations across Accounting, Sales, and Purchases
- Group data dynamically
- Apply predefined business filters
- Aggregate one or two value columns
- Perform distinct counts
- Compare periods automatically
- Limit results using Top N and Others logic
Important principle
aggregationExecute must always be used after calling aggregationCatalog
The catalog defines the exact allowed values for:
- entityKey
- aggregationType
- periodType
- filterName
- groupByName
- valueColumn1, valueColumn2
- distinctCountName
If a value is not present in aggregationCatalog, it is invalid for aggregationExecute.
Result limits
The number of rows returned by aggregationExecute is intentionally limited to a maximum of 500 results.
This operation is designed for analytical aggregations, not for data browsing.
- grouping dimensions
- Top N logic
- business filters
- time periods
As a consequence:
- pagination is not supported
- returning more than 500 rows would indicate a misuse of the aggregation endpoint
- for large datasets or record-level access, list-based APIs must be used instead
Header
| Key | Value |
|---|---|
Authorization |
Bearer Current access Token How to find? |
X-TenantId |
Current tenant id Why deprecated ? |
X-OrganizationId |
Current organization Id How to find? |
x-api-key |
Primary or secondary subscription key of your app How to find? |
How to execute an aggregation using the Aggregation API?
GraphQL query
query ($input: AggregationExecuteDtoInput!) {
aggregationExecute(input: $input) {
meta {
entityKey
context
aggregationType
periodType
dateMin
dateMax
compare
top
includeOthers
othersLabel
filterName
groupByName
valueColumn1
valueColumn2
distinctCountName
search
searchScope
}
rows {
groupValue
secondValue
period
value1
value2
periodN
periodN_1
valueN
valueN_1
deltaPercent
}
}
}
Example Variables
{
"input": {
"entityKey": "queryAggregateSalesInvoices",
"aggregationType": "SUM",
"periodType": "Month",
"dateMin": "2025-01-01",
"dateMax": "2025-12-31",
"compare": false,
"top": 5,
"includeOthers": false,
"othersLabel": "Others",
"filterName": "All Customers",
"groupByName": "Customer",
"valueColumn1": "Total Net",
"valueColumn2": "Total Liquid",
"distinctCountName": "Sales Invoices"
}
}
Example Response
{
"meta": {
"entityKey": "queryAggregateSalesInvoices",
"context": "Sales Invoices by Customer",
"aggregationType": "SUM",
"periodType": "Year",
"dateMin": "2025-01-01",
"dateMax": "2025-12-31",
"compare": false,
"top": 5,
"includeOthers": false,
"othersLabel": "Others",
"filterName": "All Customers",
"groupByName": "Customer",
"valueColumn1": "Total Net",
"valueColumn2": "Total Liquid",
"distinctCountName": "Sales Invoices",
"search":null,
"searchScope":null
},
"rows": [
{
"groupValue": "1",
"secondValue": "Customer Demo",
"period": "2025",
"value1": 54917,
"value2": 65900.4,
"periodN": null,
"periodN_1": null,
"valueN": null,
"valueN_1": null,
"deltaPercent": null
},
{
"groupValue": "ANDERSSON",
"secondValue": "Andersson AB",
"period": "2025",
"value1": 35200,
"value2": 35200,
"periodN": null,
"periodN_1": null,
"valueN": null,
"valueN_1": null,
"deltaPercent": null
},
{
"groupValue": "OPALE",
"secondValue": "Opale",
"period": "2025",
"value1": 28970,
"value2": 28970,
"periodN": null,
"periodN_1": null,
"valueN": null,
"valueN_1": null,
"deltaPercent": null
},
{
"groupValue": "CARAT",
"secondValue": "Carat S.a.r.l",
"period": "2025",
"value1": 24100,
"value2": 28920,
"periodN": null,
"periodN_1": null,
"valueN": null,
"valueN_1": null,
"deltaPercent": null
},
{
"groupValue": "DUPOND",
"secondValue": "Dupond INC",
"period": "2025",
"value1": 7000,
"value2": 7000,
"periodN": null,
"periodN_1": null,
"valueN": null,
"valueN_1": null,
"deltaPercent": null
}
]
}
| Rank | Customer Code | Customer Name | Period | Total Net | Total Liquid |
|---|---|---|---|---|---|
| 1 | 1 | Customer Demo | 2025 | 54 917 | 65 900 |
| 2 | ANDERSSON | Andersson AB | 2025 | 35 200 | 35 200 |
| 3 | OPALE | Opale | 2025 | 28 970 | 28 970 |
| 4 | CARAT | Carat S.a.r.l | 2025 | 24 100 | 28 920 |
| 5 | DUPOND | Dupond INC | 2025 | 7 000 | 7 000 |
By simply setting includeOthers to true, the API automatically adds an additional row that represents the revenue of all customers outside the Top 5.
The Others row is automatically calculated by the engine and represents the aggregated totals of all remaining customers not included in the Top N.
| Rank | Customer Code | Customer Name | Period | Total Net | Total Liquid |
|---|---|---|---|---|---|
| 1 | 1 | Customer Demo | 2025 | 54 917 | 65 900 |
| 2 | ANDERSSON | Andersson AB | 2025 | 35 200 | 35 200 |
| 3 | OPALE | Opale | 2025 | 28 970 | 28 970 |
| 4 | CARAT | Carat S.a.r.l | 2025 | 24 100 | 28 920 |
| 5 | DUPOND | Dupond INC | 2025 | 7 000 | 7 000 |
| — | Others | 13 875 | 16 650 |
With compare = true and a date range covering two full years, the engine automatically compares:
- Period N → the most recent period inside the range
- Period N-1 → the equivalent previous period
The result shows, for each customer in the Top 5, the values for both periods and the percentage evolution.
| Rank | Customer Code | Customer Name | Period N | Period N-1 | Total Net (N) | Total Net (N-1) | Δ % |
|---|---|---|---|---|---|---|---|
| 1 | OPALE | Opale | 2026 | 2025 | 28 570 | 28 970 | 🔻 -1.38% |
| 2 | RUBIS | Rubis sur ongle | 2026 | 2025 | 14 364 | 342 | 🚀 +4100% |
| 3 | CARAT | Carat S.a.r.l | 2026 | 2025 | 12 800 | 24 100 | 🔻 -46.89% |
| 4 | BAGUES | Bague’s en or 13 | 2026 | 2025 | 7 950 | 5 750 | 🔺 +38.26% |
| 5 | DUPOND | Dupond INC | 2026 | 2025 | 7 000 | 7 000 | ➖ 0% |
aggregationExecute Input parameters
| Fields | Type | Description |
|---|---|---|
| entityKey | String | Aggregation definition identifier |
| aggregationType | String | Aggregation operation to apply |
| periodType | String | Time grouping of the aggregation |
| dateMin | String | Start date of the reference period |
| dateMax | String | End date of the reference period |
| compare | Boolean | Enable period comparison |
| top | Int | Top N groups or no Top limit |
| includeOthers | Boolean | Add an aggregated Others row (only when top > 0) |
| othersLabel | String | Label for Others |
| filterName | String | Business filter applied before aggregation |
| groupByName | String | Grouping applied before aggregation |
| valueColumn1 | String | Main value used for aggregation and ranking |
| valueColumn2 | String | Optional complementary value |
| distinctCountName | String | Value used for DISTINCTCOUNT |
| search | String | Optional. Restricts the aggregation to a specific entity id (customer, product, supplier). |
| searchScope | String | Optional. Required when multiple search scopes are supported. |
Info
-
entityKey
Identifies the exact aggregation definition to execute.
This value must match a entityKey returned by aggregationCatalog.- available filters
- allowed groupBy
- available valueColumns
- supported aggregationTypes
-
aggregationType
Defines the aggregation operation applied on valueColumn1 (for example:
SUM,AVG,MIN,MAX,COUNT,DISTINCTCOUNT).
Supported values must match one of the aggregation types returned by aggregationCatalog.- COUNT and DISTINCTCOUNT ignore valueColumn1
- DISTINCTCOUNT requires distinctCountName
- all sorting and Top N logic are always based on valueColumn1, even when valueColumn2 is provided
-
Grouping logic (groupByName × periodType)
The aggregation engine uses two independent grouping dimensions:
- a business dimension defined by groupByName
- a time dimension defined by periodType
These dimensions combine to determine the structure and number of rows returned. There are four possible combinations:
-
groupByName ≠
Noneand periodType ≠None→ one row per business entity and per period Example: revenue per customer, per month -
groupByName ≠
Noneand periodType =None→ one row per business entity, without time breakdown Example: total revenue per customer -
groupByName =
Noneand periodType ≠None→ one row per period, without business breakdown Example: global revenue per month -
groupByName =
Noneand periodType =None→ a single grand total row, no grouping
-
periodType
Defines the time grouping granularity (for example:
Day,Week,Month,Quarter,Year).
This value must match one of the period types returned by aggregationCatalog.- when periodType ≠
None, results are grouped by period - when periodType =
None, no time grouping is applied and the provided dates are used as-is
- when periodType ≠
-
groupByName
Defines the business grouping dimension (for example:
Customer,Product,Account).
This value must match exactly one groupBy name returned by aggregationCatalog.- when groupByName ≠
None, results are grouped by business entity - when groupByName =
Noneor empty, no business grouping is applied
When groupByName is set to
None, the aggregation behaves as a pure time-series or grand-total aggregation.- no entity ranking is performed
- date ranges are never recalculated
- top and compare only affect how results are interpreted, not which dates are selected
- when groupByName ≠
-
dateMin
dateMax
Define the reference date range for the aggregation.
Values must be provided as ISO 8601 date strings (for example 2024-01-01).
Dates are represented as strings because the aggregation engine accepts dynamic filter values rather than strongly typed GraphQL date parameters.-
When groupByName is set (not
Noneor empty) and (top >0or compare =true) and periodType ≠None:- dateMax is used as the reference date (fallback: dateMin, then today)
- the engine automatically recalculates dateMin and dateMax to align with periodType
- one period when using top
- two periods (N and N-1) when using compare
-
When groupByName =
Noneor empty:- dateMin and dateMax are never recalculated
- the engine returns all periods between dateMin and dateMax
- when top or compare is used, dateMin is required
-
-
compare
When set to
trueand groupByName is set, the engine compares:- the reference period (N)
- with the immediately preceding equivalent period (N-1)
This comparison is performed by periodType and per business entity (for example: by customer, month vs month-1).
- When groupByName is set, date recalculation rules apply (see dateMin/dateMax).
- When groupByName =
None:- dates are not recalculated
- the engine returns all periods between dateMin and dateMax
compare must not be used to compare business entities
(for example: “revenue per customer for June” is a breakdown, not a comparison).The response structure changes to expose:
periodN,periodN_1valueN,valueN_1deltaPercent
-
top
Defines how many groups are returned and how the result is ordered.
-1= No limit. All groups are returned without ranking0= All groups are returned, ordered by valueColumn1 descending-
> 0= Only the Top N groups are returned, ordered by valueColumn1 descending - When top >
0and groupByName is set, the engine:- uses dateMax as the reference
- recalculates the date range to one period aligned with periodType
- When groupByName =
None:- dateMin and dateMax are used as-is
- all periods between the two dates are returned
Sorting is always performed only on valueColumn1.
-
includeOthers
Used only when top >
0.
Adds an additional row that aggregates all remaining groups not included in the Top N. -
othersLabel
Defines the label used for the aggregated row when includeOthers =
true.
If not specified, the default value isOthers. -
filterName
Defines the business filter applied before aggregation.
This value must match exactly one filter name returned by aggregationCatalog.
This parameter selects business filters only (for example: “Validated invoices”, “Paid invoices”).To restrict the aggregation to a specific entity (customer, product, supplier), use the search parameter instead.
When multiple ID types are supported, also provide searchScope. -
valueColumn1
The main value used for the aggregation.
This value must match exactly one valueColumn name returned by aggregationCatalog.- required unless aggregationType is
COUNTorDISTINCTCOUNT - used for all sorting and Top N logic
- required unless aggregationType is
-
valueColumn2
Optional complementary value to valueColumn1.
This value must match exactly one valueColumn name returned by aggregationCatalog.- returned as-is in the result
- never used for sorting or ranking
-
distinctCountName
Required only when aggregationType =
DISTINCTCOUNT.
This value must match one of the distinctCount values returned by aggregationCatalog. -
search
Optional parameter used to restrict the aggregation to a specific entity identifier
(for example: customer id, product id, supplier id).
This restriction is applied on top of the selected filterName. -
searchScope
Optional parameter used when the aggregation supports multiple ID types.
Supported values are exposed by searchScopes returned by aggregationCatalogWhen only one searchScope is available, this parameter can be omitted.
aggregationExecute Response
| Fields | Type | Description |
|---|---|---|
| meta | AggregationExecuteMeta | Echo of the executed aggregation parameters |
| rows | AggregationExecuteRow | Aggregated result rows |
meta fields
| Fields | Type | Description |
|---|---|---|
| entityKey | String | Executed aggregation definition identifier |
| context | String | Human-readable aggregation context |
| aggregationType | String | Aggregation operation actually applied |
| periodType | String | Time grouping used during execution |
| dateMin | String | Effective start date used by the engine |
| dateMax | String | Effective end date used by the engine |
| compare | Boolean | Indicates whether period comparison was applied |
| top | Int | Effective Top N value used |
| includeOthers | Boolean | Indicates whether an Others row was added |
| othersLabel | String | Label used for the Others row |
| filterName | String | Business filter applied |
| groupByName | String | Business grouping applied |
| valueColumn1 | String | Main aggregated value |
| valueColumn2 | String | Secondary aggregated value (if any) |
| distinctCountName | String | Distinct count metric (when applicable) |
| search | String | Entity identifier used to restrict results (if any) |
| searchScope | String | Identifier type used for search (if any) |
Info
-
meta
The values returned in this object represent the effective parameters used by the engine to execute the aggregation.In some cases, these values may differ from those provided in input if certain parameters were inconsistent or not compatible with each other.
The meta section always reflects the final parameters actually applied during execution.
Sample:
"meta": { "entityKey": "queryAggregateSalesInvoices", "context": "Sales Invoices by Customer", "aggregationType": "SUM", "periodType": "Year", "dateMin": "2025-01-01", "dateMax": "2025-12-31", "compare": false, "top": 5, "includeOthers": false, "othersLabel": "Others", "filterName": "All Customers", "groupByName": "Customer", "valueColumn1": "Total Net", "valueColumn2": "Total Liquid", "distinctCountName": "Sales Invoices", "search":null, "searchScope":null }
rows fields
| Fields | Type | Description |
|---|---|---|
| groupValue | String | Primary grouping value |
| secondValue | String | Optional complementary grouping label |
| period | String | Period label (when compare = false) |
| value1 | Decimal | Aggregated value for valueColumn1 |
| value2 | Decimal | Aggregated value for valueColumn2 |
| periodN | String | Current period label (when compare = true) |
| periodN_1 | String | Previous period label (when compare = true) |
| valueN | Decimal | Aggregated value for period N |
| valueN_1 | Decimal | Aggregated value for period N-1 |
| deltaPercent | Decimal | Percentage evolution between N and N-1 |
Info
-
rows
Contains the aggregated results.
Each row always exposes the same set of fields.
Depending on the mode (compare = false or true), some fields will contain values and others will benull.Every row contains:
groupValuesecondValueperiodvalue1value2periodNperiodN_1valueNvalueN_1deltaPercent
secondValueis an optional complementary value that depends on the selected groupBy.
For example, when grouping by Customer:groupValuecontains the Customer CodesecondValuecontains the Customer Name
If the selected grouping does not provide a complementary label,
secondValuecan benull.-
When compare = false
period,value1, andvalue2are populated.
The comparison fields (periodN,periodN_1,valueN,valueN_1,deltaPercent) arenull. -
When compare = true The comparison fields are populated.
period,value1, andvalue2arenull.
Sample 1 - Standard aggregation (no comparison)
"rows": [ { "groupValue": "ANDERSSON", "secondValue": "Andersson AB", "period": "2025", "value1": 35200, "value2": 35200, "periodN": null, "periodN_1": null, "valueN": null, "valueN_1": null, "deltaPercent": null } // ..... ]Sample 2 - Aggregation with period comparison (compare = true)
"rows": [ { "groupValue": "OPALE", "secondValue": "Opale", "period": null, "value1": null, "value2": null, "periodN": "2026", "periodN_1": "2025", "valueN": 28570, "valueN_1": 28970, "deltaPercent": -1.38 }, { "groupValue": "RUBIS", "secondValue": "Rubis sur ongle", "period": null, "value1": null, "value2": null, "periodN": "2026", "periodN_1": "2025", "valueN": 14364, "valueN_1": 342, "deltaPercent": 4100 }, // ....... ]