Export messages

Retrieve every message of your business in a date range, across all customer channels, oldest first. Use it to load conversations into your own analytics system.

GET/messages

Authentication

This endpoint authenticates with your API key sent in the X-API-Key header (ek_live_... format). You can manage your API keys from the Dev Tools section of the dashboard.

Query parameters

ParameterTypeRequiredDescription
sinceDatetimeRequiredISO 8601 date and time. Returns messages created at or after it.
untilDatetimeOptionalISO 8601 date and time. Returns messages created before it. Defaults to now. since and until can be at most 31 days apart.
channelStringOptionalComma-separated channels to include. Defaults to all. Values: whatsapp, whatsapp_web, instagram, messenger, tiktok, email, sms, web_embed, hubspot_chat, voice.
limitIntegerOptionalMessages per page (default 100, max 500).
cursorStringOptionalThe next_cursor of the previous page. Omit it on the first request.

Example request

bash
curl -X GET "https://api.eclecticlabs.com/api/external/v2/messages?since=2026-09-01T00:00:00Z&until=2026-10-01T00:00:00Z&limit=500" \
  -H "X-API-Key: ek_live_your_api_key_here"

To request the next page, repeat the request with the response's next_cursor as cursor:

bash
curl -X GET "https://api.eclecticlabs.com/api/external/v2/messages?since=2026-09-01T00:00:00Z&until=2026-10-01T00:00:00Z&limit=500&cursor=eyJ0IjoiMjAyNi0wOS0wMVQxMjowMjowMCswMDowMCIsImMiOiJ3aGF0c2FwcCIsImkiOiJhMWIyYzNkNC0wMDAyLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAifQ" \
  -H "X-API-Key: ek_live_your_api_key_here"

Example response

json
{
  "messages": [
    {
      "id": "a1b2c3d4-0001-0000-0000-000000000000",
      "conversation_id": "f3670b13-446b-4127-9623-8b1cd78899f9",
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": "whatsapp",
      "direction": "inbound",
      "sender_type": "contact",
      "agent": null,
      "user": null,
      "type": "text",
      "text": "Hola, ¿tienen despacho a regiones?",
      "media": null,
      "reply_to_id": null,
      "status": "RECEIVED",
      "error": null,
      "created_at": "2026-09-01T12:01:10Z"
    },
    {
      "id": "a1b2c3d4-0002-0000-0000-000000000000",
      "conversation_id": "f3670b13-446b-4127-9623-8b1cd78899f9",
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": "whatsapp",
      "direction": "outbound",
      "sender_type": "ai_agent",
      "agent": {
        "id": "5d6e7f80-0000-0000-0000-000000000000",
        "name": "Agente de ventas"
      },
      "user": null,
      "type": "text",
      "text": "¡Hola! Sí, despachamos a todo Chile.",
      "media": null,
      "reply_to_id": null,
      "status": "READ",
      "error": null,
      "created_at": "2026-09-01T12:02:00Z"
    }
  ],
  "next_cursor": "eyJ0IjoiMjAyNi0wOS0wMVQxMjowMjowMCswMDowMCIsImMiOiJ3aGF0c2FwcCIsImkiOiJhMWIyYzNkNC0wMDAyLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAifQ"
}

Response fields

  • idUUID of the message.
  • conversation_idUUID of the conversation the message belongs to.
  • contact_idUUID of that conversation's contact.
  • channelChannel of the message, such as whatsapp or instagram.
  • directioninbound if the contact sent it, outbound if your business did.
  • sender_typeWho sent the message. See the values below.
  • agentAI agent that replied (id and name), or null.
  • userTeam member who replied from Eclectic (id, name and email), or null.
  • typeMessage type: text, image, audio, document, template, and so on.
  • textMessage text. Can be empty for file-only messages.
  • mediaAttached file (id, filename and content_type), or null.
  • reply_to_idUUID of the message it replies to, or null.
  • statusERROR, DELIVERED, RECEIVED or READ.
  • errorDelivery error detail, or null.
  • created_atDate and time of the message (ISO 8601, UTC).

sender_type values

sender_type separates replies from AI, from your team and from your integrations.

  • contactThe customer.
  • ai_agentAn Eclectic AI agent.
  • humanA member of your team, from Eclectic or from the channel's own app (such as WhatsApp Business).
  • apiA message sent through the Eclectic public API.
  • automationCampaigns, flows and system messages.

Notes

  • Repeat the request with each response's next_cursor until it is null. A page can hold fewer messages than limit; only a null next_cursor means there are no more.
  • Each request covers 31 days at most. To export a longer period, request one month at a time.
  • For incremental sync, request again from the last created_at you stored minus a few minutes, and skip ids you already have. Some channels record a message shortly after it happened, and the overlap keeps those messages from being missed.
  • Conversations linked to a contact are exported. WhatsApp groups, test conversations and internal chats are not included. When a number is connected to both WhatsApp Web and the WhatsApp Business API, each message recorded on both appears once, under the whatsapp channel; messages that exist only on WhatsApp Web appear under whatsapp_web.
  • Files come as a reference in media. To download one, request a URL with GET /media/:id using the media id.
  • This endpoint and GET /contacts/:uuid/timeline share a limit of 120 requests per minute per business. Beyond that you get a 429.
  • Possible errors: 400 (invalid parameters, such as a window longer than 31 days or an invalid cursor), 401 (invalid or missing API key), 429 (rate limit).