Audience filters (AST v1)
One JSON format targets everything: saved segments, inline sends, previews, and the
dashboard's visual builder. It's versioned ("v": 1) — a stable contract you
can generate, store, and diff.
{ "and": [
{ "attr": "country", "op": "in", "value": ["NP", "IN", "BD"] },
{ "or": [
{ "attr": "properties.plan", "op": "eq", "value": "pro" },
{ "attr": "properties.lifetime_value", "op": "gt", "value": 100 } ] },
{ "attr": "last_seen_at", "op": "within_last", "value": "7d" },
{ "channel": "webpush", "op": "reachable" }
] }
Attributes
Reserved (exist for every user, several auto-captured):
first_name last_name email phone gender country region city language timezone
first_seen_at last_seen_at external_id. Country is auto-set from IP at
registration (ISO 3166-1 alpha-2); language/timezone come from the SDK.
Custom: anything you send in properties, referenced as
properties.<key>. Keys auto-register in the
property catalog with inferred types — only cataloged
attributes are filterable; unknown ones are rejected, never guessed.
Operators
| Type | Operators |
|---|---|
| all | eq neq in not_in exists not_exists |
| string | contains starts_with |
| number | gt gte lt lte between (between takes [min, max]) |
| date | before after within_last not_within_last anniversary + comparisons.
Windows: "24h" "7d" "2w" "3m". anniversary matches month+day — birthday campaigns. |
| array | includes includes_any includes_all |
| reachability | {"channel": "webpush"|"apns"|"fcm", "op": "reachable"|"unreachable"} |
Combinators & limits
{"and":[…]}, {"or":[…]}, {"not": …} — nest up to
8 levels deep, 64 clauses total. Values are always bound as SQL parameters — filter input
can never inject.
Preview before sending
POST /v1/segments/preview { "filter": … } → { "count": 1207 }
The dashboard shows this live on every edit; use it in CI to sanity-check generated filters.
Or skip the JSON entirely
In the dashboard: “pro users in Nepal active this week” → ✨ AI build → the generated filter is validated against your catalog, compiled by the real engine, and shown with its live count for you to confirm. How that stays trustworthy →