Skip to main content
You are sending events from a server where no user is logged in — a webhook, a cron job, a system event — and there is no obvious value for distinct_id. Set it to the empty string.
Events with an empty distinct_id will be excluded from all behavioral analysis. They are still ingested and still queryable as event volume; they just cannot participate in per-user analysis, which is the correct outcome for an event that belongs to no user.

Do Not Omit distinct_id

If you leave it out entirely, Mixpanel will use the ip address of the incoming request and compute a distinct_id using a hash function. Every event from the same server then shares one synthetic user. That is worse than the empty string: it silently invents a user, inflates per-user metrics, and can concentrate enough volume on a single ID to trigger hot shard limits. The empty string avoids this. Mixpanel spreads those events across shards rather than keying them to one ID.

Do Not Use a Placeholder

Mixpanel rejects a list of values that usually indicate a mistake:
An event carrying one of these fails validation with a 400. The same list applies to $insert_id.

When There Is a User

If the event does belong to a known user, Mixpanel recommends not setting the distinct_id directly; instead you should set the $device_id and $user_id and have our API determine the distinct_id for you. On Simplified ID Merge, distinct_id is derived automatically: it takes the value of $user_id when present, otherwise $device_id prefixed with $device:. If you do set it manually, it should be the same value as the $user_id.
This page describes Simplified ID Merge, the default for organizations created from April 2024. Check which system your project uses in project settings. On Original ID Merge, server-side anonymous events set distinct_id to the anonymous ID directly and identification happens through a $identify event.