Identify users and groups
Tell Appcues who your users are and which accounts they belong to so you can target experiences and build segments.
Table of Contents
Prerequisites
- The Appcues SDK is installed and the Debugger shows Installed and Connected as green
- You know which user properties and group properties to send (see your installation plan)
All unique users identified within a rolling 30-day period count as a Monthly Active User (MAU), whether or not they see an experience.
Where to add identify() and group()
You can add the Appcues calls directly into an existing file or create a dedicated file for them. For consistent identification, call identify() on every page load. If you use group data, call group() immediately after identify().
Identify users
Required. Call Appcues.identify() to tell Appcues which user is active.
What to pass in
User ID (required) — A unique, opaque identifier for the user, such as a UUID. Avoid using email addresses or other easily guessable values. See the FAQ for developers for guidance on choosing a User ID.
If you use Appcues integrations, your User ID may need to match a value in the integration's system. See Match User IDs across integration for details.
Custom user properties (optional but strongly recommended) — Additional data about the user that powers targeting and segmentation. Without custom properties, your targeting options are limited. Common properties include: createdAt, role, email, language, planTier.
If your User IDs aren't human-readable, set a Display Identifier in Studio using a property like email or fullName. This doesn't change the User ID — it just makes users easier to find in Studio.
Example identify() call
Replace the placeholder values with your actual user data. In production, these values should come from your application's user object, not hard-coded strings.
window.Appcues.identify(
"USER_ID", // unique, required
{
createdAt: 1566932390, // Unix timestamp of signup date
role: "Admin", // user's role or permissions
firstName: "John", // user's first name
email: "john.doe@example.com",// user's email
location: "90210", // for location-based targeting
version: "2.0", // for version-based targeting
language: "Spanish" // for multi-language applications
}
);Call identify() before page() or track(). The identify() call includes a built-in page call, so there is no need to call Appcues.page() immediately after. If page() runs before the user is identified, your users may experience a delay while events buffer.
Don't send a property called UserId, user_ID, or similar. The User ID you pass as the first argument is automatically labeled "User Id" in Appcues. Sending a custom property with a similar name creates duplicate fields and makes targeting confusing.
Properties from integrations sync differently. Properties sent via identify() are available immediately. Properties from integrations arrive through a server-side sync and may not be current on each identify() call. If a property needs to be available right away, send it directly via identify().
Don't send empty strings for null values. If a value is undefined or null, either omit it or send null. An empty string "" is treated as a real value and will affect targeting.
Limit your MAU count. To reduce costs or exclude test users, see Exclude a subset of users from your Appcues installation.
If you need to ensure that only users you verify can send data to Appcues and see Appcues experiences targeted to them, consider setting up Identity Verification.
Identify groups
Recommended. Call Appcues.group() to associate users with an account or organization. This is particularly useful for B2B products where multiple users share an account.
What to pass in
Group ID (required) — A unique identifier for the account, such as an Account ID or company slug. If you use integrations for group data, the Group ID may need to match a value in the integration's system.
Custom group properties (optional) — Attributes shared across all users in the group. Good group properties are things that don't vary from user to user within the account — planTier, companyName, MRR, renewalDate. User-specific data should go in identify() instead.
If your Group IDs aren't human-readable, set a Display Identifier in Studio using a property like companyName.
Example group() call
window.Appcues.group(
"GROUP_ID", // unique, required
{
createdAt: 1566932390, // Unix timestamp of account signup date
purchasedAt: 1566932395, // Unix timestamp of purchase date
planTier: "Standard", // account's plan tier
companyName: "CoolCo", // account name
MRR: 599, // monthly recurring revenue
renewalDate: "06202035", // upcoming renewal date
accountManager: "Jerry" // assigned account manager
}
);Things to watch out for
Always call identify() before group(). The user must be identified first so Appcues can assign them to the group.
A user can belong to multiple groups, but only the most recently associated group is used for targeting. If a user switches accounts within your app, call group() again with the new Group ID.
Format your data correctly
Keep property names simple. Appcues reformats names in the UI — days_since_signup becomes "Days Since Signup" and planName becomes "Plan Name." Avoid cryptic names like property_1 or base64UUID unless your team already knows what they mean.
Send numbers, strings, and booleans only. Appcues ignores complex objects. If you need to send information from an object, flatten it first:
var invoices = user.invoices || [];
Appcues.identify(user.id, {
name: user.name,
email: user.email,
totalInvoices: invoices.length,
lastInvoiceDate: (invoices[0] || {}).created_at
});Keep types consistent. Send numbers as numbers, strings as strings. The number 10 is greater than 2, but the string "10" sorts before "2". Inconsistent types cause unexpected targeting behavior.
String properties are case sensitive — "Admin" and "admin" are treated as different values.
Date properties must be sent in one of these formats, and the format must be consistent every time:
- Non-fractional Unix timestamp (number):
1566932390 -
ISO 8601 string:
"2025-01-15T10:00:00Z" - Formatted string:
"Jan 15, 2025 10:00:00 PM"
Appcues uses Unix epoch timestamps internally.
Reset user session data
Call Appcues.reset() when a user logs out. This clears all Appcues data for the current session, including any in-progress Flows.
Appcues.reset();If you use anonymous users, calling
reset()clears the generated anonymous ID. This can cause Flows to show a second time when the user returns.
Confirm it worked
Open the Appcues Debugger and check:
- Expand the User Identified section. Confirm your User ID and custom properties appear. Appcues auto-properties (prefixed with
_) are listed first, followed by your custom properties. - If you use groups, expand the Group Identified section. Confirm your Group ID and custom group properties appear.
- Properties sent via integrations are not visible in the Debugger. To confirm those, check your Custom Properties tab in Studio.
- If your properties look correct, move to the final step: track events in your web app.
If properties aren't showing up
-
User ID shows but custom properties are missing: Check that you're passing the properties object as the second argument in
identify(). A common mistake is callingidentify("USER_ID")without the properties object. -
Properties show as the wrong type in Studio: You may be sending a number as a string (or vice versa). Check your code —
"599"is a string,599is a number. See Supported data types. -
Group properties aren't showing: Confirm that
identify()is called beforegroup(). Ifgroup()runs first, it has no user to associate the group with.
Still stuck?
Collect the following and email support@appcues.com:
- Your Appcues Account ID
- A screenshot of the Debugger showing the User Identified and Group Identified sections
- The relevant
identify()andgroup()code from your application - The URL where the issue occurs