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().

Valid
track("signup", {
  plan: "pro",
  source: "pricing_page",
  annual: "true",        // boolean coerced to string
  referrer_campaign: "spring-launch",
})
Rejected
track("signup", {
  plan: { tier: "pro" },   // ✗ nested object
  tags: ["a", "b"],        // ✗ array
  seat_count: 5,           // ✗ number — coerce to String(5)
})

Limits

ConstraintLimit
Max keys per event20
Key length128 characters
Value length512 characters
Total payload size64 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.

Filter
"How many signups came from the spring campaign?"

→ get_events({
    name: "signup",
    property: "source",
    value: "spring-launch"
  })
Group
"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