Fetch Workspace Stats

Aggregate statistics over a filtered set of records, without listing the records. Use this for any
"how many", "what's the breakdown", or "what's the total" question: it is dramatically cheaper than paging
a collection and counting client-side.

One workspace endpoint serves every analyzable resource. Name the resource and request the stats you want
as query parameters:

GET /api/v2/workspaces/{workspace_id}/stats?resource=contact&count=true&count_by[property]=is_active&filter[tag_ids]=42

A flag of true computes the stat; an object-style query supplies a stat's parameters. Omit a stat (or pass
false) to skip it. Calling with only resource returns a 422 that lists the stats and property values the
named resource supports, so the endpoint is self-describing.

Narrowing the set

The same selectors the resource's own index accepts, composed with AND:

  • filter - simple field matches, e.g. filter[tag_ids]=42 for contacts
  • stable_id - a one-off Refine filter token, e.g. from POST /workspaces/{workspace_id}/contacts/filters
  • stored_filter_id - a saved Refine filter id

Omit all three to report on every record of that resource in the workspace.

Beyond the index's own keys, filter takes a created_at window on every resource
(created_at_after inclusive, created_at_before exclusive, ISO 8601 only, with an offset's +
sent as %2B), and on order the two attribution keys a sales dashboard needs: funnel_id
(orders attributed to that funnel) and product_id (orders containing that product, from any
channel). Every id filter (id, contact_id, page_id, tag_ids, funnel_id, product_id)
takes a numeric id or a public_id, comma-separated for several; an id that is not this
workspace's is a 422 naming it, never a silent zero:

GET /api/v2/workspaces/{workspace_id}/stats?resource=order&count=true&sum[property]=total_collected&filter[funnel_id]=41&filter[created_at_after]=2026-10-01T00:00:00Z

Large sets

Every stat is computed over the whole matching set, bounded in time rather than in rows: each query has a
statement timeout, and the request has an overall time budget. A stat that cannot finish in time is not
returned; it is named in unavailable, with unavailable_reason saying whether to narrow the filter or to
ask for it on its own, rather than computed over part of the set.

count has one fallback of its own. Past 100,000 matches, if counting the whole set cannot finish in time,
it returns 100,000 with count_capped_at beside it - the real total is higher, so narrow the filter.

When no requested stat can be computed in time, the response is a 422, not a 503: retrying it unchanged
fails the same way, so narrow it instead.

Access

Computing a statistic persists nothing, so a token with read-only access may call it. Authorization
follows the category of the resource being analyzed: contact requires read access to Contacts, order
requires read access to Store, form_submission requires read access to Forms.

Form submissions per page

form_submission reports on the same rows GET /workspaces/{workspace_id}/form_submissions lists: one per
form post on a ClickFunnels page. count_by[property]=page_id returns the submission count of every page in
one call, so counting a funnel's submissions no longer means paging the whole log:

GET /api/v2/workspaces/{workspace_id}/stats?resource=form_submission&count_by[property]=page_id&filter[page_id]=41,42

These are form posts, not opt-ins: checkout submits and repeat posts by the same contact count too. For
opt-ins as the funnel dashboard counts them, read optins from GET /funnels/{funnel_id}/stats or
GET /pages/{page_id}/stats.

It has no Refine filter class, so stable_id and stored_filter_id are refused with a 422 for it.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
Path Params
string
required
Query Params
string
enum
required

The resource to report on.

Allowed:
boolean
Defaults to false

How many records match. Exact unless counting a set of more than 100,000 cannot finish in time - see count_capped_at in the response.

count_by
object

Breaks the matching set down by one allow-listed property, returning a count per distinct value.

boolean
Defaults to false

The earliest and latest created_at in the matching set. Exact; listed in unavailable instead when it cannot finish in time.

sum
object

Totals one allow-listed numeric property. Exact; listed in unavailable instead when it cannot finish in time. Not available for every resource.

filter
object

Simple field matches. The keys the resource's index accepts - contact: id, email_address, is_active, tag_ids; order: id, contact_id, order_type, billing_status, service_status, live_mode; form_submission: id, page_id, contact_id - plus created_at_after (inclusive) and created_at_before (exclusive, both ISO 8601 only; send an offset's + as %2B) on every resource, and funnel_id and product_id on order. Every id filter takes a numeric id or a public_id; one that is not this workspace's is a 422. Comma-separated values match any of them.

string

A URL-encoded Refine stable_id token, applied to the set before computing. Same token format the resource's index accepts; for contacts it can come from POST /workspaces/{workspace_id}/contacts/filters. Pass it exactly as returned. Not accepted for form_submission (422).

string

The id or public_id of a saved Refine filter in this workspace, applied to the set before computing. Must match the resource's filter type. Not accepted for form_submission (422).

Responses

Language
Credentials
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json