Aggregations
Run SQL-native aggregation queries on any object -- count, sum, average, min, max, and group by.
The Aggregate endpoint lets you compute metrics directly on your CRM data without fetching individual records. It supports standard SQL aggregation functions with optional grouping.
Aggregate records
GET /api/v1/aggregate/{object}Path parameters
| Parameter | Type | Description |
|---|---|---|
object | string | The object to aggregate (e.g., opportunities, contacts) |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
field | string | Yes (except COUNT) | The field to aggregate (e.g., amount, status). For COUNT, the field is optional — if omitted or unknown, it falls back to the object's standard display field and counts all rows. |
function | string | No | Aggregation function. Defaults to COUNT if omitted. The set of valid functions depends on the field's type (see below). |
group_by | string | No | Field to group results by. Must be an existing field on the object. |
filter_field | string | No | Field to filter on before aggregating. |
filter_operator | string | No | Filter operator (e.g., equals, not_equals, greater_than, less_than, contains, in, is_null, is_not_null). With in, pass a comma-separated filter_value. |
filter_value | string | No | Value for the filter. |
Available functions per field type
The valid set of functions is derived from the field's type. Requesting a function that is not available for the field returns an INVALID_OPERATION error (the response lists the allowed functions in available_values).
| Function | Description | Available on |
|---|---|---|
COUNT | Count of non-null values (or all rows when no field is given) | All field types |
COUNT_DISTINCT | Count of distinct non-null values | Most types (not virtual/composite types such as MANY_TO_MANY, PIPELINE, ADDRESS) |
SUM | Sum of values | NUMBER, INTEGER, DECIMAL, PERCENT, CURRENCY, DURATION, ELAPSED_TIME |
AVG | Average of values | Numeric types, RATING, DURATION, ELAPSED_TIME |
MEDIAN | Median value | Numeric types, RATING, DATE, DATETIME, DURATION, ELAPSED_TIME |
MIN / MAX | Smallest / largest value | Numeric types, RATING, temporal types (DATE, DATETIME, DURATION, ELAPSED_TIME) |
RANGE | Difference between max and min | Numeric types, DATE, DATETIME, DURATION, ELAPSED_TIME |
STDDEV / VARIANCE | Standard deviation / variance | NUMBER, INTEGER, DECIMAL, PERCENT, CURRENCY |
PERCENT_FILLED / PERCENT_EMPTY | Share of rows where the field is filled / empty | All field types |
COUNT_TRUE / COUNT_FALSE / PERCENT_TRUE / PERCENT_FALSE | Boolean tallies | BOOLEAN |
AVG_LENGTH | Average character length | Text types (TEXT, LONG_TEXT, RICH_TEXT, EMAIL) |
For CALCULATED and ROLLUP fields, the available functions are resolved from the field's underlying output type (a rollup that produces a number exposes the full numeric suite).
Validation rules
- The
fieldmust exist on the target object (except forCOUNT, which falls back to the standard display field). - The
functionmust be available for the field's type (see the table above), otherwise anINVALID_OPERATIONerror is returned. group_by, when provided, must reference an existing field on the object.- When
filter_fieldis provided,filter_operatoris also required. - Aggregation respects your role-based access — you must have at least view access to the object.
Scalar response
When no group_by is specified, a single aggregated value is returned.
{
"object_name": "opportunities",
"field": "amount",
"function": "SUM",
"value": 284500.00
}Grouped response
When group_by is specified, results are broken down by each distinct value of the grouping field. Rows whose grouping value is empty are returned with "group": null.
{
"object_name": "opportunities",
"field": "amount",
"function": "SUM",
"group_by": "status",
"results": [
{ "group": "open", "value": 150000.00 },
{ "group": "negotiation", "value": 85000.00 },
{ "group": "closed_won", "value": 49500.00 },
{ "group": null, "value": 12000.00 }
]
}Errors
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_OBJECT | The object name does not exist |
| 400 | MISSING_REQUIRED_FIELD | No field was provided (and the function is not COUNT) |
| 400 | INVALID_FIELD | The field or group_by field does not exist on the object |
| 400 | INVALID_OPERATION | The requested function is not available for the field's type (see available_values) |
| 400 | PERMISSION_DENIED | Your role has no view access to the object |
| 401 | UNAUTHORIZED | Invalid or missing API token |
| 500 | INTERNAL_ERROR | Unexpected server error |
Examples
Count all contacts:
curl -X GET "https://kasar.app/api/v1/aggregate/contacts?field=id&function=COUNT" \
-H "Authorization: Bearer YOUR_API_TOKEN"Sum opportunity amounts:
curl -X GET "https://kasar.app/api/v1/aggregate/opportunities?field=amount&function=SUM" \
-H "Authorization: Bearer YOUR_API_TOKEN"Average deal size grouped by status:
curl -X GET "https://kasar.app/api/v1/aggregate/opportunities?field=amount&function=AVG&group_by=status" \
-H "Authorization: Bearer YOUR_API_TOKEN"Count distinct companies per country:
curl -X GET "https://kasar.app/api/v1/aggregate/companies?field=name&function=COUNT_DISTINCT&group_by=country" \
-H "Authorization: Bearer YOUR_API_TOKEN"Sum revenue with a filter:
curl -X GET "https://kasar.app/api/v1/aggregate/opportunities?field=amount&function=SUM&filter_field=status&filter_operator=equals&filter_value=closed_won" \
-H "Authorization: Bearer YOUR_API_TOKEN"Max deal value:
curl -X GET "https://kasar.app/api/v1/aggregate/opportunities?field=amount&function=MAX" \
-H "Authorization: Bearer YOUR_API_TOKEN"