Aggregate Documents

Beta
Count, sum, average, min or max over a collection, filtered with the same `where` a query takes and optionally grouped by one field, in one request. It runs on each document's indexed projection (its top-level string / number / boolean / null fields), never on the bodies: a nested value does not exist to it, a string longer than 256 characters groups by its first 256 and the answer says `key_truncated` when that happened, and at most 100 groups come back, largest first (`groups_truncated`). A read carrying a body, hence a POST on a literal sub-path; `aggregate` is a reserved document id. This is the last operation the query surface takes. A store is a Firestore-shaped document store: filter, order, page and aggregate on top-level fields. No joins, nested-field filters, full-text search or SQL follow; a customer who needs more brings their own database through a webhook or MCP tool, or pulls a collection into a run's sandbox. Dark launch: requires the `hosted_apis_access` entitlement (402 `hosted_apis_not_in_plan` otherwise).

Authentication

AuthorizationBearer

Enter your API key with the Bearer prefix, e.g. ‘Bearer sk_…’.

Path parameters

store_idstringRequired

Store id (prefixed external id, store_...).

collectionstringRequired

Collection name (lowercase letters, digits, _, -).

Headers

Speechify-VersionstringOptional

Request

This endpoint expects an object.
metricslist of objectsRequired
wherelist of objectsOptional
Filters, ANDed, the same ones a query takes.
group_bystringOptionalformat: "^[A-Za-z_][A-Za-z0-9_]{0,63}$"<=64 characters

One projected field to group by. A string that reaches the index’s 256-byte limit may have been cut there, and the answer says so.

Response headers

Speechify-Request-IdstringOptional
Unique identifier for this request, present on every response (2xx and non-2xx alike). If the caller sends a `Speechify-Request-Id` request header the server echoes it back (sanitized and length-capped) so one logical request can be traced end-to-end; otherwise the server generates a fresh value. Log it on every response and quote it in support requests - it is the stable handle that ties your observation to Speechify's server-side logs, and it matches the `request_id` field in the error envelope. The legacy alias `X-Request-ID` carries the same value and is still accepted on requests, until 2027-07-24. Prefer the un-prefixed name (RFC 6648).

Response

OK
groupslist of objects

One entry per group, largest count first; exactly one without group_by.

groups_truncatedboolean

More than 100 groups existed; the largest are here.

key_truncatedboolean

At least one group key is a string that reached the index’s 256-byte limit and may have been cut there, so groups may have merged on a prefix.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
404
Not Found Error