- Identity resolution — match the event to an existing Account / Contact.
- Auto-create (optional) — create the Account / Contact when no match is found.
- Timeline display — show the event on the matching account’s Events tab.
- Auto-create from events — on/off toggles plus naming defaults.
- Filter which events qualify — predicate rule sets that gate which events trigger creation.
- Hide events from account timelines — patterns to drop from the account-view UI.
How the layers compose
Auto-create has two gates that must both agree before a record is created:- Auto-create toggle for each record type (Contacts / Accounts). The on/off switch.
- Predicate rules in the Filter which events qualify section. Optional payload + identity rule sets — both sets must pass before a record is created.
source: "product_event" so you can filter or audit them later. Events that don’t pass auto-create still flow through identity resolution normally — they just attach to existing records or land with no account, never create.
The timeline exclusion list is independent: it hides noisy event types from the account Events tab and the daily-counts chart. Excluded events are still ingested, archived, and used for identity resolution and auto-create — they just don’t surface in the UI.
Account creation rules
Two predicate sets — both must pass before an Account is created.Payload conditions
Match against the raw event payload. Use dot-paths into the JSON:properties.tiercontext.environmentproperties.$set.signup_completedtraits.plan
{field, operator, value}. Combined with AND.
Identity conditions
Match against the resolved identifiers from the event. Available flat fields:email— resolved fromtraits.email,context.traits.email,properties.email,$set.email, orperson.properties.emaildepending on source.userId— Segment’suserId/anonymousIdor PostHog’sdistinct_id.groupId— Segment’sgroupId/context.groupIdor PostHog’s$groups.<groupKey>/$group_key.payload.<dot-path>— anywhere in the event JSON if you need something outside the three flat fields.
Common patterns
-
Block freemail signups from creating accounts
Identity rule:
email not_contains @gmail.com. Add similar rules for the freemail domains you want to exclude. -
Only create from production events
Payload rule:
context.environment eq production(orproperties.environmentdepending on your client). -
Only create paid customers as accounts
Payload rule:
properties.plan neq trial. -
Skip test groups
Identity rule:
groupId not_starts_with test_. -
Only create when the group really exists
Identity rule:
groupId is_set. Required if your events sometimes lack a group binding.
Contact creation rules
Same structure as account rules — payload conditions + identity conditions — but applied to Contact creation independently of accounts. Contacts and accounts are created on independent gates: an event with an unknownemail can auto-create a Contact even if the account is unresolved.
Useful contact-side rules:
- Block test users by email pattern — Identity rule:
email not_contains @example.com. - Only create when user has been “identified” by your client — Payload rule:
properties.$set.email is_set.
Hide events from account timelines
Some events are critical for identity resolution and auto-create but noisy on the timeline — Segment’sidentify / group calls, PostHog’s $identify / $groupidentify / $set, system pageleave events, internal telemetry, etc.
On the connection card, expand Hide events from account timelines and list the event name patterns to hide. Matching events:
- ✅ Still ingested
- ✅ Still archived to S3 (replayable later)
- ✅ Still rolled up into Postgres
- ✅ Still used for identity resolution and auto-create
- ❌ Hidden from the account Events tab and the daily-counts chart
* wildcards. Examples:
One pattern per line. Max 200 patterns. Each pattern is case-sensitive (event names usually are).
Recommended starter sets
Segment:Browse recent payloads
Configuring rules against an event payload requires knowing the exact dot-path to the property you want to match. Rather than digging through PostHog or Segment documentation:- On the connection card, expand the Auto-create from events or Filter which events qualify section, then click Browse recent payloads → Show.
- Zudo shows the 5 most recent events from your connection, deduplicated by event name.
- Each event lists every available dot-path with its sample value.
- Click a rule’s field input first to focus it, then click any path in the browser to insert it into that input. Without an active focus, the click just copies the path to your clipboard.
How creation actually works
The aggregation job runs every 10 minutes. For each inbound event that didn’t match an existing record:- Checks the connection’s auto-create toggles. Skipped if off.
- Evaluates the org-level payload + identity rules for the record type (account vs. contact). Both must pass.
- For accounts: confirms the minimum events threshold has been met. The connection setting
accountMinEventsdefaults to 1 (create on first event); 5–10 is a common spam guard. - Creates the record:
- Account:
organizationId,connectionId,externalId= the inboundgroupId,source: "product_event". Name comes from the configured payload path or falls back toAccount <id>. - Contact:
connectionId,email,productExternalUserId,source: "product_event". Name from payload path or the email’s local part. Linked to the resolved account when there is one; otherwise unlinked (Reconcile back-fills later).
- Account:
- Subsequent events for the same group / user resolve normally via the identity chain without re-creating.
Operators
Rule operators across both payload and identity sets:
Unknown operators are treated as “pass” with a server-side warning — so a UI regression can’t accidentally block all creation.
Provenance and cleanup
Auto-created records carrysource: "product_event". This shows up as a source value on the Account / Contact (indexed for fast filter). Use it to:
- Filter the Accounts list to “Auto-created” for spot-checks.
- Bulk-delete records that auto-created in error.
- Distinguish from manually-imported records (which carry
source: "manual","vitally","csv_import", or"api"depending on origin).
What auto-create does NOT do
- Doesn’t merge existing duplicate accounts/contacts. Two records with overlapping emails stay separate; auto-create never deletes.
- Doesn’t enrich created records with data from third-party services. Records are bare — you can enrich with Vitally sync, a CSV import, or the Zudo API.
- Doesn’t back-fill historic events. Once events have been aggregated as
accountId: null, creating the account later won’t retroactively attach them. Use Reconcile past events on the connection card for that. - Doesn’t cross-stitch identity. If the same human fires events with two different
anonymousIdsand no shared email, you get two contacts.
