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
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 anything, no matter how many chats there are.
In this article, you will learn how to export all chats, a ready-to-use script for saving to CSV, and how to retrieve only subsequent changes.
Requirements
- An API key with the Space controller role or higher — exporting requires the
chat.exportpermission. More details — API Key Permissions: Which Role to Assign.
- Bot ID — First API request in 5 minutes.
How chat export differs from search
| Search `/chats/v1/search` | Export `/chats/v1/export` |
|---|---|---|
How many chats can be scrolled | Up to 10,000 | No limit |
Duplicates and skips | Possible: the list changes while you are reading it | No: it reads a snapshot at the moment of the first request |
How long does a cursor last | No limit | 5 minutes after each page |
Purpose | Displaying a list, finding a chat | Retrieving everything in bulk |
Export all bot chats
All bot chats are exported using
POST /chats/v1/export with the bot_id in the body — page by page, via cursor, without the 10,000 chat limit. No more than 5 minutes should pass between pages.Count chats
This way you know how many chats to expect. The filter is the same as the one used in the export, or you can use no filter:Запросbashcurl -X POST 'https://api.chatterfy.ai/public-api/chats/v1/stats' \ -H 'ApiKey: ВАШ_КЛЮЧ' \ -H 'Content-Type: application/json' \ -d '{"bot_id": "ID_БОТА"}'The total number is in thetotalfield.Request the first page
Запросbashcurl -X POST 'https://api.chatterfy.ai/public-api/chats/v1/export' \ -H 'ApiKey: ВАШ_КЛЮЧ' \ -H 'Content-Type: application/json' \ -d '{"bot_id": "ID_БОТА", "limit": 100}'The response is structured the same way as for search: chats are indata, the next page is inpagination.Navigate through pages without pauses
Repeat the same request, addingcursorto the body with the valuenext_cursorfrom the previous response.Stop at the last page
Whenhas_more: falseis received, the export is finished.
The Cursor is valid for 5 minutes
If more than 5 minutes pass between pages, the API will return a
cursor_expired error. In that case, restart the export, without a cursor.The filter also works for exports — for example, only chats from October or only those with a tag. How to set it up is in the article Chat filters in the API.
Ready-to-use Python script: all chats in CSV
The script exports all bot chats to a
chats.csv file, which can be opened in Excel and Google Sheets. All you need is Python 3 — there is nothing else to install.Save the script
Copy the code into anexport_chats.pyfile. In theBOT_IDline, replaceID_БОТАwith your bot's ID.export_chats.pypythonimport csv import json import os import time import urllib.error import urllib.request API = "https://api.chatterfy.ai/public-api" KEY = os.environ["CHATTERFY_API_KEY"] BOT_ID = "ID_БОТА" def call(path, body): request = urllib.request.Request( API + path, data=json.dumps(body).encode("utf-8"), method="POST", headers={"ApiKey": KEY, "Content-Type": "application/json"}, ) try: with urllib.request.urlopen(request, timeout=30) as response: return json.load(response) except urllib.error.HTTPError as error: if error.code == 429: time.sleep(int(error.headers.get("Retry-After", "5"))) return call(path, body) raise body = {"bot_id": BOT_ID, "limit": 100} total = 0 with open("chats.csv", "w", newline="", encoding="utf-8-sig") as file: writer = csv.writer(file) writer.writerow(["id", "name", "username", "status", "created_at", "last_message"]) while True: page = call("/chats/v1/export", body) for chat in page["data"]: last_message = (chat.get("last_message") or {}).get("content", "") writer.writerow([chat["id"], chat.get("name", ""), chat.get("username", ""), chat["status"], chat["created_at"], last_message]) total += len(page["data"]) print("Выгружено чатов:", total) if not page["pagination"]["has_more"]: break body["cursor"] = page["pagination"]["next_cursor"] print("Готово: chats.csv")Pass the key and run
Терминалbashexport CHATTERFY_API_KEY='ВАШ_КЛЮЧ' python3 export_chats.pyPowerShellpowershell$env:CHATTERFY_API_KEY = "ВАШ_КЛЮЧ" python export_chats.pyOpen the file
Thechats.csvfile will appear in the same folder. It contains the chat ID, name, username, status, creation date, and the text of the last message.
The key is passed via the
CHATTERFY_API_KEY environment variable, rather than being written to the file — this way, the script can be shown and shared without risk. If the API returns 429, the script will wait and continue automatically.Retrieve only updated chats
After the first full export, you don't need to retrieve everything every time. Request only chats that have had new messages since the last time:
Remember the start time
Save the current time before each synchronization.Request modified chats
Next time, send a search request withsort: ascand a filter byupdated_at— the time of the last message. The lower bound is the time of the previous run with a buffer of a few minutes, the upper bound is the current time:Тело запроса /chats/v1/searchjson{ "bot_id": "ID_БОТА", "limit": 100, "sort": "asc", "filter": { "field": "updated_at", "operator": "between", "value": ["2026-10-29T11:55:00Z", "2026-10-30T12:00:00Z"] } }Update records by id
If you already have the chat, replace it with the new version. This way, duplicates caused by the time buffer won't cause any issues.
Use
between, not after: between includes the boundaries, so a chat with a message exactly at the moment of the boundary will not be lost.FAQ
Related
Was this article helpful?

