The event object is the complete read-only picture of everything the platform knows at the moment your action runs. This page catalogues every field, its type, the point in a flow when it becomes available, and what to do if it is absent.
The seven top-level keys
Section titled “The seven top-level keys”Every field on event belongs to one of these seven groups:
| Key | What it holds |
|---|---|
event.authentication | The assurance level, verified methods, and risk score for this flow run |
event.client | The OAuth2 application that initiated the flow |
event.connection | The authentication method (social provider, enterprise directory, or local database) used for this login |
event.request | The raw HTTP request — IP, geo enrichment, device fingerprint, threat signals |
event.tenant | The IntelliAuth tenant handling this flow |
event.transaction | The in-flight OAuth2 transaction — scopes, redirect URI, nonce, locale |
event.user | The authenticated user's identity, metadata, and enrolled factors |
At the start of a Login flow, before Identity Lookup runs, event.user fields are not yet populated. Reading them directly will throw. Use optional chaining throughout:
const email = event.user?.email ?? 'unknown';const tier = event.user?.app_metadata?.tier ?? 'free';The same caution applies to event.request.geo.* — if the GeoIP database is cold or the IP is private/reserved, geo fields return empty strings and lat/long return 0. Never gate trust decisions on a falsy geo field alone; check event.request.asn.is_bogon first.
event.authentication
Section titled “event.authentication”Set by the flow engine as the run progresses. aal and methods update as each authentication block succeeds. risk_score is written by the Risk Evaluate block and stays 0 until that block runs.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.authentication.aal | string | Flow start | "aal1" after first factor verified; "aal2" after second factor. Starts as "aal0" before any factor is verified. |
event.authentication.methods | unknown[] | Updated as factors pass | Ordered list of verified method names for this run, e.g. ["password", "totp"]. Empty array before any factor runs. |
event.authentication.risk_score | number | After Risk Evaluate block | Integer 0–100. 0 when no Risk Evaluate block has run yet in this flow. |
event.client
Section titled “event.client”Available from flow start. These fields describe the OAuth2 application that launched the login — useful for branching behaviour by client type or restricting certain actions to server-side applications.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.client.id | string | Flow start | Opaque client identifier. |
event.client.name | string | Flow start | Human-readable display name configured in the application settings. |
event.client.type | string | Flow start | "public" for SPAs and mobile apps; "confidential" for server-side applications. |
event.connection
Section titled “event.connection”Describes the authentication method used for this login. Present from flow start; most relevant when your tenant has multiple connections configured (for example, both a local database and Google).
| Path | Type | When populated | Notes |
|---|---|---|---|
event.connection.id | string | Flow start | Opaque connection identifier. |
event.connection.name | string | Flow start | Display name, e.g. "Google" or "Okta SAML". |
event.connection.type | string | Flow start | One of "oidc", "saml", "ldap", or "database". |
event.request
Section titled “event.request”The full request context: raw HTTP fields, geo enrichment from MaxMind GeoLite2, ASN threat signals, and browser fingerprinting output from FingerprintJS. All fields are populated from flow start; geo and ASN fields may be empty for private or reserved IPs.
Core request fields
Section titled “Core request fields”| Path | Type | When populated | Notes |
|---|---|---|---|
event.request.ip | string | Flow start | Client IP after proxy header resolution. May be an IPv6 address. |
event.request.hostname | string | Flow start | Hostname from the HTTP Host header. |
event.request.method | string | Flow start | HTTP method, e.g. "POST". |
event.request.accept_language | string | Flow start | Browser's Accept-Language header value, e.g. "en-US,en;q=0.9". |
event.request.user_agent
Section titled “event.request.user_agent”Parsed from the raw User-Agent header by the server. Treat these as best-effort classifications — unusual or spoofed user agents may parse incorrectly.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.request.user_agent.raw | string | Flow start | Verbatim User-Agent header string. |
event.request.user_agent.browser | string | Flow start | Detected browser name, e.g. "Chrome" or "Firefox". Empty string when undetected. |
event.request.user_agent.browser_version | string | Flow start | Detected browser version, e.g. "124.0.6367.82". Empty string when undetected. |
event.request.user_agent.os | string | Flow start | Detected OS name, e.g. "Windows" or "macOS". Empty string when undetected. |
event.request.user_agent.os_version | string | Flow start | Detected OS version string. Empty string when undetected. |
event.request.user_agent.device_type | string | Flow start | "desktop", "mobile", or "tablet". |
event.request.user_agent.is_bot | boolean | Flow start | true when the User-Agent matches known bot or crawler patterns. |
event.request.geo
Section titled “event.request.geo”Derived from the client IP via the MaxMind GeoLite2 database. Country is ISO 3166-1 alpha-2. Latitude and longitude are city-level — accuracy varies by region and is too coarse for trust decisions. Use country or region for routing logic; use the ASN threat flags for access control.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.request.geo.country | string | Flow start | ISO 3166-1 alpha-2 country code, e.g. "IN". Empty string when the IP is private or the database has no record. |
event.request.geo.region | string | Flow start | State or region name, e.g. "Maharashtra". Empty string when unavailable. |
event.request.geo.city | string | Flow start | City name, e.g. "Mumbai". Empty string when unavailable. |
event.request.geo.latitude | number | Flow start | Approximate latitude. 0 when unavailable. |
event.request.geo.longitude | number | Flow start | Approximate longitude. 0 when unavailable. |
event.request.asn
Section titled “event.request.asn”Heuristic threat signals derived from the client IP's Autonomous System. These flags come from ASN classification and threat feed lookups — treat them as signals, not ground truth. A false value does not certify the IP is safe; it means the platform has no record indicating otherwise.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.request.asn.number | number | Flow start | Autonomous System Number of the client's network. 0 when unresolvable. |
event.request.asn.org | string | Flow start | Organisation name for the ASN, e.g. "AS15169 Google LLC". Empty string when unresolvable. |
event.request.asn.is_vpn | boolean | Flow start | true when the IP is associated with a commercial VPN service. |
event.request.asn.is_tor | boolean | Flow start | true when the IP is a known Tor exit node. |
event.request.asn.is_datacenter | boolean | Flow start | true when the IP belongs to a known cloud or hosting provider. |
event.request.asn.is_bogon | boolean | Flow start | true when the IP is a bogon — unroutable or reserved (loopback, private, link-local). |
Browser fingerprinting
Section titled “Browser fingerprinting”FingerprintJS runs in the browser and sends these identifiers to the platform at flow start. visitor_id is a pseudonymous, probabilistic identifier — it is not a stable user ID and is not personally identifiable on its own. Treat it as one signal among many, not as authoritative device identity.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.request.visitor_id | string | Flow start | FingerprintJS stable visitor identifier for the browser/device combination. Empty string when FingerprintJS was unable to run (headless browsers, strict privacy modes). |
event.request.visitor_confidence | number | Flow start | FingerprintJS confidence score 0–1 for the visitor_id identification. Lower values indicate higher uncertainty. |
event.request.canvas_fp | string | Flow start | Hash of the browser's HTML5 Canvas rendering output. Used alongside visitor_id as a secondary fingerprinting signal. |
event.request.webgl_fp | string | Flow start | Hash of the browser's WebGL renderer output. Empty string in environments where WebGL is disabled. |
event.tenant
Section titled “event.tenant”Available from flow start. Identifies the IntelliAuth tenant running this flow.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.tenant.id | string | Flow start | Opaque tenant identifier. |
event.tenant.name | string | Flow start | Display name of the tenant. |
event.tenant.slug | string | Flow start | URL-safe slug used in subdomain routing. |
event.transaction
Section titled “event.transaction”The in-flight OAuth2 parameters sent by the client application at the start of the authorization request. All fields are available from flow start; some are empty strings when the flow was not initiated by an OAuth2 authorize request (for example, a direct admin login).
| Path | Type | When populated | Notes |
|---|---|---|---|
event.transaction.id | string | Flow start | Unique identifier for this authentication transaction. |
event.transaction.nonce | string | Flow start | Nonce from the OAuth2 authorize request. Empty string when not provided. |
event.transaction.state | string | Flow start | Opaque state value from the authorize request. Returned unchanged to the client after the flow completes. |
event.transaction.redirect_uri | string | Flow start | The URI the authorization code or token is sent to after a successful flow. |
event.transaction.requested_scopes | string | Flow start | Space-separated string of OAuth2 scopes requested by the client, e.g. "openid profile email". Empty string when no scopes were specified. |
event.transaction.acr_values | string | Flow start | Requested Authentication Context Class Reference values, e.g. "urn:mace:incommon:iap:silver". Empty string when not provided. |
event.transaction.locale | string | Flow start | Locale requested by the client, e.g. "en-US". Empty string when not provided. |
event.transaction.prompt | string | Flow start | OAuth2 prompt parameter: "none", "login", "consent", or "select_account". Empty string when not provided. |
event.user
Section titled “event.user”Populated after Identity Lookup runs. Before that block executes, event.user fields are not available — every access on this group must be optional-chained.
| Path | Type | When populated | Notes |
|---|---|---|---|
event.user.id | string | After Identity Lookup | The user's stable usr_-prefixed identifier. |
event.user.email | string | After Identity Lookup | Primary email address. Empty string when the user has no email on file. |
event.user.email_verified | boolean | After Identity Lookup | true when the user has completed email verification. |
event.user.phone | string | After Identity Lookup | Primary phone number in E.164 format, e.g. "+919876543210". Empty string when no phone is on file. |
event.user.phone_verified | boolean | After Identity Lookup | true when the user has completed phone number verification. |
event.user.created_at | string | After Identity Lookup | ISO 8601 timestamp when the identity was created. |
event.user.last_login_at | string | After Identity Lookup | ISO 8601 timestamp of the user's most recent successful login. Empty string for brand-new accounts. |
event.user.app_metadata | Record<string, unknown> | After Identity Lookup | Admin-controlled metadata object. Users cannot read or write this directly. Use api.user.setAppMetadata to write from an action; reads are available immediately in the same run after the write. |
event.user.user_metadata | Record<string, unknown> | After Identity Lookup | User-controlled metadata object — the user can update this from their profile. Actions can read it; writing it from a custom action is not recommended. |
event.user.enrolled_factors | unknown[] | After Identity Lookup | Array of MFA factor type strings the user has enrolled, e.g. ["totp", "webauthn"]. Empty array when no factors are enrolled. |
event.user.identities | unknown[] | After Identity Lookup | Array of linked authentication methods. Each entry is an object with connection, provider, and sub properties — one entry per social or enterprise account linked to this user. |
app_metadata vs user_metadata
Section titled “app_metadata vs user_metadata”event.user.app_metadata is the admin-managed side. It is never exposed to the user in the SDK or profile API. Use it to store derived properties that your application or future actions need: tier classification, signup country, consent timestamps, internal account flags.
event.user.user_metadata is the self-managed side. Users can write to it through the profile API. Read it in actions to learn what the user has told the platform about themselves, but do not overwrite it from an action — that would silently undo user-controlled preferences.
api.user.setAppMetadata applies a shallow merge to app_metadata. If you write { tier: 'enterprise' }, any existing keys in app_metadata that are not named tier remain unchanged. If a value is itself an object, the whole nested object is replaced — pass the full nested value to preserve sub-keys.
Examples
Section titled “Examples”Reading a user's email safely
Section titled “Reading a user's email safely”Always optional-chain when reading event.user.*. Actions that run early in a flow may execute before Identity Lookup has resolved the user.
const email = event.user?.email ?? 'unknown';api.log('info', `Processing login for: ${email}`);Branching on country
Section titled “Branching on country”ISO 3166-1 alpha-2 country codes make country-based routing concise. Cymmetri uses this pattern to route users through a regional compliance check.
const country = event.request.geo.country;
if (country === 'CN' || country === 'RU') { api.state.set('requires_additional_review', true); api.log('warn', `Login from restricted region: ${country}`);}Checking whether a user is on Tor
Section titled “Checking whether a user is on Tor”event.request.asn.is_tor is a direct signal from the platform's threat feed. Cymmetri's security team uses this to block logins from Tor exit nodes for their high-value tenant.
if (event.request.asn.is_tor) { api.deny('tor-exit-node-blocked'); return;}