ChatMaxima Docs

Conversations Export API - Sync Message History on a Schedule

Pull your ChatMaxima conversation history as flat message rows with the export API, using date windows and cursor pagination for a reliable daily sync.

Overview

The Conversations Export API returns your team's conversation history as flat message rows. Each row carries the contact's name and mobile number along with the message itself, plus the conversation's current status, department, labels, and the agent who replied, so you can rebuild full conversations in your own database, CRM, or data warehouse.

This is a pull endpoint. Your system calls it on a schedule (for example, a nightly job) and pages through everything inside a date window. It is the simplest way to keep an external copy of your conversations in sync.

A typical use case is a daily export into a warehouse or CRM: every night your job pulls the previous day's messages and loads them into your own tables for reporting or analytics.

Endpoint

GET https://chatmaxima.com/api/v2/conversations/export/

Authentication

Send your API key as the raw value of the Authorization header. You can find the key in the dashboard under Developer settings.

curl -G https://chatmaxima.com/api/v2/conversations/export/ \
  -H "Authorization: YOUR_API_KEY" \
  --data-urlencode "cursor=0" \
  --data-urlencode "limit=500"

Query parameters

ParameterTypeDefaultDescription
cursorinteger0The last message_id you received. Pass meta.next_cursor from the previous response to fetch the next page. Paging is keyed on the message id, so you never miss or duplicate a row.
limitinteger500Number of rows per page. Minimum 1, maximum 1000.
fromstringcurrent UTC day startLower bound on message time. Accepts ISO 8601 (2026-07-01T00:00:00) or YYYY-MM-DD HH:MM:SS.
tostringcurrent UTC day endUpper bound on message time. Same format as from.

Note: Use the T separated ISO format (2026-07-01T00:00:00) when building URLs, since it has no space to encode. The server accepts both forms.

Date window rules

Every export request runs against a bounded date window:

  • No dates given - the window defaults to the current UTC day, from 00:00:00 to 23:59:59. The applied window is echoed back in meta.from and meta.to.
  • Only from given - to is automatically set to 3 days after from.
  • Only to given - from is automatically set to 3 days before to.
  • Maximum span is 3 days - a wider window is rejected.

Requests that break the rules return HTTP 400 with an error code:

Error codeMeaning
INVALID_DATE_FORMATfrom or to is not a parseable datetime.
INVALID_DATE_RANGEto is earlier than from.
DATE_RANGE_TOO_LARGEThe window between from and to exceeds 3 days.

To export more than 3 days of history, walk the range in consecutive windows (see the backfill example below).

Sample response

{
  "status": "success",
  "code": 200,
  "message": "Conversation export",
  "data": [
    {
      "message_id": 340117,
      "conversation_alias": "fyz2ul5qki_923001234567",
      "lead_id": 366246,
      "contact_name": "Ahmed Raza",
      "contact_mobile": "923001234567",
      "contact_email": "",
      "direction": "inbound",
      "message_type": "incoming",
      "message_text": "Where is my order?",
      "media_url": null,
      "agent_name": null,
      "message_datetime": "2026-07-08 10:12:48.7011",
      "status": "Open",
      "department": "Customer Service",
      "labels": "Delivery,Priority"
    },
    {
      "message_id": 340118,
      "conversation_alias": "fyz2ul5qki_923001234567",
      "lead_id": 366246,
      "contact_name": "Ahmed Raza",
      "contact_mobile": "923001234567",
      "contact_email": "",
      "direction": "outbound",
      "message_type": "bot",
      "message_text": "Your order is out for delivery and arrives today.",
      "media_url": null,
      "agent_name": null,
      "message_datetime": "2026-07-08 10:12:49.1233",
      "status": "Open",
      "department": "Customer Service",
      "labels": "Delivery,Priority"
    },
    {
      "message_id": 340119,
      "conversation_alias": "fyz2ul5qki_923001234567",
      "lead_id": 366246,
      "contact_name": "Ahmed Raza",
      "contact_mobile": "923001234567",
      "contact_email": "",
      "direction": "outbound",
      "message_type": "outgoing",
      "message_text": "Apologies for the delay, it is on the way now.",
      "media_url": null,
      "agent_name": "Sana",
      "message_datetime": "2026-07-08 10:15:02.8890",
      "status": "Resolved",
      "department": "Customer Service",
      "labels": "Delivery,Priority"
    }
  ],
  "meta": {
    "count": 3,
    "limit": 500,
    "next_cursor": "340119",
    "has_more": false,
    "from": "2026-07-08 00:00:00",
    "to": "2026-07-08 23:59:59"
  }
}

Response fields

Each object in data is a single message.

FieldTypeDescription
message_idintegerStable unique id for the message. Also the cursor key. Use it to deduplicate on your side.
conversation_aliasstringGroups messages that belong to the same conversation or thread.
lead_idintegerThe contact's id in ChatMaxima.
contact_namestringThe contact's display name.
contact_mobilestringThe contact's mobile number.
contact_emailstringThe contact's email, when available.
directionstringinbound for messages from the customer, outbound for replies from a bot or agent.
message_typestringRaw type such as incoming, outgoing, bot, or broadcast.
message_textstringThe message body.
media_urlstringURL of the attached media, when the message carries an image, audio, or document. null for text-only messages.
agent_namestringThe agent who sent the message. null for bot or automated messages.
message_datetimestringWhen the message was sent, with microsecond precision.
statusstringThe conversation's current status, such as Open, Pending, or Resolved.
departmentstringThe department the conversation is currently assigned to.
labelsstringComma-separated list of labels on the conversation. null when no labels are set.

Note: status, department, and labels reflect the conversation's current state, not the state at the time the message was sent. Every message of the same conversation carries the same values.

The meta object describes the page, the cursor, and the applied date window.

FieldTypeDescription
countintegerNumber of rows in this page.
limitintegerThe limit that was applied.
next_cursorstringPass this as cursor on the next call. null when there is nothing more to fetch.
has_morebooleantrue while more pages are available. Keep paging while this is true.
fromstringThe lower bound that was applied, including defaults.
tostringThe upper bound that was applied, including defaults.

Daily incremental pull

The recommended pattern pulls one full day with an explicit window and pages through it with the cursor. Cursor paging is keyed on message_id, so re-running a window never creates gaps or duplicates.

  1. Set from and to to the day you want to export.
  2. Call with cursor=0, read the rows from data, and store them.
  3. If meta.has_more is true, call again with cursor set to meta.next_cursor and repeat.
  4. When meta.has_more is false, the day is complete.
# Pull one day, first page
curl -G https://chatmaxima.com/api/v2/conversations/export/ \
  -H "Authorization: YOUR_API_KEY" \
  --data-urlencode "from=2026-07-07T00:00:00" \
  --data-urlencode "to=2026-07-07T23:59:59" \
  --data-urlencode "cursor=0" \
  --data-urlencode "limit=500"

# Next page of the same day, continue from next_cursor
curl -G https://chatmaxima.com/api/v2/conversations/export/ \
  -H "Authorization: YOUR_API_KEY" \
  --data-urlencode "from=2026-07-07T00:00:00" \
  --data-urlencode "to=2026-07-07T23:59:59" \
  --data-urlencode "cursor=340119" \
  --data-urlencode "limit=500"

If you call without any dates, you get the current UTC day, which is handy for intraday syncs of today's traffic.

Backfill older history

To backfill more than 3 days, walk the history in consecutive windows of up to 3 days each, paging every window to completion before moving to the next:

# Window 1
from=2026-07-01T00:00:00  to=2026-07-03T23:59:59
# Window 2
from=2026-07-04T00:00:00  to=2026-07-06T23:59:59
# ... and so on until you reach today

Best practices

  • Page until has_more is false - one call returns at most limit rows, so always loop within a window.
  • Deduplicate on message_id - safe to re-run a job without creating duplicates.
  • Use explicit from/to in scheduled jobs - the no-date default always means "today in UTC", so a nightly job that runs after midnight should pass the previous day explicitly.
  • Keep windows at 3 days or less - wider ranges return DATE_RANGE_TOO_LARGE; split backfills into consecutive windows.
  • Keep your key server side - never expose the API key in a browser or mobile app.

Next steps

في هذه الصفحة