Skip to content

Timeline ​

Audit TrailInvestigation

Builds a chronological log of everything a user or device did within a time window — like a play-by-play activity feed. Each event is recorded with a timestamp and any extra fields you capture.

When to Use ​

  • Abuse investigation: pull a user's timeline to see exactly what happened and in what order
  • Compliance audit trails: generate a full record of user activity for regulatory review
  • Anomaly investigation: a user flagged by another behavior — what did their session look like?
  • Onboarding drop-off analysis: what's the last event users hit before they stop?

Configuration ​

json
{
  "name": "device_activity_timeline_24h",
  "operation": "timeline",
  "group_by": "device_id",
  "fields": ["country_code", "ip_address", "identity"],
  "window_duration_seconds": 86400,
  "operation_config": {
    "max_entries": 50,
    "dedupe_consecutive": true
  }
}

Fields ​

fields is optional. It specifies additional fields to capture per entry beyond the always-included event_name and event_id. Fields are resolved from the top-level event data first, then fall back to event_properties (e.g., "phone" resolves to event_properties.phone if no top-level phone field exists). Dot notation also works: "event_properties.phone".

Configuration Options ​

OptionDefaultDescription
max_entries50Maximum entries to retain. Oldest are evicted (FIFO). Summary stats still cover the full window.
dedupe_consecutivetrueConsecutive events with the same event_name and identical field values are collapsed into a single entry with min_time, max_time, and count. When two events share the same name but differ in any captured field, they are not merged. Set to false for one entry per event.

Response ​

FieldDescription
entriesArray of event snapshots (capped to max_entries, most recent retained)
entries[].event_nameThe name of the event
entries[].event_idID of the first event in a collapsed group
entries[].min_timeTimestamp of the first event in the entry (when dedupe_consecutive is enabled)
entries[].max_timeTimestamp of the most recent event in the entry (when dedupe_consecutive is enabled)
entries[].event_timeTimestamp of the event (when dedupe_consecutive is false)
entries[].countNumber of consecutive events collapsed into this entry
summary.countTotal number of events in the window (may exceed entry_count)
summary.entry_countNumber of entries currently in the timeline
summary.min_timeTimestamp of the first event in the window
summary.max_timeTimestamp of the most recent event
summary.duration_secondsTime elapsed between first and last event
summary.eventsPer-event-name breakdown with count, min_time, and max_time

Example (with dedupe_consecutive: true) ​

In this example, 5 raw events occurred, but the 3 consecutive page_view events were collapsed into a single entry with count: 3:

json
{
  "behaviors": {
    "device_activity_timeline_24h": {
      "entries": [
        {
          "event_name": "page_view",
          "event_id": "a1b2c3",
          "min_time": "2025-06-12T14:00:00.000Z",
          "max_time": "2025-06-12T14:02:00.000Z",
          "count": 3,
          "country_code": "US",
          "ip_address": "1.2.3.4",
          "identity": "wallet_0xabc"
        },
        {
          "event_name": "trade",
          "event_id": "d4e5f6",
          "min_time": "2025-06-12T14:05:00.000Z",
          "max_time": "2025-06-12T14:05:00.000Z",
          "count": 1,
          "country_code": "US",
          "ip_address": "1.2.3.4",
          "identity": "wallet_0xabc"
        },
        {
          "event_name": "login",
          "event_id": "g7h8i9",
          "min_time": "2025-06-12T15:30:00.000Z",
          "max_time": "2025-06-12T15:30:00.000Z",
          "count": 1,
          "country_code": "IR",
          "ip_address": "5.6.7.8",
          "identity": "wallet_0xabc"
        }
      ],
      "summary": {
        "count": 5,
        "entry_count": 3,
        "min_time": "2025-06-12T14:00:00.000Z",
        "max_time": "2025-06-12T15:30:00.000Z",
        "duration_seconds": 5400,
        "events": {
          "page_view": {
            "count": 3,
            "min_time": "2025-06-12T14:00:00.000Z",
            "max_time": "2025-06-12T14:02:00.000Z"
          },
          "trade": {
            "count": 1,
            "min_time": "2025-06-12T14:05:00.000Z",
            "max_time": "2025-06-12T14:05:00.000Z"
          },
          "login": {
            "count": 1,
            "min_time": "2025-06-12T15:30:00.000Z",
            "max_time": "2025-06-12T15:30:00.000Z"
          }
        }
      },
      "timestamp": "2025-06-12T14:00:00.000Z",
      "remaining_window_seconds": 81000
    }
  }
}

Deduplication

When dedupe_consecutive is enabled (default), consecutive events with the same event_name and identical captured field values are merged into a single entry. This dramatically reduces timeline size for repetitive actions like polling, page reloads, or heartbeat events — while preserving the full event count in summary.count. If a field value changes (e.g., country switches from US to IR), a new entry is created even if the event_name is the same.

Summary vs Entries

When summary.count exceeds summary.entry_count, it means older entries were evicted from the timeline but the summary stats (including per-event breakdowns in summary.events and duration_seconds) still reflect the full window of activity.