Export events

Retrieves what happened to your business's conversations and contacts in a date range, oldest first: manual control taken or released, alerts, transfers, sentiment, archiving, agent changes and contact field changes. Pair it with GET /messages to build support dashboards in your own system.

GET/events

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 events created from that moment on, inclusive.
untilDatetimeOptionalISO 8601 date and time. Returns events created before that moment. Defaults to now. since and until can be at most 31 days apart.
typesStringOptionalComma-separated event types to include (for example alert_triggered,manual_control_activated). Defaults to all. Values are listed below.
channelStringOptionalComma-separated channels to include. Defaults to all. Contact field changes belong to no channel, so this filter leaves them out. Values: whatsapp, whatsapp_web, instagram, messenger, tiktok, email, sms, web_embed, hubspot_chat, voice.
limitIntegerOptionalEvents per page (default 100, max 500).
cursorStringOptionalThe next_cursor of the previous page. Leave it out on the first request.

Example request

bash
curl -X GET "https://api.eclecticlabs.com/api/external/v2/events?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 get 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/events?since=2026-09-01T00:00:00Z&until=2026-10-01T00:00:00Z&limit=500&cursor=eyJ0IjoiMjAyNi0wOS0wMVQxMjowNTowMCswMDowMCIsInMiOiJjb252ZXJzYXRpb24iLCJpIjoiYzdkOGU5ZjAtMDAwMy0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIn0" \
  -H "X-API-Key: ek_live_your_api_key_here"

Example response

json
{
  "events": [
    {
      "id": "c7d8e9f0-0001-0000-0000-000000000000",
      "type": "sentiment_analyzed",
      "conversation_id": "f3670b13-446b-4127-9623-8b1cd78899f9",
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": "whatsapp",
      "actor_type": "ai_agent",
      "agent": null,
      "user": null,
      "data": { "sentiment": "NEGATIVE" },
      "created_at": "2026-09-01T12:03:40Z"
    },
    {
      "id": "c7d8e9f0-0002-0000-0000-000000000000",
      "type": "alert_triggered",
      "conversation_id": "f3670b13-446b-4127-9623-8b1cd78899f9",
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": "whatsapp",
      "actor_type": "ai_agent",
      "agent": {
        "id": "5d6e7f80-0000-0000-0000-000000000000",
        "name": "Agente de ventas"
      },
      "user": null,
      "data": { "reason": "El cliente pide hablar con una persona" },
      "created_at": "2026-09-01T12:04:05Z"
    },
    {
      "id": "c7d8e9f0-0003-0000-0000-000000000000",
      "type": "manual_control_activated",
      "conversation_id": "f3670b13-446b-4127-9623-8b1cd78899f9",
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": "whatsapp",
      "actor_type": "human",
      "agent": null,
      "user": {
        "id": "8a9b0c1d-0000-0000-0000-000000000000",
        "name": "Camila Rojas",
        "email": "camila@example.com"
      },
      "data": { "reason": null },
      "created_at": "2026-09-01T12:05:00Z"
    },
    {
      "id": "c7d8e9f0-0004-0000-0000-000000000000",
      "type": "contact_field_changed",
      "conversation_id": null,
      "contact_id": "eb2b914a-977e-4ab8-96e7-b886698b3eac",
      "channel": null,
      "actor_type": "human",
      "agent": null,
      "user": {
        "id": "8a9b0c1d-0000-0000-0000-000000000000",
        "name": "Camila Rojas",
        "email": "camila@example.com"
      },
      "data": {
        "source": "crm",
        "changes": [
          { "field": "caso", "custom": true, "from": "Consulta", "to": "Cambio" }
        ]
      },
      "created_at": "2026-09-01T12:07:30Z"
    }
  ],
  "next_cursor": "eyJ0IjoiMjAyNi0wOS0wMVQxMjowNTowMCswMDowMCIsInMiOiJjb252ZXJzYXRpb24iLCJpIjoiYzdkOGU5ZjAtMDAwMy0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIn0"
}

Response fields

  • idUUID of the event.
  • typeEvent type. See the values below.
  • conversation_idUUID of the conversation, or null for contact_field_changed.
  • contact_idUUID of the contact.
  • channelChannel of the conversation, such as whatsapp or instagram, or null for contact_field_changed.
  • actor_typeWho caused the event. See the values below.
  • agentAI agent that caused it (id and name), when known, or null.
  • userTeam member who caused it from Eclectic (id, name and email), or null.
  • dataType-specific fields. See the types below.
  • created_atDate and time of the event (ISO 8601, UTC).

Event types

Each type lists what it carries in data.

  • manual_control_activatedA person took over the conversation and the AI stopped replying. data: reason (can be null).
  • manual_control_releasedThe conversation went back to the AI, by hand or on a timer. data: reason.
  • manual_control_lockedManual control was pinned and the AI does not come back on its own. data: reason.
  • manual_control_unlockedThe manual control pin was removed. data: reason.
  • alert_triggeredThe conversation was escalated to the team with an alert. data: reason.
  • transfer_acceptedThe AI transferred the conversation to a person or another number. data: reason, target_user, attempt_number.
  • transfer_rejectedA transfer could not be made. data: reason, target_user, attempt_number.
  • transfer_fallback_requiredNo transfer target was available. data: reason, target_user, attempt_number.
  • sentiment_analyzedThe conversation's sentiment was analyzed. data: sentiment (POSITIVE, NEUTRAL or NEGATIVE).
  • conversation_archivedThe conversation was archived. data: origin.
  • conversation_unarchivedThe conversation was unarchived. data: origin.
  • conversation_resolvedA person marked the case as resolved. data: reason.
  • agent_assignedAn AI agent was assigned to the conversation. data: from_agent, to_agent.
  • agent_switchedThe conversation's AI agent was changed. data: from_agent, to_agent.
  • agent_removedThe AI agent was removed from the conversation. data: from_agent, to_agent.
  • contact_field_changedOne or more fields of a contact changed. data: source and changes, a list of field, custom (true for custom fields), from and to.

actor_type values

  • ai_agentAn Eclectic AI agent.
  • humanA member of your team, from Eclectic or from the channel's own app (such as WhatsApp Business). In the second case user is null.
  • apiA call to the Eclectic public API.
  • systemAutomatic rules, timers and integrations (for example, the AI taking a conversation back after the team stopped replying).

Notes

  • Repeat the request with each response's next_cursor until it is null. A page can hold fewer events 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.
  • Events of conversations linked to a contact are exported. Test conversations, internal chats and internal platform events (Shopify orders, follow-ups, agent instructions) are not included.
  • Contact field history exists since August 4, 2026. One contact_field_changed event groups every field that changed together.
  • This endpoint has a limit of 120 requests per minute per business, separate from GET /messages. Beyond that you get a 429.
  • Possible errors: 400 (invalid parameters, such as a window longer than 31 days, an unknown type or an invalid cursor), 401 (invalid or missing API key), 429 (rate limit).