Discover event property schemas
Inspect permitted property names, JSON types and quality counts through MCP or the CLI.
On this page
Use get_event_schema through the MCP execute_read_action tool, or run:
anectico --project PROJECT_UUID analytics schema --event checkout_completed \
--start-time 2026-09-10T00:00:00Z --end-time 2026-09-11T00:00:00Z \
--environment production
The equivalent REST endpoint is GET /api/v1/events/schema. MCP and REST arguments
are project_id, event, start_time, end_time and optional environment.
Choose an exact event name, or discover names with get_event_catalog first.
The start is inclusive and the end exclusive. Use RFC3339 timestamps at millisecond
precision or coarser, spanning at most 90 days. A future end does not establish
completeness for that future period. Environment matches exactly; omitting it
includes all environments. Environment strings are exact, up to 32,768 UTF-8 bytes;
whitespace is not trimmed. Event names are limited to 200 UTF-8 bytes.
Permissions and visibility
The read requires analytics:read; MCP also needs mcp:read. A project credential
supplies its project and cannot select another. Organization credentials must
choose a project. The project must be active and the full window readable under
its retention rules.
The response's visibility is permitted_stored_properties. Recognized benign
metadata is available without content permission unless it carries a declared-sensitive
protection. Protected keys require content permission plus both attribute-content READ
classes and their full-window retention, even when the key normally counts as benign.
These protections survive deletion of the declaring plan. Other property summaries also
require agents:content:read and the project's current content READ policy.
Unknown property names require both applicable attribute-content classes. A
class is omitted if its retention does not cover the full requested window;
narrowing the window may reveal still-retained properties. Content scope cannot
override a project policy denial.
No raw examples or property values are returned. Nested content is checked too: if any occurrence contains a refused nested value, that property's entire summary is withheld. Stored redaction can also remove fields. An omitted name does not prove the application never sent it. The response does not enumerate withheld names or their counts.
Read the result
observed_events counts converged stored occurrences for the selected event,
including retries collapsed into one occurrence. It does not count people.
Each property contains:
key: the literal top-level name; dots are not interpreted as a nested path.presentandmissing: presence or absence in the observed stored bags.types: nonzero counts forstring,number,boolean,array,objectandnull.finite_numbers: the subset of number values eligible for finite binary64 numeric measures.first_seenandlast_seen: event times of present observations within this window.
Numeric-looking strings stay strings. A JSON number outside finite numeric range
stays a number but is excluded from finite_numbers. Explicit null is present,
not missing. The type counts sum to present; present + missing equals
observed_events. Missing describes stored data, not proof the SDK omitted a field.
Both platform_completeness and upstream_completeness remain unknown, even
for zero events or an empty schema. ingested_before is a first-receipt cutoff;
observed_from and observed_until describe the database read. These are not a
consumption watermark, frozen snapshot or completeness proof.
The operation returns a whole bounded schema without pagination. It currently
allows at most 250 distinct property keys of up to 512 UTF-8 bytes each and 250,000 observed events, with an
8 MiB source-string budget and a ten-second service deadline. Database resource
limits also apply. Exceeded limits fail the whole request. Narrowing the event window may reduce the
selected events, bytes or property diversity; it cannot reduce one event's property bag.
Unreadable storage or sensitivity declarations, changed permissions/policy/protections
or elapsed retention cannot become
a successful partial result. Start a fresh read after a policy-change error. A temporarily unavailable source
returns HTTP 503 with Retry-After: 1; retry after that delay.
This discovery workflow describes observed instrumentation. It does not publish tracking plans, enforce a declared application schema or add raw property examples.
Reserved properties
$release and $app_version are reserved, well-known string properties every SDK may stamp on
a product event: $release is the app or service's full release identifier (for example
checkout-service@2.4.1 or web@2.4.1+318); $app_version is the bare version string alone
(for example 2.4.1). Both are event properties, never person properties — they describe
what a person did (which build produced this occurrence), not who the person is, so they are
never offered as current-person filters, only as source: "event" filters and breakdowns.
Neither is invented by an SDK that has nothing configured: an event captured before a release is set, or by an SDK that never sets one, simply carries neither property, the same as any other absent property. See each SDK's own reference page for exactly what it stamps and how to configure it: iOS, Android, JavaScript, Go, Python, React Native, Flutter.
Filter or break down on $release/$app_version exactly like any other event property (see
Product analytics) — there is no separate release
primitive. Comparing a metric across two releases with non-overlapping active periods is a
comparison-window query whose event filter additionally pins $release; comparing several
releases active at once is a breakdown on $release.