For AI agents: markdown of this page — /docs-content-en/entities/shipments/aggregate.md documentation index — /llms.txt

Shipment aggregation

POST /v1/shipments/aggregate

Counts shipments and computes the sum, average, minimum and maximum of the delivery cost, with filtering and grouping by order or delivery service.

Standard fields

Field Purpose
FieldpriceDelivery PurposeDelivery cost — the main field for sum / avg / min / max. Also available for groupBy
FieldbasePriceDelivery, discountPrice PurposeBase delivery cost and delivery discount — numeric fields for sum / avg / min / max
FieldorderId PurposeOrder ID — used in groupBy to break shipments down by order
FielddeliveryId PurposeDelivery service ID — used in groupBy to break shipments down by service

The fields available for groupBy are listed in the aggregatable array in GET /v1/shipments/fields. Numeric functions accept any field of type number from the same schema, including fields outside aggregatable.

User fields. For a non-existent field name in sum / avg / min / max, the 400 INVALID_PARAMS response lists the allowed numeric fields. That list contains only standard shipment fields — basePriceDelivery, companyId, deliveryId, discountPrice, empAllowDeliveryId, empCanceledId, empDeductedId, empMarkedId, empResponsibleId, id, orderId, priceDelivery, responsibleId, with no user fields. A rejection for a field outside aggregatable in groupBy names only orderId, priceDelivery, deliveryId as allowed.

Request fields (body)

Field Type Required Description
Fieldaggregate Typearray Requiredno DescriptionArray of expressions { "field": "priceDelivery", "function": "sum" }, up to 5 per request. Functions: count, sum, avg, min, max. For count the field is "*". Without the parameter, only count is returned
Fieldfilter Typeobject Requiredno DescriptionFiltering by the fields of GET /v1/shipments/fields.
Filtering syntax. Example: { "orderId": 1027 }
FieldgroupBy Typestring | string[] Requiredno DescriptionA field or an array of fields to group by, up to 5 fields. Allowed values come from the aggregatable array: orderId, priceDelivery, deliveryId
FieldgroupOrderBy Typearray Requiredno DescriptionGroup sorting: [{ "field": "priceDelivery:sum", "direction": "desc" }]. field accepts count, a field name from groupBy, or <field>:<function> from aggregate. Works only together with groupBy
FieldgroupLimit Typenumber Requiredno DescriptionLimits the number of returned groups, from 1 to 1000. Works only together with groupBy

Examples

curl — personal key

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/shipments/aggregate" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "orderId": 1027 },
    "aggregate": [
      { "field": "*", "function": "count" },
      { "field": "priceDelivery", "function": "sum" },
      { "field": "priceDelivery", "function": "avg" }
    ],
    "groupBy": "deliveryId"
  }'

curl — OAuth application

Terminal
curl -X POST "https://vibecode.bitrix24.com/v1/shipments/aggregate" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": { "orderId": 1027 },
    "aggregate": [
      { "field": "*", "function": "count" },
      { "field": "priceDelivery", "function": "sum" },
      { "field": "priceDelivery", "function": "avg" }
    ],
    "groupBy": "deliveryId"
  }'

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/shipments/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { orderId: 1027 },
    aggregate: [
      { field: '*', function: 'count' },
      { field: 'priceDelivery', function: 'sum' },
      { field: 'priceDelivery', function: 'avg' },
    ],
    groupBy: 'deliveryId',
  }),
})

const { success, data } = await res.json()
// data.groups — delivery cost by delivery service
console.log(data.groups)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/shipments/aggregate', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    filter: { orderId: 1027 },
    aggregate: [
      { field: '*', function: 'count' },
      { field: 'priceDelivery', function: 'sum' },
      { field: 'priceDelivery', function: 'avg' },
    ],
    groupBy: 'deliveryId',
  }),
})

const { success, data } = await res.json()

Other scenarios

The blocks below are request bodies.

Shipment count for an order only — without the aggregate array no records are fetched, and data.meta.recordsProcessed in the response is 0:

JSON
{ "filter": { "orderId": 1027 } }

Grouping by two fields — by order and delivery service:

JSON
{
  "aggregate": [{ "field": "*", "function": "count" }],
  "groupBy": ["orderId", "deliveryId"]
}

Sum and average of the delivery cost without grouping:

JSON
{
  "filter": { "orderId": 1027 },
  "aggregate": [
    { "field": "*", "function": "count" },
    { "field": "priceDelivery", "function": "sum" },
    { "field": "priceDelivery", "function": "avg" }
  ]
}

Response fields

Field Type Description
Fieldsuccess Typeboolean DescriptionAlways true on success
Fielddata.count Typenumber DescriptionNumber of shipments matching the filter
Fielddata.aggregates Typeobject DescriptionResults of numeric functions by field: { "priceDelivery": { "sum": 500, "avg": 500 } }. An empty object if aggregate contains only count
Fielddata.groups Typearray DescriptionPresent only with groupBy. Each element holds the grouping field values, count and aggregates for the group
Fielddata.meta.totalRecords Typenumber DescriptionTotal number of records matching the filter
Fielddata.meta.recordsProcessed Typenumber DescriptionNumber of processed records, up to 5000
Fielddata.meta.truncated Typeboolean Descriptiontrue if the numbers were not computed over all records matching the filter: fewer records were read than data.count promised — including when more than 5000 matched the filter — or the slice was cut short by a subpage error. The size of the shortfall arrives in data.meta.recordsShortfall, the cut-short slice in data.meta.pageErrorSample. Always present, false on a complete response. If the request has neither groupBy nor numeric functions, no records are fetched and the flag is always false
Fielddata.meta.groupTotal Typenumber DescriptionPresent only with groupBy — the number of groups before groupLimit is applied
Fielddata.meta.groupsTruncated Typeboolean DescriptionPresent only with groupBy. true if the group list was cut by groupLimit

Response example

JSON
{
  "success": true,
  "data": {
    "count": 1,
    "aggregates": {
      "priceDelivery": {
        "sum": 500,
        "avg": 500
      }
    },
    "groups": [
      {
        "deliveryId": 1,
        "count": 1,
        "aggregates": {
          "priceDelivery": {
            "sum": 500,
            "avg": 500
          }
        }
      }
    ],
    "meta": {
      "totalRecords": 1,
      "recordsProcessed": 1,
      "truncated": false,
      "groupTotal": 1,
      "groupsTruncated": false
    }
  }
}

Error response example

400 — the field is not in the schema. The message lists the allowed numeric fields:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Field 'weight' not found. Available numeric fields: basePriceDelivery, companyId, deliveryId, discountPrice, empAllowDeliveryId, empCanceledId, empDeductedId, empMarkedId, empResponsibleId, id, orderId, priceDelivery, responsibleId."
  }
}

Errors

HTTP Code Description
HTTP400 CodeINVALID_PARAMS Descriptioncount is passed with a field other than "*"
HTTP400 CodeINVALID_PARAMS Descriptionaggregate is passed as a non-array or an empty array
HTTP400 CodeINVALID_PARAMS Descriptionaggregate has more than 5 expressions
HTTP400 CodeINVALID_PARAMS DescriptionUnknown function — the message lists the allowed ones
HTTP400 CodeINVALID_PARAMS Descriptionsum / avg / min / max without a field or with the field "*"
HTTP400 CodeINVALID_PARAMS DescriptionThe field for sum / avg / min / max is not numeric, for example trackingNumber — the message names its type
HTTP400 CodeINVALID_PARAMS DescriptionThe field for sum / avg / min / max is not in the schema — the message contains the list of numeric fields
HTTP400 CodeINVALID_PARAMS DescriptionThe op, field or function fields are passed at the top level of the body instead of the aggregate array
HTTP400 CodeINVALID_PARAMS DescriptiongroupBy is neither a string nor an array of strings
HTTP400 CodeINVALID_PARAMS DescriptionA field in groupBy is outside the aggregatable array — the message contains the list of allowed ones
HTTP400 CodeINVALID_PARAMS DescriptiongroupBy has more than 5 fields
HTTP400 CodeINVALID_PARAMS DescriptiongroupBy contains a reserved name: count, aggregates, meta, groups
HTTP400 CodeINVALID_PARAMS DescriptiongroupOrderBy or groupLimit is passed without groupBy, or its value is invalid
HTTP400 CodeUNKNOWN_FILTER_FIELD DescriptionUnknown field in filter — the message contains the list of shipment fields
HTTP400 CodeINVALID_FILTER_FIELD DescriptionA field name in filter starts with the unsupported prefix @ or !@
HTTP400 CodeINVALID_FILTER_OPERATOR DescriptionUnsupported operator in filter, an empty object in a condition value, or the $or logical condition
HTTP400 CodeINVALID_FILTER_SHAPE Descriptionfilter is not an object of conditions, for example a string, a number or an array
HTTP400 CodeINVALID_DUPLICATE_FILTER_FIELD DescriptionTwo filter conditions reduce to one Bitrix24 condition, for example $ne and $nin on the same field. Pass only one of them
HTTP403 CodeSCOPE_DENIED DescriptionThe API key has no sale scope
HTTP401 CodeMISSING_API_KEY DescriptionThe X-Api-Key header is not passed
HTTP401 CodeTOKEN_MISSING DescriptionThe API key has no configured tokens
HTTP429 CodeRATE_LIMITED DescriptionRate limit exceeded: 300 requests per minute per portal. All API keys of the portal share one limit. The current limit is returned in the x-ratelimit-limit header. Retry after the delay in the Retry-After header

For the full list of common API errors, see Errors.

Known specifics

count versus numeric functions. A request without groupBy and without numeric functions is handled by a single request to Bitrix24 — no records are fetched, and the response time does not depend on the number of shipments. As soon as the request has sum / avg / min / max or groupBy, including together with a single count, up to 5000 records are loaded page by page, and the aggregates are computed by Vibecode. With meta.truncated: true, the truncated: true mark is also set inside the object of each field in data.aggregates and on each element of data.groups, and data.meta.warnings carries the AGGREGATE_TRUNCATED warning. For an exact number on a large selection, use a request without groupBy and numeric functions, or narrow the filter, for example by orderId. For a full explanation, see Aggregation POST — the 5000-record ceiling.

See also