Announcing our new Vercel integration
Join our Discord
Sign up for free

User identification and audit trails

To attribute events to users, you must include the user object within your event. It must contain at least one identifying attribute from the following, in order of precedence:

  • external_id (preferred; the ID of the user in your system)
  • email
  • phone
  • any other attribute ending in _id (eg. stripe_customer_id, zendesk_id)

Users will only be tracked if one of these fields exists. All attributes within the user object of an event will be saved on the user itself.

By adding user information to an event you automatically activate user-level workflow transparency, user segmentation, and user time travel.

Inngest offers a full audit trail of every event and workflow in your system. Each time an event is received, we inspect the user object to:

  1. Identify the user
  2. Link the event to the user
  3. Update user attributes
  4. Link new workflow runs to this user

Field precedence

In order to attribute an event to a user you must include the user field within your event. The user field must contain at least one identifying field from the following, in order of precedence:

  1. external_id - the user ID in your system. This is the preferred identification key, as it is static
  2. email - the user's email
  3. phone - the user's phone
  4. any other attribute ending in _id (eg. stripe_customer_id, zendesk_id)

Without these fields there is no way for Inngest to know which user the event belongs to. It is preferrable to always include the external_id where possible.

If you send an event containing user data of external_id "1" and stripe_customer_id "S1", either of these attributes can be used to refer to that user from then on. Given the following event:

"name": "ticket.updated",
"data": {
"ticket_id": 189325,
"comment": "Thanks for sending me the return label!",
"status": "open"
"user": {
"external_id": 83561,
`external_id` takes precedence and will be used to upsert a new user.
"zendesk_id": "1274895",
The user will also be tagged with `zendesk_id`. This field can be used in the future to reference the same user without any other identifier.

If you start consuming events directly from Zendesk, as long as `zendesk_id` exists in the user object we will attribute the event correctly: no lookups necessary.
"email": ""
"last_seen": 1632232002369,
"plan": "pro"
"v": "2021-09-15.01",
"ts": 1632232002369,

This event will upsert a user with the specified attributes (external_id, email, zendesk_id, last_seen, and plan). Because we identify users given the above order of preference the system will search for a user in the following order:

  1. external_id matching 83561
  2. email matching
  3. zendesk_id matching 1274895

If not found, a new user will be created. If a user is found, all attributes will be written to that user. From then on any of these identifiers can be used to reference the user in the future. For example, an event containing only a user.zendesk_id of "1274895" will be associated with the same user.


Each user's attributes is stored fully encrypted in our database using row-level encryption the data itself is encrypted and only visible to users signed in to your workspace.

Each user gets its own encryption key which is permenantly deleted when you delete the user from our system, which helps ensure we're GDPR and CCPA compliant.

Finally, this information is never shared without your configuration (for example, unless you share it within a workflow).