Recipe: export your history and keep it in sync
Last updated: 11 November 2026 · 10 min read
This recipe combines two jobs: getting the workspace's whole history once as a file, and then keeping your own database in step with Clomni. Use it when moving to another system, keeping an archive or filling an analytics warehouse.
Steps
-
1
What you get
- Conversations, messages and contacts in one gzip file, one object per line.
- After that, only the objects that changed, a few minutes behind, or right away by webhook.
- A way to recover events missed while your server was down, from the last 30 days.
-
2
Scopes you need
exports:run(high risk): bulk export. In the review describe the purpose, the system the file goes to, how often you export and how long you keep the file and how you delete it.- For ongoing sync:
conversations:read,messages:read,contacts:read(medium risk). Take only the resources you need. - For missed events:
events:read(medium risk), together with each topic's read scope.
The "Data export" preset selects
exports:runandevents:read. -
3
1. Start the export
resourcestakes one or more ofconversations,messages,contacts; without it all three are exported.sinceanduntilare ISO 8601 times and filter onupdated_at.curl -X POST "https://api.clomni.ai/v1/exports" \ -H "Authorization: Bearer clomni_pat_xxx" \ -H "Content-Type: application/json" \ -d '{"resources": ["conversations", "messages", "contacts"], "since": "2026-01-01T00:00:00Z", "until": "2026-11-01T00:00:00Z"}'The answer is
202 Acceptedwith the job'sidandstatus: "queued". -
4
2. Wait until it is ready
Check every 15-30 seconds:
curl "https://api.clomni.ai/v1/exports/15" \ -H "Authorization: Bearer clomni_pat_xxx"
status:queued,running,done,failed. When it isdone, the answer hasdownload_urlanddownload_expires_at. The link works for 1 hour: if it has expired, read the export again and you get a new link. When it isfailed, the reason is inerror. -
5
3. Read the file
The file is gzipped JSON Lines: each line is
{"type": ..., "data": {...}}.typeisconversation,messageorcontact, anddatais the same object the sync endpoints return. Read the file line by line instead of loading it all into memory:curl -s "$DOWNLOAD_URL" | gunzip | head -n 3
attachments[].urlin a message is a short-lived link. If you need the files, download them as soon as the export is ready. If a link has expired, read the message again withGET /v1/conversations/{conversation_id}/messagesto get a fresh one. -
6
4. Then fetch only what changed
Do not repeat the export every day. After loading the file, use the sync endpoints:
curl "https://api.clomni.ai/v1/sync/messages?updated_since=2026-11-01T00:00:00Z&limit=100" \ -H "Authorization: Bearer clomni_pat_xxx"
GET /v1/sync/conversations,GET /v1/sync/messagesandGET /v1/sync/contactsreturn objects ordered by(updated_at, id).- For the next page send
next_cursorasafter; whenhas_moreisfalse, you are done. - Store the largest
updated_at, start next time 2 minutes earlier than it, and write objects byid. - Running every 5-15 minutes is enough. The limit is 60 requests a minute per token, so use
limit=100.
To get new messages right away add the
message.createdwebhook and let the sync fill the gaps. See App webhooks and events: setup, topics, signature verification. -
7
5. Recover missed events
If your server was down, take the last 30 days of events from the feed, with the same
ids as the webhooks:curl "https://api.clomni.ai/v1/events?types=message.created&limit=100" \ -H "Authorization: Bearer clomni_pat_xxx"
Each topic's read scope is needed as well:
events:readalone returns an empty list. Events are written only while the workspace has an active developer token or installation, so events from before the token was created are not in the feed. -
8
For a reporting dashboard
If Power BI or another BI tool only needs totals, use
reports:read(low risk) instead of an export: conversation counts, first response and resolution times, totals per agent, inbox and team. Times are in Unix seconds:curl "https://api.clomni.ai/v1/reports?metric=conversations_count&type=account&since=1793491200&until=1794096000&group_by=day&timezone_offset=4" \ -H "Authorization: Bearer clomni_pat_xxx"
All report endpoints: Scopes and endpoints: reports, CSAT, SLA.
-
9
Limits and data protection
- One export runs at a time per workspace: a second request gets 409
conflict. - 6 exports per 24 hours: over the limit you get 429
rate_limited. Do not retry automatically. - An unknown resource or a wrong time format returns 400
invalid_request. - The file holds customers' personal data and messages. Store it encrypted, limit access, and delete it after the period you named in the review. When the app is deleted, data taken from Clomni must be deleted within 30 days.
- One export runs at a time per workspace: a second request gets 409
-
10
Common mistakes
- The export is repeated every day and the daily limit runs out. Export once, then use sync.
- The whole file is loaded into memory. Read it line by line.
download_urlis used after it expired.GET /v1/exports/{export_id}gives a new link.- In a sync object the conversation
idis taken for the dashboard number. The internal ID is inid, the dashboard number innumber(in a message,conversation_number). - The dashboard number is passed to the
conversation_idparameter of/v1/sync/messages. It expects the internalidof the sync conversation object. - ISO 8601 and Unix seconds get mixed up: sync and exports use ISO 8601, the older lists and reports use Unix seconds.
- The regular lists (
GET /v1/conversations) are paged through to copy everything. The order shifts between pages and objects are lost or come twice. Use the sync endpoints.
All export and event endpoints: Scopes and endpoints: calls, webhooks, events, exports.