Properties
Event properties are flat string → string maps. Any key you send becomes queryable: filter, group, segment, or build funnels on it.
Shape
Properties are a flat object of string keys to string values. Nested objects and arrays are rejected at ingest. Non-string values are rejected too — coerce them yourself before calling track().
track("signup", {
plan: "pro",
source: "pricing_page",
annual: "true", // boolean coerced to string
referrer_campaign: "spring-launch",
})track("signup", {
plan: { tier: "pro" }, // ✗ nested object
tags: ["a", "b"], // ✗ array
seat_count: 5, // ✗ number — coerce to String(5)
})Limits
| Constraint | Limit |
|---|---|
| Max keys per event | 20 |
| Key length | 128 characters |
| Value length | 512 characters |
| Total payload size | 64 KB |
Values beyond the limit are truncated. Extra keys beyond 20 are dropped, lowest-priority keys first. Treat the limits as the ceiling, not a target.
Typed events
Declare an event map once to get autocomplete and type safety on every track() call. Zero runtime cost. See SDK / typed events.
Querying by property
The MCP tool get_events supports filtering and grouping on a single property key.
"How many signups came from the spring campaign?"
→ get_events({
name: "signup",
property: "source",
value: "spring-launch"
})"Break down signups by plan"
→ get_events({
name: "signup",
group_by: "plan"
})
// Returns: [{ plan: "free", count: 42 }, { plan: "pro", count: 18 }, ...]Funnels can filter on first-party cohort attributes (country, channel, device_type, utm_source, utm_campaign, referrer_host) but not on arbitrary custom properties yet.
Money properties
One property type gets special treatment: Money. Attach amounts and currencies to any event and the get_revenue MCP tool can aggregate them by source, country, or cohort. See Revenue.
Naming conventions
- Use
snake_casefor event names and keys. Matches the enriched fields and keeps MCP queries readable. - Keep names verbs or past-tense actions:
signup,checkout_completed,invite_sent. NotSignuporsignups. - Keep property keys stable. Renaming a key creates two series that your agent has to stitch back together.