# Events

What an audience event is, how the project's event catalogue and its parameter schemas are discovered live, how events attach to a contact, and how to tell an event type that is declared apart from one that actually arrives.

**Language:** en
**Audience:** developer
**TLDR:** An event is an immutable record of something a contact did, attached to the audience contact so one person has one timeline. GET /project/{project}/specs/events lists the event types available in the project; GET /project/{project}/specs/events/{eventType} returns that type's parameters. Declared is not the same as received: POST /project/{project}/event/volumes says which types actually arrive, when the last one did, and what values their parameters carry.
**Search keywords:** event, events, audience event, event type, event types, event catalogue, event catalog, specs events, event parameters, parameter, which events does my project have, custom event, ecommerce event, order event, purchase event, event category, attribution, automation trigger, contact timeline, activity, behaviour, behavior, what did the contact do, declared but never received, event never arrives, event retention, event history
**Related pages:** /developers/product-api/audience/probes, /developers/product-api/audience/event-query-filter
**Docs index (every page):** https://docs.instasent.com/llms.txt
**This zone's index:** https://docs.instasent.com/developers/product-api/llms-full.txt
**This page:** https://docs.instasent.com/developers/product-api/audience/events/ (HTML) · https://docs.instasent.com/developers/product-api/audience/events.md (Markdown)

An event is an immutable record of something a person did: a purchase, a page view, a form submission, an appointment, anything the account decides to track. Events are the behavioural half of the audience. Attributes say what somebody **is**; events say what they **did**, and when.

Because contacts merge, so do timelines. Every event reported by any data source about a person ends up on that person's single audience contact, in one chronological stream, regardless of how many systems contributed to it.

## The event catalogue

Which event types a project can receive is project-specific, exactly like the attribute catalogue. Read it live rather than hardcoding a list.

[`GET /project/{project}/specs/events` - Every event type available in this project.](/developers/product-api/reference)

```bash
curl "$BASE/specs/events" \
  -H "Authorization: Bearer $INSTASENT_TOKEN"
```

Each entry describes the type, not any instance of it:

- `uid` — `string`
  The identifier used everywhere else: as the event type in a filter condition, and as the `event` argument of a probe. For example `ecommerce_order_create`, `ecommerce_product_view`, `appointment`.
- `name` — `string`
  Human-readable name for the type.
- `category` — `string`
  Which family the type belongs to (`ecommerce`, `crm`, `marketing`, `subscriptions`, `payments`, `meetings`, `contact_data`, `contact_behaviour`). Useful for grouping in a UI, not for filtering.
- `attribution` — `boolean`
  Whether this type takes part in attribution tracking, which is what lets a conversion be credited to what preceded it.
- `automation` — `boolean`
  Whether the type can trigger an automation. A type with `automation: false` can still be filtered on; it just will not start anything.
- `important` — `boolean`
  Whether the platform treats the type as a headline event for the contact's timeline.

## Event parameters

An event carries **parameters**: the payload that makes one purchase different from another. They are declared per type, and their schema is discovered the same way.

[`GET /project/{project}/specs/events/{eventType}` - The parameter schema of one event type.](/developers/product-api/reference)

```bash
curl "$BASE/specs/events/ecommerce_product_purchase" \
  -H "Authorization: Bearer $INSTASENT_TOKEN"
```

Each parameter reports its `parameter` key, `title`, `dataType`, whether it is `required`, its `multiValue` ceiling and, for strings, a `maxLength`. Parameter keys are namespaced by their event type when you filter on them: for a `create` event you filter on `create.source`, for an order on `ecommerce_order_create.order-euro-amount`. The [event query filter](/developers/product-api/audience/event-query-filter) page documents the resolution rules.

> **Note**: A parameter schema tells you what a type **can** carry. It does not tell you what any of those parameters actually hold in your project, and a filter on a value that never occurs is a valid filter with an empty result. For the real values, probe: see [what actually arrives](#declared-is-not-received) below.

## Reading a contact's events

Given an audience contact id, its timeline is one call.

[`GET /project/{project}/audience/{audienceId}/events` - The events attached to a single audience contact.](/developers/product-api/reference)

This needs `PROJECT_AUDIENCE_READ` **and** `PROJECT_AUDIENCE_DATA_EVENTS`, the second of which is gated by the subscription plan. Without it the call is refused rather than returning a thinner timeline.

To search events across the whole project rather than for one person, use the [event query filter](/developers/product-api/audience/event-query-filter) against `/event/search` and `/event/scroll`. Note that the event listing endpoints look back over a bounded window whose length depends on the subscription: read what the response reports rather than assuming your requested range was honoured.

## Declared is not received

The catalogue lists every type the project **could** receive. It cannot tell you which of them anything ever sends, and that difference is usually the one that decides whether a feature is worth building.

`POST /project/{project}/event/volumes` answers it: per declared type, the count inside a window, whether anything arrived, and when the last one did. A type that is declared and never received comes back as an explicit zero rather than being silently absent. Pass an `event` and the answer goes a level deeper, returning the values that type's parameters actually carry: product ids and names, categories, tags, vendors, the campaign ids and names behind an attribution, sources and mediums, statuses, methods.

[`POST /project/{project}/event/volumes` - Which event types arrive, how many, when the last one did, and what their parameters hold.](/developers/product-api/reference)

Four caveats travel with that answer and are easy to lose:

- A null `lastSeenAt` means nothing arrived **in that window**, never that the type was never seen.
- Where a parameter has both an id and a name, both come back. **Filter on the id** (`product-id`, `utm-id`), which is stable and unique, and **read the name** (`product-name`, `utm-campaign`), which is neither: a condition written against a name breaks the first time the customer renames the thing.
- The type counts are never sampled, but **the parameter values are**, above 10,000 contacts. Their answer is in `event.sampling`, a second block nested under `event`, not in the top-level `sampling` that reports on the counts. A value missing from a sampled list has not been shown not to occur.
- The probe reads the project's event history, while a **segment's** event condition is evaluated against a narrower, per-contact store. So a value the probe lists can match fewer people than its count suggests, sometimes none. Use the probe to pick a value, then count.

The full treatment, with the rest of the caveats, is on [Probes](/developers/product-api/audience/probes).

## Events in a contact filter

You do not need the event grammar to select **people** by what they did. The [audience query filter](/developers/product-api/audience/query-filter) has `event_condition` and `group_event` nodes for exactly that: "contacts who purchased in the last 30 days" is a contact-side filter with an event group inside it. Reach for the [event query filter](/developers/product-api/audience/event-query-filter) when the rows you want back are events, not people.

## What's next

- **[Probes](/developers/product-api/audience/probes)**: which types arrive and what their parameters really hold.
- **[Event query filter](/developers/product-api/audience/event-query-filter)**: the grammar for searching and aggregating events directly.
- **[Query filter](/developers/product-api/audience/query-filter#filter-by-events)**: selecting contacts by their events.

---

This is one page of the Instasent documentation. For the complete machine-readable index of every guide and API reference, fetch https://docs.instasent.com/llms.txt — start there for full context.
