Events
The event feed: the first message to a lead and the lead's reply. Read it with a cursor to learn about changes without scanning every lead.
#The lead.first_message_sent event
A first message was sent to the lead. data.first_message is present only with include_text=true.
Attributes
objectstringObject type, alwaysevent.idstringEvent ID:evt_followed by 32 hexadecimal characters. The deduplication key. Format^evt_[a-f0-9]{32}$.api_versionstringEvent format version. Always"2026-10-18".timestampstring (date-time)When the fact occurred.testbooleanAlwaysfalse.typestringEvent type. Always"lead.first_message_sent".dataobjectEvent data.Child attributes
organization_idstring (uuid)Organization where the event occurred.workspaceobjectWorkspace at the time of the event.campaignobject or nullCampaign at the time of the event. Can benull.leadobjectLead snapshot.Child attributes
idstring (uuid)Lead ID.usernamestring or nullTelegram username without@. Can benull.statusstringLead status at the time of the event. Values:newcontactedcompletedrepliedblockedfailedsuspendeddeletedopted_outunknownfieldsobjectContact record fields at the time of the event.Child attributes
- Record ID in an external CRM, passed when the contacts were uploaded.
nullifrecord_id_statusis notvalid. Up to 128 characters. - First name. Up to 1024 characters.
- Last name. Up to 1024 characters.
- Company. Up to 1024 characters.
- Job title. Up to 1024 characters.
- Website. Up to 1024 characters.
- Contact source. Up to 1024 characters.
- The
utm_sourcetag. Up to 1024 characters. - The
utm_mediumtag. Up to 1024 characters. - The
utm_campaigntag. Up to 1024 characters.
fields_truncatedbooleantrueif some values were shortened.record_id_statusstringReliability offields.record_id. In v1 events returnunknown, andfields.record_idisnull: getrecord_idfromGET /v1/leads/{id}usingdata.lead.id. Values:validmissingconflictunknown
accountobject or nullAccount that handled the conversation.nullif unknown.first_message_sent_atstring (date-time) or nullWhen the first message was sent.nullif sending is not confirmed; this is common for reply events.- First message text. Only with
include_text=true.Child attributes
textstring or nullSaved text, up to 4000 characters.nullif the text is unavailable. Up to 4000 characters.text_truncatedboolean or nulltrue: the text is shortened;false: the text is complete;null: completeness is unknown.
{
"object": "event",
"id": "evt_3b9e2c7a1f4d4e8a9b6c0d2e5f7a8c91",
"type": "lead.first_message_sent",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T07:30:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "contacted",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": "2026-10-26T07:30:00.000Z"
}
}#The lead.replied event
The lead replied. Sent for every counted reply, so one lead can have several. Text fields in data.reply are present only with include_text=true.
Attributes
objectstringObject type, alwaysevent.idstringEvent ID:evt_followed by 32 hexadecimal characters. The deduplication key. Format^evt_[a-f0-9]{32}$.api_versionstringEvent format version. Always"2026-10-18".timestampstring (date-time)When the fact occurred.testbooleanAlwaysfalse.typestringEvent type. Always"lead.replied".dataobjectEvent data.Child attributes
organization_idstring (uuid)Organization where the event occurred.workspaceobjectWorkspace at the time of the event.campaignobject or nullCampaign at the time of the event. Can benull.leadobjectLead snapshot.Child attributes
idstring (uuid)Lead ID.usernamestring or nullTelegram username without@. Can benull.statusstringLead status at the time of the event. Values:newcontactedcompletedrepliedblockedfailedsuspendeddeletedopted_outunknownfieldsobjectContact record fields at the time of the event.Child attributes
- Record ID in an external CRM, passed when the contacts were uploaded.
nullifrecord_id_statusis notvalid. Up to 128 characters. - First name. Up to 1024 characters.
- Last name. Up to 1024 characters.
- Company. Up to 1024 characters.
- Job title. Up to 1024 characters.
- Website. Up to 1024 characters.
- Contact source. Up to 1024 characters.
- The
utm_sourcetag. Up to 1024 characters. - The
utm_mediumtag. Up to 1024 characters. - The
utm_campaigntag. Up to 1024 characters.
fields_truncatedbooleantrueif some values were shortened.record_id_statusstringReliability offields.record_id. In v1 events returnunknown, andfields.record_idisnull: getrecord_idfromGET /v1/leads/{id}usingdata.lead.id. Values:validmissingconflictunknown
accountobject or nullAccount that handled the conversation.nullif unknown.first_message_sent_atstring (date-time) or nullWhen the first message was sent.nullif sending is not confirmed; this is common for reply events.replyobjectLead reply.Child attributes
idstring (uuid)Reply ID.replied_atstring (date-time)When the reply arrived.automation_stoppedboolean or nullWhether the sequence stopped after the reply.nullif the stop is not confirmed. Currently alwaysnull.- Whether this is the lead's first reply in the campaign. Not sent at the moment.
- Reply text. Only with
include_text=true. Up to 4000 characters. - Whether the text is shortened. Only with
include_text=true.
{
"object": "event",
"id": "evt_8d4f1a6c2e9b4c7d8a3e5f0b1c6d9e27",
"type": "lead.replied",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T09:12:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "replied",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": null,
"reply": {
"id": "e4b7a2d9-6c1f-4e38-9a5b-0d8c3f7e1a62",
"replied_at": "2026-10-26T09:12:00.000Z",
"automation_stopped": null
}
}
}#List events
GET/v1/events
Events in the order they occur: the first message to a lead and the lead's reply. Poll the feed with the cursor. next_cursor is always present, even on an empty page. With include_text=true the request weight is 3.
Parameters
- Number of objects to return per page. From 1 to 200. Defaults to
50. - The
next_cursorvalue from the previous response. Other filters must match the first request. - Only objects in this workspace.
- Only objects in this campaign.
- Only events of this type. Values:
lead.first_message_sentlead.replied - Include message texts in events. Requires the
messages:readpermission and "Message text" enabled on the key. Values:truefalseDefaults tofalse. now: start the feed from the current moment. Returns an empty page and a cursor. Cannot be combined withcursor. Values:now
Response
A list: object, data (an array of Event objects), has_more, next_cursor, meta. See Pagination.
The meta field
available_fromstring (date-time) or nullEarliest time for which the feed has events.nullif unknown.retention_daysstringNumber of days the feed retains events. Always30.collectionobjectStatus of saved conversation collection for the API.Child attributes
statestringrunning: collection is active;paused: paused in Meliora;preparing: preparing after being enabled;degraded: data may be incomplete. Values:runningpausedpreparingdegradedenabled_atstring (date-time) or nullWhen collection was enabled.nullif it has not been enabled yet.pause_pendingbooleanA pause or resume was requested in Meliora but has not been applied yet.
coverageobjectEvent feed completeness.Child attributes
statusstringcomplete,partialorunknown. Values:completepartialunknowngapsarray of objectUp to 50 intervals of possible incompleteness. Up to 50 items.gaps_truncatedbooleantrueif there are more than 50 intervals.incomplete_fromstring (date-time) or nullEarliest boundary of the hidden incomplete intervals.nullif there are none.
observed_atstring (date-time)Time the server read the data.
Endpoint-specific errors
cursor_mismatch: The cursor is corrupted, was issued for a different route or filters, or the key's permissions and scope have changed.scope_required: The key does not have permission for this read. Texts also require "Message text" to be enabled.not_found: The object was not found or is outside the key's scope. An unknown path also returns 404.cursor_expired: The cursor expired: 15 minutes for lists, 30 days for the event feed.
Common errors are described in Errors.
curl -G https://api.melioralab.io/v1/events \
-H "Authorization: Bearer $MELIORA_API_KEY" \
-d limit=100const url = new URL('https://api.melioralab.io/v1/events');
url.searchParams.set('limit', '100');
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.MELIORA_API_KEY}` },
});
if (!res.ok) throw new Error(`Meliora API: ${res.status}`);
const body = await res.json();import os
import requests
resp = requests.get(
"https://api.melioralab.io/v1/events",
headers={"Authorization": f"Bearer {os.environ['MELIORA_API_KEY']}"},
params={"limit": 100},
timeout=15,
)
resp.raise_for_status()
body = resp.json(){
"object": "list",
"data": [
{
"object": "event",
"id": "evt_3b9e2c7a1f4d4e8a9b6c0d2e5f7a8c91",
"type": "lead.first_message_sent",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T07:30:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "contacted",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": "2026-10-26T07:30:00.000Z"
}
},
{
"object": "event",
"id": "evt_8d4f1a6c2e9b4c7d8a3e5f0b1c6d9e27",
"type": "lead.replied",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T09:12:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "replied",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": null,
"reply": {
"id": "e4b7a2d9-6c1f-4e38-9a5b-0d8c3f7e1a62",
"replied_at": "2026-10-26T09:12:00.000Z",
"automation_stopped": null
}
}
}
],
"has_more": false,
"next_cursor": "v1.k1.Qm9hcmRfMWZ4.c3RyaWN0bHlfb3BhcXVl.dGFnX2V4YW1wbGU.bWFjX2V4YW1wbGVfdmFsdWU",
"meta": {
"available_from": "2026-10-20T08:00:00.000Z",
"retention_days": 30,
"collection": {
"state": "running",
"enabled_at": "2026-10-20T08:00:00.000Z",
"pause_pending": false
},
"coverage": {
"status": "unknown",
"gaps": [],
"gaps_truncated": false,
"incomplete_from": null
},
"observed_at": "2026-10-27T09:15:42.000Z"
}
}{
"object": "list",
"data": [
{
"object": "event",
"id": "evt_3b9e2c7a1f4d4e8a9b6c0d2e5f7a8c91",
"type": "lead.first_message_sent",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T07:30:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "contacted",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": "2026-10-26T07:30:00.000Z",
"first_message": {
"text": "Good afternoon, Anna! I'm writing from Example: could you tell me who handles outreach at your company?",
"text_truncated": false,
"text_unavailable": false,
"text_unavailable_reason": null
}
}
},
{
"object": "event",
"id": "evt_8d4f1a6c2e9b4c7d8a3e5f0b1c6d9e27",
"type": "lead.replied",
"api_version": "2026-10-18",
"timestamp": "2026-10-26T09:12:00.000Z",
"test": false,
"data": {
"organization_id": "2c8f4a61-7d3e-4b9a-8f21-6a0d5e9c3b17",
"workspace": {
"id": "3f6a9d21-8b4c-4e7f-a102-5c9e8d7b6a43",
"name": "Main workspace"
},
"campaign": {
"id": "4d8b2f73-6e1a-4c95-b7d0-8a3f5e2c9b14",
"name": "Example campaign"
},
"lead": {
"id": "5a7c3e92-1f4b-4d68-9c2e-7b0a6d4f8e31",
"username": "example_user",
"status": "replied",
"fields": {
"record_id": null,
"first_name": "Anna",
"company": "Example Ltd"
},
"fields_truncated": false,
"record_id_status": "unknown"
},
"account": {
"id": "1d9f6b28-4c3e-4a75-8b19-5e7a2c0f6d83",
"username": "example_sender",
"name": "Mary from Example"
},
"first_message_sent_at": null,
"reply": {
"id": "e4b7a2d9-6c1f-4e38-9a5b-0d8c3f7e1a62",
"replied_at": "2026-10-26T09:12:00.000Z",
"automation_stopped": null,
"text": "Hello! That's me, let's have a call tomorrow.",
"text_truncated": null,
"text_unavailable": false,
"text_unavailable_reason": null
}
}
}
],
"has_more": false,
"next_cursor": "v1.k1.Qm9hcmRfMWZ4.c3RyaWN0bHlfb3BhcXVl.dGFnX2V4YW1wbGU.bWFjX2V4YW1wbGVfdmFsdWU",
"meta": {
"available_from": "2026-10-20T08:00:00.000Z",
"retention_days": 30,
"collection": {
"state": "running",
"enabled_at": "2026-10-20T08:00:00.000Z",
"pause_pending": false
},
"coverage": {
"status": "unknown",
"gaps": [],
"gaps_truncated": false,
"incomplete_from": null
},
"observed_at": "2026-10-27T09:15:42.000Z"
}
}{
"object": "list",
"data": [],
"has_more": false,
"next_cursor": "v1.k1.Qm9hcmRfMWZ4.c3RyaWN0bHlfb3BhcXVl.dGFnX2V4YW1wbGU.bWFjX2V4YW1wbGVfdmFsdWU",
"meta": {
"available_from": "2026-10-20T08:00:00.000Z",
"retention_days": 30,
"collection": {
"state": "running",
"enabled_at": "2026-10-20T08:00:00.000Z",
"pause_pending": false
},
"coverage": {
"status": "unknown",
"gaps": [],
"gaps_truncated": false,
"incomplete_from": null
},
"observed_at": "2026-10-27T09:15:42.000Z"
}
}