Skip to content
API PlatformDevelopers
POST/v1/contacts/countbeta

Count contacts by filter

Needs
Read your data (mcp:read)
Plan
Any plan with API access
Limits
300 a minute per key
Undo
Nothing to undo: this only reads.

Counts the contacts an advanced filter (the Search contacts format) or a saved filter matches, without listing them. approximate is true when the number is an estimate.

Try it

Body

82 / 16,384 bytes as JSON

Limits: at most 8 levels deep, 60 conditions, 500 items per list, 500 characters per value, regex ≤ 200 characters, 16 KB in all. Format, operators and recipes: Filtering contacts.

The advanced filter (see **Search contacts**).

Count the contacts of a saved contact filter.

This only reads. It uses your real data and changes nothing.

Code and response

curl -X POST 'https://mcp.wa-api.cloud/v1/contacts/count' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "filter": {
    "broadcasts": {
      "some": {
        "id": {
          "eq": "88"
        },
        "message_status": {
          "eq": "not_responded"
        }
      }
    }
  }
}'

The code reads your key from $API_KEY.

Body

Body fields
FieldTypeWhat it is
filterobjectThe advanced filter (see Search contacts).
saved_filter_idstring | integerCount the contacts of a saved contact filter.pattern ^[1-9]\d{0,18}$

Headers

Headers
FieldTypeWhat it is
AuthorizationrequiredheaderBearer $API_KEY — your API key.
Api-VersionheaderThe API version to use, e.g. 2026-10-01. Default: the version your key is pinned to.one of: 2026-10-01 · pattern ^\d{4}-\d{2}-\d{2}$

Response 200

The count.

Response fields
FieldTypeWhat it is
countrequiredinteger-9007199254740991–9007199254740991
approximaterequiredbooleantrue when the count is an estimate.
resolved_datesarray of objectRelative or local dates in filter and the absolute instants they were run with.
pathrequiredstring
inputrequiredstring
valuerequiredstring
warningsarray of objectFilter conditions that may not mean what they look like: {path, message}.
pathstring
messagerequiredstring

Errors

Errors are application/problem+json. Branch on code.

StatusCodeWhen
400invalid_input

A field is missing or has the wrong format. errors[] points at each field. The filter is not valid: each problem names its field and how to fix it. reason names the class when there is one: filter_too_deep, filter_too_many_conditions, filter_list_too_long, filter_string_too_long, filter_regex_too_long, filter_regex_invalid, filter_too_large, saved_filter_cycle.

401unauthenticated

The Authorization header is missing, the key is unknown, expired or revoked.

403entitlement_required

The workspace's plan does not include API access (api_access).

403forbidden

The filter or sort compares phone numbers, which are hidden from this staff member (reason: phone_hidden).

403insufficient_scope

The key does not have the permission this operation needs.

404not_found

A saved filter it names does not exist in your workspace (reason: saved_filter_not_found).

429rate_limited

The key or workspace went over its rate limit. Wait for Retry-After seconds.

502upstream_error

The contacts service could not run this filter (reason: filter_failed), e.g. a regular expression its engine gives up on. Simplify the filter; retrying the same one fails again.

503service_unconfigured

Advanced filters are switched off on this server (reason: advanced_filter_disabled).

503upstream_unavailable

A service behind the API is briefly unavailable. Safe to retry with backoff.

504timeout

The filter took too long to run (reason: query_timeout): narrow it.

Examples

Contacts that read broadcast 88 but did not reply

Request body

{
  "filter": {
    "broadcasts": {
      "some": {
        "id": {
          "eq": "88"
        },
        "message_status": {
          "eq": "not_responded"
        }
      }
    }
  }
}

Response 200

{
  "count": 412,
  "approximate": false
}

Operation path

The same operation is also at POST /v1/ops/crm_count_contacts, with every field in the JSON body.