---
title: "Filter subscribers by engagement, sign-up date, state, and tags"
method: POST
path: "/v4/subscribers/filter"
tags: ["Subscribers"]
---

# Filter subscribers by engagement, sign-up date, state, and tags

`POST /v4/subscribers/filter`

Searches your subscriber list with compound conditions: email engagement (opens, clicks, sends, deliveries — with count thresholds and date ranges), sign-up date, subscriber state, and tags. Every condition in the `all` array must match (AND logic).

Use `counting_mode` to control how engagement thresholds are tallied — `raw` (default) counts every event, `unique_email` counts distinct emails — and the `include` array to embed extra fields (tags, stats, custom fields, location, attribution, canceled_at) on each returned subscriber.

**Data retention:** Starting October 15, 2026, email stats (opens, clicks, sends, bounces, and unsubscribes) are available via the API for the last 5 years — engagement-condition date bounds are clamped to that window, and a `stats` include range outside it returns a `400` error. See [Email data retention](/api-reference/email-data-retention) for the full policy.

## Request body

- SubscriberFilterRequest — Filter subscribers based on engagement and subscription criteria using the 'all' array with filter conditions that must all be met (AND logic).
  - `counting_mode` 'raw' | 'unique_email' — Controls how engagement-filter count thresholds are tallied. `raw` (default) counts every event — five opens of the same email = five. `unique_email` counts distinct emails on which the action occurred — five opens of the same email = one. Applies to every engagement filter (opens, clicks, sent, delivered) in the request; ignored for other filter types.
  - `all` FilterCondition[], required — Array of filter conditions where ALL must be met (AND logic)
    - `type` 'opens' | 'clicks' | 'sent' | 'delivered' | 'subscribed' | 'subscriber_state' | 'tags' | 'attribution' | 'custom_field' | 'location', required — Type of filter condition. `attribution` matches subscribers by their *original signup attribution* — supports two sub-conditions: `forms` matches by the form / landing-page id the subscriber signed up through, and `kit_source` matches by any combination of the underlying Kit source fields (source type, source id, source name, mechanism, mechanism id). Attribution is the original signup source; it does not track current subscription state. `custom_field` matches subscribers by the value they have stored for a particular custom field, identified by `subscriber_custom_field_id`. `location` matches subscribers whose primary location falls within a `radius` (miles) of (`latitude`, `longitude`). All three fields are required.
    - `count_greater_than` integer — Minimum count (exclusive). Only applicable for engagement types ('opens', 'clicks', 'sent', 'delivered').
    - `count_greater_than_or_equal` integer — Minimum count (inclusive). Only applicable for engagement types ('opens', 'clicks', 'sent', 'delivered').
    - `count_less_than` integer — Maximum count (exclusive). Only applicable for engagement types ('opens', 'clicks', 'sent', 'delivered').
    - `count_less_than_or_equal` integer — Maximum count (inclusive). Only applicable for engagement types ('opens', 'clicks', 'sent', 'delivered').
    - `after` string, date — Start date (YYYY-MM-DD). For 'subscribed' type, filters by subscriber_created_at. For engagement types, filters by event date. Not applicable for 'tags', 'subscriber_state', 'attribution', or 'custom_field' types.
    - `before` string, date — End date (YYYY-MM-DD). For 'subscribed' type, filters by subscriber_created_at. For engagement types, filters by event date. Not applicable for 'tags', 'subscriber_state', 'attribution', or 'custom_field' types.
    - `states` string[] — Subscriber lifecycle states. Required for 'subscriber_state' type; ignored for other types. Subscribers matching any of the listed states pass the filter. Strongly recommended to use `['active']` unless you specifically need other states — most subscriber-facing queries elsewhere in the app scope to active subscribers by default.
    - `subscriber_custom_field_id` integer — Id of the custom field whose stored value is being filtered on. Required for 'custom_field' type; ignored for other types.
    - `value` string — Value to compare against. Used by 'custom_field' type together with `comparison`. For the numeric comparisons (`greater_than`, `greater_than_or_equal`, `less_than`, `less_than_or_equal`) the value is parsed as a number; non-numeric stored values are excluded. Ignored when `comparison` is `has_value`.
    - `comparison` 'is' | 'contains' | 'has_value' | 'greater_than' | 'greater_than_or_equal' | 'less_than' | 'less_than_or_equal' — How `value` is matched against the stored custom-field value. `is` is exact equality, `contains` is a case-insensitive substring (blank `value` matches any subscriber that has a value stored for the field), `has_value` matches any non-empty stored value (ignores `value`), `greater_than` / `greater_than_or_equal` / `less_than` / `less_than_or_equal` compare numerically. Only applicable for 'custom_field' type.
    - `latitude` number, float — Center latitude (decimal degrees). Required for the 'location' type. Combined with `longitude` and `radius` to form a bounding box around the point.
    - `longitude` number, float — Center longitude (decimal degrees). Required for the 'location' type.
    - `radius` number — Radius around (`latitude`, `longitude`) in miles. Required for the 'location' type. Subscribers whose primary location falls inside the bounding box pass the filter.
    - `any` union[] — Array of OR conditions. Subscriber activity must match ANY of these conditions. Engagement types accept broadcasts/URLs; 'tags' accepts tag id matchers; 'attribution' accepts attribution sub-conditions ('forms' or 'kit_source'). Not applicable for 'subscribed', 'subscriber_state', 'custom_field', or 'location' types.
      - union
        - BroadcastAnyCondition — Filter by specific broadcast IDs. Subscriber must have interacted with ANY of the specified broadcasts.
          - `type` 'broadcasts', required — Must be 'broadcasts'
          - `ids` integer[], required — Array of broadcast IDs. Subscriber must match ANY of these.
        - UrlAnyCondition — Filter by URL patterns. Only applicable for 'clicks' type. Subscriber must have clicked ANY of the specified URLs.
          - `type` 'urls', required — Must be 'urls'
          - `ids` integer[] — Array of URL IDs. Subscriber must have clicked ANY of these.
          - `urls` string[] — Array of URL patterns. Subscriber must have clicked ANY of these.
          - `matching` 'exact' | 'contains' | 'starts_with' | 'ends_with' — URL matching strategy
        - IdsAnyCondition — Match a list of ids. Used by the 'tags' filter to select tag ids.
          - `type` 'ids', required — Must be 'ids'
          - `matching` integer[], required — Ids the filter should match against.
        - FormsAnyCondition — Attribution sub-condition: matches subscribers whose original signup attribution points at one of the given form / landing-page ids. Ids may refer to either a form or a legacy landing page — the attribution source does not distinguish between the two.
          - `type` 'forms', required — Must be 'forms'
          - `ids` integer[], required — Form / landing-page ids the subscriber's attribution should match.
        - KitSourceAnyCondition — Attribution sub-condition: matches subscribers whose original signup attribution row matches any combination of the supplied Kit source fields. All fields are optional; supplied fields are ANDed together against the same attribution row, and array fields (`source_ids`, `source_names`, `mechanism_ids`) match any value in the array. Known `source_type` values include `form_subscription` (form / landing-page signup), `api_subscription` (added via the API), and `manual` (added by the creator). Multiple entries in the parent `attribution` filter's `any` array are OR-ed together (consistent with `any` semantics elsewhere in this endpoint), so use separate entries to express "kit_source A OR kit_source B".
          - `type` 'kit_source', required — Must be 'kit_source'
          - `source_type` string — Match attribution rows whose `kit_source_type` equals this value.
          - `source_ids` integer[] — Match attribution rows whose `kit_source_id` is in this list.
          - `source_names` string[] — Match attribution rows whose `kit_source_name` is in this list.
          - `mechanism` string — Match attribution rows whose `kit_source_mechanism` equals this value.
          - `mechanism_ids` integer[] — Match attribution rows whose `kit_source_mechanism_id` is in this list.
  - `include` object[] — Optional. Array of `{ type, ...config }` objects naming additional fields to embed on each subscriber row. Valid types: `attribution`, `tags`, `location`, `canceled_at`, `stats`, `custom_fields`. The `stats` type accepts an optional `range: { start, end }` (YYYY-MM-DD dates, defaulting to the last 90 days). The `custom_fields` type adds a `fields` object with all account custom field values (null for fields the subscriber has not set).
    - `type` 'attribution' | 'tags' | 'location' | 'canceled_at' | 'stats' | 'custom_fields', required
    - `range` object — Only used by the `stats` type. Date window for the engagement stats. Defaults to the last 90 days; clamped to the account's data-retention window.
      - `start` string, date
      - `end` string, date

## Response `200`

Returns a list of subscribers matching the filters

- object
  - `subscribers` object[], required
    - `id` string, required
    - `first_name` string, nullable, required
    - `email_address` string, required
    - `created_at` string, required
    - `tag_names` string[]
    - `tag_ids` string[]
    - `attribution` object, nullable — Returned when `include` contains `attribution`.
      - `referrer` string, nullable
      - `utm_source` string, nullable
      - `utm_medium` string, nullable
      - `utm_campaign` string, nullable
      - `utm_term` string, nullable
      - `utm_content` string, nullable
      - `source_type` string, nullable
      - `source_name` string, nullable
      - `source_mechanism` string, nullable
      - `source_mechanism_id` integer, nullable
    - `tags` object[] — Returned when `include` contains `tags`.
      - `id` integer
      - `name` string
    - `location` object, nullable — Returned when `include` contains `location`.
      - `city` string, nullable
      - `state` string, nullable
      - `country` string, nullable
      - `latitude` number, float, nullable
      - `longitude` number, float, nullable
      - `timezone` string, nullable
    - `canceled_at` string, date-time, nullable — Returned when `include` contains `canceled_at`. Reflects the timestamp of the subscriber's most recent state transition.
    - `stats` object — Returned when `include` contains `stats`. Per-subscriber email engagement over the requested date range (defaults to the last 90 days). Counts cover broadcasts, sequences, and email templates. Subscribers with no sends in the range come back with zeroed counts and null timestamps.
      - `sent` integer
      - `opened` integer
      - `clicked` integer
      - `bounced` integer
      - `open_rate` number, float — opened / sent, rounded to 3 decimals (0.0 when nothing was sent).
      - `click_rate` number, float — clicked / sent, rounded to 3 decimals (0.0 when nothing was sent).
      - `last_sent` string, date-time, nullable
      - `last_opened` string, date-time, nullable
      - `last_clicked` string, date-time, nullable
      - `sends_since_last_open` integer
      - `sends_since_last_click` integer
    - `fields` object — Returned when `include` contains `custom_fields`. All account custom field keys, with the subscriber's value or null for fields that have not been set.
  - `pagination` object, required
    - `has_previous_page` boolean, required
    - `has_next_page` boolean, required
    - `start_cursor` string, required
    - `end_cursor` string, required
    - `per_page` integer, required
    - `total_count` integer

## Other responses

- `401` — Returns a 401 if the token and/or account cannot be authenticated

---

[API](https://skmtc.dev/kit/apis/kit-api.md) · [All operations](https://skmtc.dev/kit/apis/kit-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/kit/kit-api/revisions/0df0c90d12da/schema)
