---
title: "Aggregate %alias records server-side"
method: POST
path: "/objects/aggregate"
tags: ["objects"]
---

# Aggregate %alias records server-side

`POST /objects/aggregate`

## Request

- Base URL: `https://api.ontraport.com/1`
- URL: `https://api.ontraport.com/1/objects/aggregate`
- Auth: none declared

Exact aggregation over the same Collection machinery getList uses, discriminated by mode. mode=single aggregates one object type with an optional group_by on its own fields; mode=related groups a child object by its foreign key to a parent with an optional having threshold; mode=subscriber counts distinct subscribers per visible, active tag, sequence, campaign, or membership site. Grouped pages return at most 50 rows and fetch one additional sentinel row: has_more_groups=true means additional groups were omitted and total_groups is null; otherwise total_groups is exact. Group keys are RAW stored values (option keys, record ids) — callers resolve display names themselves. Ungrouped min/max values preserve the aggregated field's numeric or textual type. Database execution failures return HTTP 503 rather than a successful empty result. Responds with { mode, value, matched_count, groups: [{key, value}], total_groups, has_more_groups, error }.

## Request body `application/x-www-form-urlencoded`

- object
  - `objectID` integer, required: Object type id. mode=single: the aggregated object; mode=related: the PARENT object being grouped; mode=subscriber: the subscribed object (0 = Contact).
  - `mode` 'single' | 'related' | 'subscriber', required: Aggregation shape: single, related, or subscriber.
  - `aggregate` string: Aggregate function. mode=single: count, sum, avg, min, max. mode=related: count, sum, avg. Not accepted for mode=subscriber (always a distinct count).
  - `field` string: Column to aggregate. Required for sum/avg/min/max, not accepted for count. mode=related: a column on the CHILD object.
  - `group_by` string: mode=single only: column to group by. Omit for a scalar result.
  - `condition` string: Standard JSON condition array (the same format getList accepts, parsed by Collection::SQLFromJSON). mode=related: the condition applies to the CHILD rows. A condition referencing an unknown, inaccessible, or invalid field or operator fails the whole request (never a silently broadened result or hidden-field count oracle).
  - `related_object_id` integer: mode=related only (required): the CHILD object type holding the foreign key.
  - `relationship_field` string: mode=related only (required): the foreign-key column ON THE CHILD that points at the parent.
  - `having` string: mode=related only: JSON {op, value} threshold on the per-parent aggregate, e.g. {"op": ">", "value": 10}. Ops: >, >=, <, <=, =, !=.
  - `relation_type` string: mode=subscriber only (required): tag, sequence, campaign, or membership.
  - `limit` integer: Max groups per page (default and cap: 50).
  - `offset` integer: Groups to skip (pagination).

## Response `200`

Successful aggregation (the data envelope carries "error" when the query itself is refused)

- Response
  - `code` integer, required
  - `data` object, required
  - `account_id` integer, required

## Other responses

- `400`: Contract violation: unknown mode, parameter not valid for the mode, bad aggregate function, malformed filters/having
- `403`: No permissions

## Changes

- **2026-09-30** `c102850cff71`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/ontraport/apis/ontraport-api/changes/objects/aggregate/post.md)

---

[API](https://skmtc.dev/ontraport/apis/ontraport-api.md) - [All operations](https://skmtc.dev/ontraport/apis/ontraport-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ontraport/apis/ontraport-api/revisions/4c878a9f93aa?raw)
