Skip to main content
GET
/
leads
/
{leadId}
/
events
cURL
curl --request GET \
  --url https://api.attent.app/v1/leads/{leadId}/events \
  --header 'x-api-key: <api-key>'
{
  "events": [
    {
      "id": "msg_abc",
      "roomId": "room_abc",
      "orgId": "org_123",
      "type": "MESSAGE",
      "timestamp": "2026-05-14T15:00:00.000Z",
      "updatedAt": "2026-05-14T15:00:00.000Z",
      "data": {
        "direction": "INBOUND",
        "content": {
          "text": "Hi, I am interested"
        },
        "isAiGenerated": false,
        "deliveryChannel": "SMS"
      }
    },
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "roomId": "room_abc",
      "orgId": "org_123",
      "type": "COMPLIANCE_BLOCKED",
      "timestamp": "2026-05-20T05:50:12.000Z",
      "updatedAt": "2026-05-20T05:50:12.000Z",
      "data": {
        "channel": "sms",
        "reason": "STATE_DNC",
        "source": "http",
        "triggeredBy": "llm"
      }
    }
  ],
  "nextToken": null
}

Incremental sync

Pair this endpoint with GET /leads:
  1. Poll GET /leads?updatedSince=… for leads whose profile or activity changed.
  2. When lastActivityAt moves forward, call GET /leads/{leadId}/events?since=… for that lead.
  3. Paginate with nextToken until it is null.
Events are ordered by updatedAt ascending. Use the largest updatedAt from the page as the next since cursor for that lead.

Event types and forward compatibility

The type field identifies each event (MESSAGE, CALL, EMAIL, and others documented in the API reference). Apten may add new event types at any time as the product evolves. We do not treat new types as a breaking API change and do not guarantee advance notice before they appear in production responses. Build integrations to be forward-compatible:
  • Prefer an explicit types filter when you only need a fixed set of shapes for your pipeline.
  • Otherwise, tolerate unknown type values — persist the raw event, skip it, or route it to a generic handler. Do not fail the entire sync or reject the payload because type is unrecognized.
  • Use type plus id as the stable key; do not assume every event is a message, call, or email.
The OpenAPI schema lists event types Apten documents today; it is not an exhaustive guarantee of all types you may receive over time.

Compliance blocks (COMPLIANCE_BLOCKED)

When external compliance is enabled and an outbound SMS, email, or voice attempt is suppressed, Apten writes a COMPLIANCE_BLOCKED room event. It appears on this endpoint like any other interaction event.
ExpectationDetail
No outbound message/call/email rowA blocked send does not create a MESSAGE, EMAIL, or CALL for that attempt — only COMPLIANCE_BLOCKED.
Allowed checks are omittedPass results are stored in Apten’s internal audit log only; they are not returned by this API.
Filter?types=COMPLIANCE_BLOCKED (or include it in a comma-separated list).
PIIdata includes channel, reason, source, and optional triggeredBy — not phone, email, or full provider payloads.
Example event:
{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "roomId": "room_abc",
  "orgId": "org_123",
  "type": "COMPLIANCE_BLOCKED",
  "timestamp": "2026-05-20T05:50:12.000Z",
  "updatedAt": "2026-05-20T05:50:12.000Z",
  "data": {
    "channel": "sms",
    "reason": "STATE_DNC",
    "source": "http",
    "triggeredBy": "llm"
  }
}
The event id is the stable identifier for the block (same UUID as the internal audit row). data does not repeat it — same pattern as MESSAGE / CALL / EMAIL. reason is either an Apten system code (e.g. COMPLIANCE_TARGET_MISSING, DNC) or a string returned by your compliance HTTP API when allowed is false. source indicates which check leg blocked (http, apten-dnc, configuration, provider-error, etc.). Treat COMPLIANCE_BLOCKED in your warehouse as suppressed outreach — not a delivery failure on an existing message.

Authorizations

x-api-key
string
header
required

Path Parameters

leadId
string
required

The lead (room) ID to fetch events for.

Query Parameters

since
string<date-time>
required

ISO 8601 timestamp. Returns events whose updatedAt is greater than or equal to this value.

types
string

Comma-separated list of event types to include. Documented values include MESSAGE, CALL, EMAIL, TOOL_CALL, CUSTOM, and COMPLIANCE_BLOCKED. Use this filter when your integration only handles a known set of types. Defaults to all types currently stored for the lead (including types not listed here). When supplied, a page may return fewer than limit items even if more matching events exist — always paginate using nextToken.

Example:

"MESSAGE,COMPLIANCE_BLOCKED"

limit
integer
default:100

Maximum number of events to return per page. Defaults to 100, max 1000.

Required range: 1 <= x <= 1000
nextToken
string

Opaque cursor from a prior response. Pass it back to fetch the next page. null in the response means you have reached the end; a non-null value means more pages exist (true regardless of how many items the current page returned).

Response

A page of events ordered by updatedAt ascending.

events
object[]

An interaction event between a lead and your organization. The type discriminator determines the shape of data.

New interaction event types may be added in the future. Integrations must accept responses containing undocumented type values or restrict ingestion with the types query parameter on GET /leads/{leadId}/events.

nextToken
string | null

Cursor for the next page. null if there are no more results.