> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Count objects with search

> Use groupBy on v3 search to count a kind's objects by one field, instead of listing them.

`search` can answer "how many, by what?" without returning rows. Add `groupBy`,
the name of one field, and `search` returns each value of that field with the
number of objects that carry it.

```json theme={null}
{ "kind": "inventory_source", "groupBy": "status" }
```

The response is the same page object `search` returns for the kind, with counts
in place of `results`:

```json theme={null}
{
  "objects": {
    "outcome": "page_inventory_source",
    "kind": "inventory_source",
    "groupBy": "status",
    "total": 6,
    "groups": [
      { "value": "ACTIVE", "count": 3 },
      { "value": "PENDING", "count": 2 },
      { "value": "DISABLED", "count": 1 }
    ],
    "truncated": false
  }
}
```

The tool result's text carries the same counts for hosts that read only text.

## Request

| Field | Meaning |
| - | - |
| `groupBy` | One field the kind can be grouped by. Requires `kind`. It composes with that kind's other filters and `query`, so a count covers exactly the objects the same search would list. |
| `limit` | Caps the number of groups returned, 1 to 50. The default is 50. |
| `cursor` | Not accepted with `groupBy`. A grouped count is one response. |
| `sources` | If sent, must be only `objects`. A grouped count never searches the docs. |

## Response

| Field | Meaning |
| - | - |
| `kind`, `groupBy` | The kind counted and the field grouped by. |
| `total` | The number of objects that match the search, filters applied. |
| `groups` | One entry per distinct value, ordered by `count` descending and then `value` ascending. `value` is `null` for objects with no value for the field, which sort after named values with the same count. |
| `truncated` | `true` when more distinct values exist than `limit` returned. |
| `otherCount` | Present only when `truncated`: the number of objects in the values not returned. |

`sum(groups.count) + otherCount` always equals `total`.

A count uses the same account, permissions and data source as the list it
summarises. It never returns rows. `total` is the number of objects that match
the search with its filters applied, not the number the account holds. A plain
`search` of `inventory_source` reports the same number as its `total`, so the
two always agree. Earlier previews also returned `matched` on that plain search;
it is gone, because `total` now carries that meaning.

## Which kinds can be counted

| Kind | `groupBy` fields | Accounts |
| - | - | - |
| `inventory_source` | `status` (`PENDING`, `ACTIVE`, `DISABLED`) | Seller |

Other kinds do not support `groupBy` yet. The listed `tools/list` schema for
your account is authoritative: accounts that cannot count any kind do not see
the field. Source health is not counted, because it is read per source and not
from the list.

## Errors

| Condition | Code |
| - | - |
| The kind does not support grouped counts, including a kind read by fanning out across sellers or other sources that can each fail | `UNSUPPORTED_FEATURE`, naming the kind |
| The field is not one the kind can be grouped by | `VALIDATION_ERROR`, listing the groupable fields |
| `groupBy` without `kind`, with `cursor`, with `limit` above 50, or with `sources` other than `objects` | `VALIDATION_ERROR` |
| A Scope3 staff read that names a `storefrontId` | `UNSUPPORTED_FEATURE` |

`VALIDATION_ERROR` is the code every v3 input refusal carries on the wire.
Correct the request and call again. See [Errors](/v3/errors) for the full
envelope.

Grouping by more than one field, and grouping by time period, are not part of
this contract.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.