Skip to content
ChatterfyHelp Center
HomeGeneralCRMAI ManagerTrackerPlatformsAPIFAQUpdate log
Getting started
Instructions
How to get chats and messages via API
How to send a message to a client via API
How to update a chat via API: status, tags, assignee, fields
Chat filters in the API
How to export all chats via API
New real-time messages via API
Analytics and Tracker via API
Help Center
API and AI
  1. API
  2. Instructions
  3. Chat filters in the API

Chat filters in the API

Chat filters are conditions used by the API to select chats: for example, 'unread', 'with the tag Paid', or 'came from Google'. The same filter works in search, counting, exporting, and event subscrip

Updated November 2, 20265 min
Chat filters are conditions used by the API to select chats: for example, 'unread', 'with the tag Paid', or 'came from Google'. The same filter works in search, counting, exporting, and event subscriptions.
This article covers how the filter is structured, all fields and operators, and ready-to-use examples you can copy.



Where chat filters work

Request
What it does
POST /chats/v1/search
List of chats
POST /chats/v1/stats
Number of chats in each status
POST /chats/v1/export
Export all chats — How to export all chats via API
POST /chats/v1/realtime
Real-time chat events — New real-time messages via API
The filter is passed in the filter field of the request body, next to bot_id.



Single-condition filter

A filter condition consists of three parts: field, operator, and value. For example, the condition below selects chats with the status manual:
Тело запросаjson
{
  "bot_id": "ID_БОТА",
  "filter": { "field": "status", "operator": "is", "value": "manual" }
}
Read as: 'status — equals — manual'.



Multiple conditions: and and or groups

To combine filter conditions, place them in a group with logic and filters fields. "logic": "and" — all conditions must be met, "or" — at least one must be met.
Чаты у операторов с непрочитанными сообщениямиjson
{
  "bot_id": "ID_БОТА",
  "filter": {
    "logic": "and",
    "filters": [
      { "field": "status", "operator": "is", "value": "manual" },
      { "field": "incoming_unread_count", "operator": "more_number", "value": 0 }
    ]
  }
}
Groups can be nested within each other. Here are chats with a tag managed by an operator or AI:
Вложенная группаjson
{
  "logic": "and",
  "filters": [
    { "field": "tags", "operator": "has_any", "value": ["ID_ТЕГА"] },
    {
      "logic": "or",
      "filters": [
        { "field": "status", "operator": "is", "value": "manual" },
        { "field": "status", "operator": "is", "value": "ai" }
      ]
    }
  ]
}
Single filter limitations:
  • up to 64 conditions and groups;
  • up to 5 nesting levels;
  • up to 100 values in a single list.



Filter fields: search, status, assignee

The field field in the filter condition is what is being checked. Search by client, chat status, who wrote last, unread messages, and assignee:
Field
What it checks
Operators
Value
query
Client name, username, or Telegram ID
No operator
Text up to 128 characters
status
Chat status
is, is_any, is_not
manual, ai, waiting, ignore, blocked, error, stopped, finished, start, lead
last_message_sender_type
Who wrote last
is, is_any, is_not
incoming — client, outcoming — your side
incoming_unread_count
Unread client messages
Numeric
Number
assign_id
Assignee
is, is_any, is_not, is_empty, is_not_empty
Space member ID
What is ignore
ignore is not a separate status, but a question: the chat is in manual status, and the last message came from the client. This means the client must be answered.



Filter fields: tags, custom fields, Tracker

Tags and custom fields are filtered only by id, not by name. For custom_fields and tracker_fields, you also need a key in the condition:
Field
What it checks
Operators
Value
tags
Chat tags
has_any, has_all, has_only, has_none, is_not_empty
List of tag ids
custom_fields
Field value
is, is_not, is_any
Plus key — field id
tracker_fields
Tracker label, for example utm_source
is, is_not, is_any
Plus key — label name
tracker_events
Tracker events, for example purchase
has_any, has_all, has_none, is_not_empty
For example, ["purchase"]



Filter fields: dates, amount, scenario, id

Dates in the filter — created_at and updated_at, lead amount — cost, position in the scenario — step and sales stage:
Field
What it checks
Operators
Value
created_at
When the chat was created
before, after, between
Date
updated_at
Time of the last message
before, after, between
Date
cost
Amount associated with the lead
Numeric
Number
current_flow_id, current_step_id
Current scenario and step
is, is_any, is_not, is_empty, is_not_empty
id
current_sale_stage_id
Sales stage
is, is_any, is_not, is_not_empty
id
id, external_id
chat id or Telegram client id
is, is_any, is_not
id



Filter operators

Operator
Value
Meaning
is / is_not
Single value
Equal to / Not equal to
is_any
List
Equal to any from the list
is_empty / is_not_empty
No value
Field is empty / filled
has_any
List
Contains at least one of the values
has_all
List
Contains all values, and possibly others
has_only
List
Exactly these values, and no others.
has_none
List
None of the values
before / after
Date
Strictly earlier / strictly later
between
Two dates
In the range, inclusive of boundaries
more_number, less_number, more_equal_number, less_equal_number, equal_number, not_equal_number
Number
Greater than, less than, greater than or equal to, less than or equal to, equal to, not equal to



Dates in filters and time zones

You can write the date in full — 2026-10-01T00:00:00Z — or just as a day: 2026-10-01. To have the day calculated according to your time rather than UTC, add timezone:
Чаты, появившиеся в октябре по Москвеjson
{ "field": "created_at", "operator": "between", "value": ["2026-10-01", "2026-10-31"], "timezone": "Europe/Moscow" }



Filter examples: who has not been answered

Client not answered

Status ignore: chat is in manual mode, and the last message was sent by the client.
Фильтрjson
{ "field": "status", "operator": "is", "value": "ignore" }

Unanswered, and chat is unassigned

Status ignore and empty assignee: assign_id with operator is_empty.
Фильтрjson
{
  "logic": "and",
  "filters": [
    { "field": "status", "operator": "is", "value": "ignore" },
    { "field": "assign_id", "operator": "is_empty" }
  ]
}



Filter examples: purchases, fields, dates

Purchased, came from Google

Tracker label utm_source is equal to google, and the lead has a purchase event in tracker_events.
Фильтрjson
{
  "logic": "and",
  "filters": [
    { "field": "tracker_fields", "key": "utm_source", "operator": "is", "value": "google" },
    { "field": "tracker_events", "operator": "has_any", "value": ["purchase"] }
  ]
}

City from field — Moscow

Custom field 'City' is equal to 'Moscow'. In key — field ID from GET /bots/v1/{bot_id}/custom-fields.
Фильтрjson
{ "field": "custom_fields", "key": "ID_ПОЛЯ_ГОРОД", "operator": "is", "value": "Москва" }

Correspondence for the last 24 hours

Last message after the specified time: updated_at with the after operator.
Фильтрjson
{ "field": "updated_at", "operator": "after", "value": "2026-10-29T12:00:00Z" }



How many chats are in each status

The number of chats by status is returned by POST /chats/v1/stats. Pass the same filter as in the search, or a request without a filter—the total number total and the counters statuses will be returned:
Запросbash
curl -X POST 'https://api.chatterfy.ai/public-api/chats/v1/stats' \
  -H 'ApiKey: ВАШ_КЛЮЧ' \
  -H 'Content-Type: application/json' \
  -d '{"bot_id": "ID_БОТА"}'
Ответjson
{
  "total": 3634,
  "statuses": [
    { "status": "waiting", "count": 2980 },
    { "status": "manual", "count": 605 },
    { "status": "ai", "count": 33 },
    { "status": "blocked", "count": 16 },
    { "status": "ignore", "count": 421 }
  ]
}
ignore chats are part of manual chats, so they are not counted twice in total.



Frequently Asked Questions

A 400 error in the filter means the condition is incorrect. The message field in the response states which condition is wrong and what was expected, for example: filter.filters[1]: "tags" does not support operator "is". An unknown field or operator always results in an error, not an empty list.

A filter by custom field searches by field ID: you need the id from GET /bots/v1/{bot_id}/custom-fields in the key, not its key. The value must match completely.

No, you cannot search for chats by message text. query searches only by the client's name, username, and Telegram ID.

No, the tag filter accepts only the tag ID. Get the ID from GET /bots/v1/{bot_id}/tags.

The API filter result may differ from the application because the API adds key permissions to the filter: if the role only sees assigned chats, the filter will not expand that scope. Also, the search updates with a delay of a second or two.



Related

How to get chats and messages via API
Chats and messages via the API are read in two requests: first the list of bot chats, then the messages of the specific chat. This is the same as opening the bot in the application and tapping on a co
How to export all chats via API
Chat export is a way to retrieve all of a bot's chats at once: into a spreadsheet, your CRM, or a database. It reads a snapshot of the chats at the moment of initiation, so it doesn't skip or repeat a
New real-time messages via API
Real-time is a way to learn about new messages and changes in chats immediately, without constant polling. Chatterfy sends an event to your program as soon as something happens. Article for programmer
How to update a chat via API: status, tags, assignee, fields
Modifying a chat via API is the same as editing a client card in the app: changing the status, assignee, tags, and fields. Everything is done with a single PATCH request, in which you pass only what y

Was this article helpful?

BackHow to update a chat via API: status, tags, assignee, fieldsNextHow to export all chats via API

On this page

  • Where chat filters work
  • Single-condition filter
  • Multiple conditions: and and or groups
  • Filter fields: search, status, assignee
  • Filter fields: tags, custom fields, Tracker
  • Filter fields: dates, amount, scenario, id
  • Filter operators
  • Dates in filters and time zones
  • Filter examples: who has not been answered
  • Client not answered
  • Unanswered, and chat is unassigned
  • Filter examples: purchases, fields, dates
  • Purchased, came from Google
  • City from field — Moscow
  • Correspondence for the last 24 hours
  • How many chats are in each status
  • Frequently Asked Questions
  • Related