Inspect events and customer cohorts
Ask your agent to check who performed a diagnostic event and to save reusable customer groups (cohorts) for investigation or rollout targeting.
On this page
Use event discovery to verify instrumentation and connect behavior to customer investigations. Your agent reads the event catalog and the people who triggered an event, and it manages reusable customer groups, called cohorts. The Console has no Events page and no Cohorts page. For property names, types and presence counts, see event property schemas.
For typed measurements, frozen evidence and exact contributor pages through MCP or CLI, see
measure product events.
That guide also covers confirmed creation and replacement of derived audiences from complete
result selections through MCP and CLI, and exact-generation reuse in product queries — including
an engagement lifecycle state's audience,
which is offered only for a lifecycle state (continuing, new_to_observed_history, resurrected or
dormant), never a rolling-active point or a days-active bin. Its labels describe the observed
history only: dormant is not churn, an unsubscribe or marketing eligibility, only "active in the
previous bucket, not the current one."
Approve configuration changes
Every management write through MCP, REST or the CLI first returns a server preview
and changes nothing. It includes complete before and proposed definitions,
required permissions and a confirmation token. Customer-authored configuration is
marked as untrusted data. Creation IDs and commit timestamps are assigned at apply;
the preview states which values are generated then.
Approve that state, then repeat identical arguments with MCP confirm_token, CLI
--confirm-token TOKEN, or REST header X-Anectico-Confirm-Token: TOKEN. Keep the
same body, version arguments and retry key. A changed state, source or argument
requires a fresh preview and approval. Local --yes is no longer accepted.
Creation needs a stable idempotency_key (1–128 bytes), supplied with CLI
--idempotency-key KEY or REST Idempotency-Key: KEY. Identical retries return the
first committed result, even after the object changes or is deleted; they create
nothing new. Changed arguments cannot reuse the key. Current permissions and
privacy restrictions still apply when reading a receipt.
Flag updates, toggles and deletion require exact expected_updated_at from
flags get (--expected-updated-at TIMESTAMP). Full flag reads include default
payloads and every variant's name and payload. Previews include all targeting,
variants and payloads. A pinned derived audience is supported by remote evaluation
using its cohort UUID and positive decimal-string generation; its source scopes
are checked and named before approval. Such flags are omitted from local snapshots.
Flag lists take limit and cursor and return the next cursor; a page is no total.
Cohort create uses a retry key. Metadata updates and deletion require the exact
update timestamp. Dynamic definition replacement and refresh additionally require
current expected_definition_version and expected_generation; generation may
be zero before the first refresh. Static replacement uses expected_generation
and an explicit complete array, including [] to clear it. These membership
previews return complete current and proposed resolved-person sets and resolution
information. Confirmation refuses changed identity resolution or source evidence
instead of substituting an unapproved person set. Dynamic create saves an
unmaterialized definition; refresh is a separate approved change.
Ask your agent
"Was the
checkout_completedevent captured in production yesterday? Show me how many times and who triggered it."
"Create a behavioral cohort of people who completed checkout at least twice in the last 30 days. Preview it first and show me the size and a sample."
| Job | MCP tool or action | CLI command |
|---|---|---|
| List event names and counts in an exact window | get_event_catalog |
anectico analytics catalog |
| List captured event names, optionally by prefix or one exact property | list_event_names |
anectico events names |
| Page the people who triggered one event | list_event_triggerers |
anectico events triggerers |
| Open one person and their timeline | get_person_timeline, get_person_profile, resolve_person, search_persons |
anectico persons timeline, anectico persons get |
| List cohorts, or read one cohort's definition | list_cohorts |
anectico cohorts list, anectico cohorts get |
| Preview a behavioral or property definition without saving it | preview_cohort |
anectico cohorts preview |
| Create a cohort | create_cohort |
anectico cohorts create |
| Change a cohort's name, description or definition | update_cohort |
anectico cohorts update |
| Recompute membership now | refresh_cohort |
anectico cohorts refresh |
| Replace a static cohort's whole membership | replace_static_cohort_members |
anectico cohorts replace-members |
| Page a cohort's members, current or one retained generation | get_cohort_members |
anectico cohorts members |
| Read a cohort's generation history | list_cohort_generations |
anectico cohorts history |
| Save a complete result selection as a derived audience, or replace one | create_analytics_audience, replace_analytics_audience |
anectico analytics audiences create, anectico analytics audiences replace |
| Delete a cohort | delete_cohort |
anectico cohorts delete |
Event reads need analytics:read, and over MCP mcp:read. See
Cohort permissions for the cohort scopes.
What your agent gets back
The event catalog returns, for each name, count, first_seen and last_seen in the selected
window. The triggerer list returns person_id and distinct_id for each person. A cohort read
returns the definition, the member count, the current generation and alert_mirror_status
(pending, synced or failed). A member read returns a page of person IDs with the exact
generation and the total count. All counts are evidence, not a promise that capture was complete:
platform_completeness and upstream_completeness stay unknown.
Open the proof
The event catalog, the triggerer list and the cohort tools return no link. A cohort has no proof
page. To let a person check one customer, ask your agent to read that person with
get_person_timeline, get_person_profile, resolve_person or search_persons. Each of these
returns a link to the read-only person page for that customer. See
proof pages. To let a person
check a count, ask for a measurement instead and use its result link; see
measure product events.
Inspect an event
Ask your agent for the event names in an exact window, then for the people who triggered the event you care about. If an event is missing, confirm the SDK sent it after identity was established and that the project and the time window are correct.
Each triggerer carries the recognizable identifier used for the event (distinct_id) and the
canonical person behind it (person_id). Internal person UUIDs are not customer display names.
Read a triggerer's timeline with get_person_timeline to compare the event with their errors,
traces, logs, agent runs and sessions. Event volume alone does not explain an outcome.
Discover the event catalog
Use the MCP read action get_event_catalog through execute_read_action, or run:
anectico --project PROJECT_UUID analytics catalog \
--start-time 2026-09-10T00:00:00Z \
--end-time 2026-09-11T00:00:00Z \
--environment production --prefix checkout --limit 50
MCP arguments use project_id, start_time, end_time, environment, prefix,
limit and cursor. The equivalent REST endpoint is GET /api/v1/events/catalog.
The read requires analytics:read; MCP also requires mcp:read. A project-scoped
credential supplies its project automatically and cannot read another project.
Organization credentials must select a project. The project must be active, and
the entire window must remain within its currently readable history.
The start is inclusive and the end exclusive. Supply RFC3339 times with millisecond
precision or coarser and a window of at most 90 days. A future end time is allowed,
but does not establish completeness for the future portion of the window. Environment matches exactly;
omitting it includes all environments. Prefix matches event names literally and
case-sensitively: % and _ are ordinary characters. Event names are returned in
ascending order, with 50 names per page by default and a maximum of 200.
Each entry contains name, count, first_seen and last_seen. Counts represent
converged event occurrences in the selected window, including delivery retries
that collapse into one event. They are not unique people or lifetime totals;
first or last times also refer only to the selected window. No property examples or
person identifiers are returned.
When has_more is true, pass next_cursor as cursor (CLI --cursor) with the same
project, window, environment, prefix and page size. Cursors expire 15 minutes after
the first page; later pages do not extend that lifetime. Start a fresh read after
expiry. Invalid or changed filters are rejected. Resource-limit failures return an
error for the whole page; narrow the window or prefix before retrying.
ingested_before records the initial receipt cutoff. observed_from and
observed_until describe the database-read interval. These do not establish a
consumption watermark or freeze the source: delayed consumption and deletion can
change subsequent pages. platform_completeness and upstream_completeness remain
unknown, including when the catalog is empty. An empty page cannot prove that no
customer action occurred. Catalog counts are live evidence, not a saved analytics
result.
Create a cohort
Your agent creates a reusable customer group. Anectico supports behavioral, property-based, and static definitions. Use a stable name that describes membership rather than the campaign that first needed it.
An event-behavior condition must fit inside your currently readable product history. A free organization normally has seven days. A previous retention cut can make the available window shorter even after you increase retention; increasing retention does not restore expired history. Saved conditions keep their original windows, so shorten an overlong condition explicitly before evaluating it again. This applies to any event condition, including one inside a nested group. Preview and refresh check current history and source access on the server. Person-property conditions and static member lists do not need a readable event-history window.
A cohort read reports readable membership rules, member counts, last refresh and alert-targeting status, with the membership generation and the definition version. A withheld membership count is unavailable; it is not zero. Rule-based cohorts, static member lists, and saved audiences from analytics results remain separate choices.
Editing a behavioral or property cohort replaces its complete rule and evaluates a new membership generation. A zero count replaces the previous threshold; clearing all filters removes them. Retained historical generations keep the rule and membership that produced them.
For event conditions, count accepts whole numbers starting at zero, including inside nested
groups. A saved zero-count condition keeps its count at zero for preview and saving.
Refresh (refresh_cohort) after changing upstream data or when current membership is required
immediately. Read the cohort's members to validate representative customers before using it in a
feature rollout or watched alert. An ordinary cohort can also be written on a schedule to your own
bucket as an audience snapshot; see warehouse export.
A members read (get_cohort_members) reads membership again each time. Its total and generation
describe the returned member list, even if another session changed the cohort meanwhile. The total
can exceed the number on the first page; follow the cursor to continue. If the read does not report
a total or generation, that value is unavailable. Pass a retained generation to read that exact
generation.
For a behavioral or property cohort, preview it (preview_cohort) before saving. Preview is a
point-in-time, non-mutating evaluation: Anectico returns the complete matching count, a bounded sample of
people, the evaluation time, and the definition hash. The evaluation time is the shared UTC anchor
selected when evaluation starts and the exclusive end of behavioral windows. Saving or editing a definition does not make an
older preview current; run preview again after every definition change.
Preview checks current project history, tracking declarations, source permissions and content
policy before evaluation and again before returning the count or sample. Profile predicates need
persons:profile:read; sensitive event filters, including declared-sensitive properties and
nested content inside selected values, need agents:content:read and an allowing content policy.
The check includes candidate events that do not match the filter. Profile checks cover the age of
all consulted profiles, even when none match. Missing source evidence, expired history or a policy
or declaration change causes the whole preview to fail; it does not return a partial audience.
All behavioral conditions are read together from one source snapshot, preserving each condition's own event, filters and time window. The complete preview is limited to 250,000 candidate events and 64 MiB of inspected source and condition-count input. Nonmatching events count toward these limits. A definition can include up to 64 behavioral conditions; the encoded behavioral request and generated query are each limited to 256 KiB. Narrow the window or event selection if a limit is exceeded. These are evaluation guardrails, not measured capacity or incoming-event completeness. All behavioral conditions share one owning identity snapshot for up to 250,000 distinct event identifiers across the definition. Event identifiers mapped to the same person have their matching counts combined before count thresholds are applied. Nonmatching candidate events also need a valid identity mapping. Missing or invalid mappings refuse the entire evaluation; retry after identity processing recovers. An event identifier equal to a person UUID is accepted only when Anectico explicitly resolves that identifier to a live canonical person.
Each behavioral condition considers people who performed its event inside its time window.
If their events do not match its property filters, their matching count is zero and the selected
comparison applies to that zero. For example, < 1 or = 0 includes those zero-match participants,
and <= 1 includes both zero-match participants and people with one matching event.
Property pages carry an owning revision for the selected field's source, including nonmatches and property removals. A change between pages or during the final checks refuses evaluation, even if a property is changed back to its original value. Changes to unrelated fields do not change that revision. Each property condition is limited to 500,000 source profiles and 32 MiB of encoded source input, counted across all its pages; removed-property winner records also count. Repeated conditions each perform their own bounded read. The whole definition has a separate 64 MiB budget for retained evaluation input, including condition counts and matching identities. Narrow the definition if a limit is exceeded.
The dynamic-cohort population ceiling is 500,000 matching people. Preview also has a 30-second execution deadline; large property sources can time out below the population ceiling. A timeout returns no partial audience. These limits are not a promise that every permitted size finishes. If a combined definition exceeds the population limit, preview, definition evaluation and refresh fail; refresh keeps the previously stored generation. Narrow the definition before retrying. Behavioral windows must be between 1 and 365 days. Each behavioral condition uses its configured number of 24-hour days, ending at one shared UTC instant for that evaluation. Events exactly at the end instant are excluded. Refresh and definition edits retain this evaluation boundary with the resulting generation. This shared time boundary does not freeze incoming events or changes to person properties. Refresh and definition edits repeat the complete behavioral count observation and owning identity and property checks before writing the new generation. Changes to any condition's observed aliases, source counts or matching counts refuse the operation, even when qualifying membership would be unchanged. An unavailable reader, changed mapping or property source, invalid profile identity, or observed organization and project deletion refuses the operation. Count thresholds, result limits and combined conditions cannot hide missing identity evidence. Failed checks before commit preserve the previous stored membership and generation. If mirror preparation has already started, the alert mirror can remain unavailable until a successful refresh restores it; a failed or canceled refresh never activates a partial audience.
These checks do not freeze incoming events or make these reads one atomic transaction. A late event can affect a later refresh, and source changes after the final check can occur before the new generation becomes visible. A cohort is a recorded evaluation, not a continuously current membership guarantee.
Behavioral membership also depends on the product history it was evaluated over. The full source window must still be readable under the current product retention when membership is used. If a retention change or ordinary aging removes part of that window, refresh the cohort to create a new generation. Shorten the behavioral lookback first if it no longer fits the readable history window. Increasing retention later does not restore an old generation. Member pages and dependent queries refuse it; counts and membership differences can be withheld while the cohort definition remains visible. For an analytics query pinned to the old generation, select the refreshed generation and run a new query. A temporary retention-authority failure can be retried after service recovers. Manually supplied static membership and cohorts based only on current person properties do not acquire an event-history dependency. Their other permission and source checks still apply.
Static cohorts use explicit full-list replacement (replace_static_cohort_members). Supply the
complete desired list of person UUIDs or project-scoped distinct IDs. The write previews first, and
you confirm it. The operation never appends. An empty submission intentionally clears the cohort.
Anectico fences the write with the expected_generation you read, so a concurrent refresh or edit
is rejected instead of overwriting newer membership.
After a static create or replacement, keep the resolution summary with the change record. It reports:
- input values received;
- inputs that resolved to a known person;
- unique canonical people written;
- duplicate inputs that collapsed to an already-resolved person; and
- unresolved inputs, including the exact unknown values to correct.
Unknown values are skipped; they are never treated as new people. Read the summary, so a successful request with unresolved inputs cannot be mistaken for a lossless import.
Erasing a person removes them from every cohort
When a person is erased they are removed from every cohort of the project, including each earlier generation kept in the cohort's history, and every member count is lowered to match. A generation that held them keeps its other members and stays readable. The person cannot be added to a cohort again.
A saved audience from an analytics result is different: it is a fixed list taken from that result. If the erased person was in it, the audience is withdrawn the way an expired one is. Save it again from a new measurement.
Audit membership generations
Read a cohort's history (list_cohort_generations) to inspect immutable materialization
generations. The current and retained states are explicit, along with total members, added and
removed counts, refresh reason, actor, materialization time, definition snapshot and hash, and
alert-targeting delivery status. Read the members of a retained historical generation with
get_cohort_members and its generation. A generation that is not retained keeps its audit metadata
but no longer exposes a member list.
History counts require access to the sources of both the selected and preceding generation, because added and removed counts compare those member sets. Reading a retained member list requires access to that generation's own sources. A later sensitive-property declaration can restrict reads of existing generations; editing a definition or retiring its tracking plan does not remove protection from those historical sources.
Update and refresh responses apply the current source permissions and content-erasure evidence
to their counts too. membership_withheld: true means the scalar member count is withheld;
its zero is not an empty cohort. Generation history also returns deltas_withheld: true when
added and removed counts cannot be disclosed, even if the current member count is available.
MCP and CLI cohort reads display unavailable for these values. Configuration and history stay
readable, and a member read works only when the generation can be read. Authorized refresh and
edit actions remain available.
Ordinary dynamic generations retain the content-erasure revisions observed before evaluation.
A subject-content clear invalidates older generations that depend on that content class in the
same project, even when the subject was not a member. Content-dependent members and counts
remain unavailable if their original evidence is missing, pending or changed; restoring source
rows does not restore an old generation's evidence. Refresh creates a new generation from
current sources. Static supplied membership and content-independent generations do not inherit
that dependency. A fresh generation's deltas remain unavailable if the preceding generation
cannot be read. An authorized get_cohort_members response for the exact returned generation
can establish its count, including zero.
An error after an update or refresh does not prove the change was rolled back: the result's
source may have become unavailable after the write. Inspect the cohort and its history before retrying.
alert_mirror_status describes whether the current generation has reached the audience mirror
used by alert evaluation:
pending— delivery is pending, including a retry in progress or queued;failed— the generation is not available to alert targeting; andsynced— alert targeting is evaluating this generation.
When membership is withheld, treat alert targeting as unknown even if an earlier
delivery succeeded. Delivery status alone does not establish current source validity.
Do not assume an updated cohort is active for alerts until the status reads synced. Retry a failed
refresh or contact an administrator if delivery does not converge. A generation retired because
its source evidence failed during delivery cannot be reactivated by a delivery retry; refresh
creates a newer generation from current sources.
Cohort permissions
Cohort definitions require cohort read access. Computed members, counts and targeting decisions also require the scopes of their sources. Event-property filters outside Anectico's exact operational-metadata allowlist require agents:content:read as well as analytics:read; profile predicates require persons:profile:read. Combining predicates combines these requirements. A count can reveal a restricted property even without returning its raw value. Creating, editing, refreshing, and
replacing membership need cohorts:write, which every member role holds. Deleting a cohort is
destructive and needs cohorts:delete, a dedicated organization owner or admin permission.
Deleting a cohort is destructive. Feature flags that target it stop matching those members, so remove or replace those dependencies first.
Keep definitions trustworthy
-
Prefer stable identity and normalized properties.
-
Avoid static lists when a behavioral or property definition expresses the rule.
-
Sample members after creation and after significant instrumentation changes.
-
Record why a cohort exists in its name or team runbook.
Live event-triggerer reads preserve the exact event name, including leading or trailing whitespace. Their optional property-key filter retains its restricted key syntax; use native typed analytics filters and frozen participant pages for arbitrary property keys. Empty triggerer results contain an empty array.