# Accessibility in Userpilot in-app messages Source: https://docs.userpilot.com/accessibility/accessibility-in-userpilot-in-app-messages Learn how Userpilot supports accessible in-app messages by aligning with WCAG 2.1 Level AA standards, helping teams build inclusive user experiences. ### What is web accessibility? Web accessibility means designing and building digital content, such as websites, web apps, and mobile apps, so that people of all abilities, including those with visual, auditory, motor, or cognitive impairments, can perceive, understand, navigate, and interact with it. It’s not just about compliance; accessible design improves usability for everyone, from older adults to keyboard-only users. At Userpilot, our engineering team started by reviewing WCAG and identifying areas to improve accessibility in our in-app messages. ### Which web content accessibility guidelines apply? The [**Web Content Accessibility Guidelines (WCAG)**](https://www.w3.org/WAI/standards-guidelines/wcag/) provide the global standards for this. They’re built on four key principles: * **Perceivable:** Content must be visible or audible; for example, images should include alt text. * **Operable:** All interface elements should work via keyboard and other input methods. * **Understandable:** Content and navigation should be clear, with the page language defined in the code. * **Robust:** Code should follow web standards to work across browsers and assistive tools. For example, one specific success criterion is Contrast (Minimum) - SC 1.4.3 in WCAG 2.1, which requires a contrast ratio of at least 4.5:1 for normal text. You can consult the full standard here: [WCAG 2.1 Recommendation](https://www.w3.org/TR/WCAG21/). In practice, many organisations target **WCAG 2.1 Level AA** conformance (which covers many of the key accessibility issues). ## How Userpilot supports accessibility Userpilot currently aligns with key **WCAG 2.1 Level AA** principles by offering essential accessibility features in in-app messages. These include: * Keyboard navigation * Screen reader support * Color contrast **Multi-language accessibility** - Userpilot automatically sets the **language attribute** on HTML elements, enabling screen readers to detect the correct language and read text with accurate pronunciation and context. ### Screen reader support Screen readers are tools that help people with visual impairments understand what’s on a webpage by reading the content out loud. To make this work smoothly, we make sure all text is easy to read and navigate, and we use **ARIA labels** and **Alt text** to describe what each element does or what state it’s in. Combined with solid keyboard navigation, full support for screen readers ensures everyone can easily access and interact with our in-app messages. Demo of screen reader support in a Userpilot flow ### Color contrast Userpilot encourages maintaining **high color contrast** between text and backgrounds and avoiding color as the sole indicator of meaning (e.g., success vs. error). In your in-app messages, ensure contrast ratios follow **WCAG 2.1 standards**, **4.5:1** for normal text and **3:1** for large text. Since Userpilot allows full control over fonts and colors through its **Themes**, you can easily adjust styles to meet these accessibility requirements. Theme editor showing font contrast ratio and WCAG pass/fail indicators ## Accessibility features built into Userpilot All Userpilot content automatically includes key accessibility features, no setup needed. These enhancements make your in-app messages easier to navigate and more inclusive for everyone. ### Semantic headings Userpilot uses proper heading structures (like H2, H3, and paragraph tags) to create logical reading content elements. Screen readers rely on this hierarchy to help users move through content smoothly and understand its structure. ### ARIA Labels ARIA (Accessible Rich Internet Applications) labels are automatically applied to describe each element’s purpose. This helps users who rely on assistive technologies, such as screen readers, better understand what each element does. ### Roles The right HTML roles (for example, role="button" or role="dialog") are included by default so assistive tools can accurately interpret and announce how each element behaves. Resource Center widget with corresponding ARIA roles and labels shown in DevTools ## In-app messages that support accessibility in Userpilot Userpilot’s accessibility features apply across **all in-app experience types**, ensuring inclusivity throughout the user journey. Accessibility is supported in: * **Flows** * **Spotlights** * **Embeds (Cards and Banners)** * **Checklists** * **Resource Center** * **NPS** * **Surveys** Each of these experiences inherits accessibility enhancements such as customizable **alt text for images**, compliant **color contrast ratios**, and **language attributes**, helping you create consistent and inclusive product experiences. 1. To make videos accessible in **Flows**, **Checklists**, or the **Resource Center**, add `aria-label` to the embed code and include a brief video description for screen readers. Embed Video dialog with an aria-label describing the video for screen readers 2. For images in **Flows** or **Resource Center posts**, click the **accessibility** icon and add a short description to make the image readable by screen readers. Image accessibility panel with an alt text field ### Keyboard navigation Keyboard navigation plays a crucial role in making your in-app messages accessible. Many users with visual or auditory impairments rely on their keyboards along with screen readers to explore content and interact with elements. You can test this yourself by enabling your device’s built-in screen reader and navigating through your in-app experiences using the standard keyboard shortcuts. As you move through each element, you’ll hear how focus shifts across the interface and how every item is announced aloud. * **Tab** → Move **forward** through interactive elements (links, buttons, inputs, etc.) * **Shift + Tab** → Move **backward** through elements * **Enter/Spacebar** → **Activate** the selected element (like clicking a button or link) * **Arrow keys** → Navigate **within** components such as dropdown menus, radio buttons, sliders, or tabs * **Esc (Escape)** → **Close** modals, tooltips, or dropdowns Demo of keyboard navigation announcing focus through a Resource Center panel For **tooltip** and **driven action steps**, enabling the autofocus option helps users navigate smoothly with the keyboard by clearly indicating the active element. Tooltip settings with the autofocus toggle enabled [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Cloning Content Across Applications Source: https://docs.userpilot.com/admin-console/duplicating-and-cloning-content-across-applications Clone surveys, checklists, flows, themes, and design library groups from one Userpilot app into your others to reuse content and keep experiences consistent. Clone surveys, checklists, flows, themes, and design library groups from one Userpilot application into your others. Reuse content across apps instead of rebuilding it from scratch, and keep experiences consistent across every app you manage. ## Overview If you manage more than one application in Userpilot, you can copy content from one app into your others instead of recreating it manually in each one. This works for surveys, checklists, flows, themes, and design library groups, and you can copy into a single app, several apps, or all of them at once. The content itself comes across intact, while app-specific settings reset so you can tailor them for each destination. ## Use cases * **Multi-region or multi-brand setups:** if you run separate apps for different regions, brands, or divisions, build a flow, checklist, or survey once and copy it everywhere instead of rebuilding it per app. * **Consistent branding across apps:** copy a theme or design library group so every app shares the same look and feel. * **Launching a new app:** instantly seed a newly added application with your proven content rather than starting from an empty workspace. * **Reducing manual error:** maintain one source of truth and copy it out, instead of risking typos or missed updates when recreating content by hand. ## Get Started #### **Copy a single item to other apps** 1. On any content item, click the **⋮** menu and select **Duplicate**. 2. In the duplicate window, turn on **Duplicate to other applications**. 3. Choose your destination(s) in the app picker — pick individual apps, or select **All applications**. 4. *(Optional)* Enter a custom name for the copied content. 5. Confirm. You'll get per-app success/failure feedback. #### **Copy several items at once (Surveys, Checklists, Flows)** 1. Select one or more items from the list. 2. Click **Clone to other applications**. 3. Pick your destination app(s) and confirm. Screenshot 2026 06 10 At 14 09 29 #### **What you can clone** | Content type | Duplicate in
the same app | Bulk duplicate | Clone to other
apps | | --------------------------- | ------------------------------- | -------------- | ------------------------- | | Surveys | Yes | Yes | Yes | | Checklists | Yes | Yes | Yes | | Flows | Yes | Yes | Yes | | Themes | Yes | No | Yes | | Design library
groups | Yes | No | Yes | ### Permissions The cross-app option only appears if you have access to more than one application — it's available to users who manage multiple apps via the Admin Console. If you have access to a single app, you'll see the standard same-app duplicate options only. ### **What doesn't get transferred over?** To keep each app correctly scoped, the following settings *do not* get transferred over when cloning content across multiple applications; * Trigger * Targeting (pages / domains) * Audience * Goals (flows only) These will need to be reconfigured after being cloned. The content itself — steps, questions, design — comes across intact. **Further information:** * **Checklists that trigger a flow:** the triggered flow is cloned (or reused) in the destination app automatically. * **Themes & design library groups:** if a matching one already exists in the destination, it's reused rather than duplicated — so you won't get (copy) clutter. Design library cloning covers Colors, Shadows, Spacing, Typography, and Assets. * **Plan limits:** each app has its own plan limit. Once an app reaches its limit, content won't duplicate into it. Nothing is partially copied.  # Admin Console Source: https://docs.userpilot.com/admin-console/overview All users who have Userpilot installed on more than one application have access to the Admin Console. Additional applications can be added to your plan. All users who have Userpilot installed on more than one application have access to the Admin Console. Additional applications can be added to your plan. ### Overview The Admin Console in Userpilot gives you centralized control and visibility over all of your applications, users, and account settings. From the admin console, users can create reports and dashboards using data from all of their applications, manage user roles and permissions, configure authentication, and manage subscription information at an organizational level. ### Use Cases * **Cross-application analytics:** Create reports and dashboards that bring together data from multiple applications to gain a complete view of performance. For example, compare active users between apps, track core feature adoption across products, or view all users engaging with your entire product suite. * **Centralized user and role management:** Add teammates, assign roles, and adjust permissions for any application from a single location, ensuring each person has the right level of access based on their role in the organization. * **Security configuration:** Configure and enforce SSO or two-factor authentication across all applications to maintain consistent security standards organization-wide. ### Get started If your organization already has multiple applications within Userpilot, the Admin Console will be automatically enabled. Open the application switcher menu in the navigation bar and select **View Admin Console**. From within the Admin Console, use the same menu and select **Exit Admin Console** to return to your previous application. View Admin Console button in the application switcher menu ### Aggregated Analytics In the Admin Console, you can build reports and dashboards that combine data from all your applications into a single view. This unified approach helps you better understand user behavior across platforms and uncover meaningful insights with full context. When adding a metric to a report, start by selecting the application it belongs to. This allows you to include events from multiple applications in one report, making cross-app comparisons easier and more insightful. Select app dropdown when adding a metric to a report You can also view key product usage metrics aggregated across all your applications in the **Product Usage Dashboard**. This dashboard helps you quickly understand: * The total number of unique users and companies active across all applications * The top-performing pages and events across your entire product suite * The most engaged users and companies, based on activity across all applications Product Usage Dashboard with aggregated analytics ### Manage Applications and Teammates Easily manage user roles, permissions and applications from one centralized location within the Admin Console. **Manage Applications:** After adding additional app tokens to your account, kickstart the set-up process directly from Userpilot by specifying the application name and who you would like to provide access to. **Manage Teammates:** From the **Teammates** tab, you can invite new users to any application, assign appropriate roles, and grant access to the Admin Console as needed. Managing applications and teammates in the Admin Console **Manage Authentication:** From the **Authentication** tab, you can enhance security and control by enabling [SSO](/configure/team-and-roles/sso), [two-factor authentication (2FA)](/configure/team-and-roles/2fa), [SCIM directory sync](/configure/team-and-roles/scim), and [JIT provisioning](/configure/team-and-roles/jit) across all of your Userpilot applications. ### Manage Userpilot Subscription and Add-ons Manage your Userpilot plan and any add-ons across all your applications from the **Billing** section of the Admin Console. Here, you can view and update key subscription details, including: * Monthly Active User (MAU) usage across applications * Organization information * Recent invoices In the **Add-ons** tab, you can enhance your plan by enabling additional features, which will be applied to all connected applications. Add-ons tab in the Admin Console billing section [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Userpilot MCP Server Source: https://docs.userpilot.com/ai/userpilot-mcp-server Connect AI assistants like Claude to your Userpilot account to explore analytics, look up users and companies, and create segments, reports, and surveys. ## Overview The Userpilot MCP server connects AI assistants to your Userpilot account. Once connected, you can ask questions in plain language, such as "How did my signup funnel perform last month?", and the assistant reads the answer directly from your Userpilot data. You can also ask it to create things for you, such as segments, reports, dashboards, and survey drafts. MCP (Model Context Protocol) is an open standard that AI tools use to talk to other products. Userpilot hosts the server for you: you connect from the AI tool you already use and sign in with your regular Userpilot login. There is nothing to install or configure inside Userpilot. ## Use Cases * **Ask analytics questions**: "What's the completion rate of my onboarding funnel this quarter?" or "Show retention for users who used the export feature." * **Explore users and companies**: "Which companies were most active this week?" or "Summarize this user's recent activity." * **Build as you think**: "Create a segment of users who completed onboarding but never opened reports" or "Build a dashboard for my activation metrics." * **Draft surveys**: "Draft a short survey asking users why they canceled." You review and publish it in Userpilot. * **Look things up while you work**: "What audience does the 'New user tour' flow target?" or "List the events we track on the checkout page." ## What you need * A Userpilot account. The MCP server is available on all plans, and your plan's feature limits apply the same way they do in the app. * An AI tool that supports remote MCP servers (sometimes called custom connectors), for example Claude, Claude Code, ChatGPT, Cursor, or Microsoft 365 Copilot. The server address is: ```text theme={null} https://mcp.userpilot.io/mcp ``` ## Connect your AI tool Custom connectors are available on paid Claude plans. On Team and Enterprise plans, a Claude admin adds the connector once for the organization; every member then connects it with their own Userpilot login. Open the account menu (your name, bottom left) and go to **Organization settings → Connectors** (under "Libraries & Access"). Click **+ Add → Custom → Web**. In the **Add custom connector** dialog, name it "Userpilot" and paste the server address above into **Remote MCP server URL**. Leave the Advanced settings fields empty — Userpilot registers automatically. Keep **Individual sign-in** switched on, then click **Add**. On a personal account, add the same connector under **Settings → Connectors** instead. Click **Connect** on the Userpilot connector. Your browser opens the Userpilot sign-in. Log in as you always do (SSO included). On team plans, each member does this once with their own login. Userpilot shows a permission screen. Tick the access you want to grant and approve. Choosing what the assistant can access Claude can now use Userpilot in your chats. You can toggle it per conversation from the tools menu. ```bash theme={null} claude mcp add --transport http userpilot https://mcp.userpilot.io/mcp ``` Run `/mcp` inside Claude Code, select **userpilot**, and complete the browser sign-in and permission screen. Claude Code lists the Userpilot tools once the connection is active. Custom connectors are available on paid ChatGPT plans and need developer mode switched on. On Business and Enterprise plans, a ChatGPT workspace owner may need to allow custom connectors first. Open **Settings → Apps & Connectors → Advanced settings** and switch on **Developer mode**. Turning on developer mode in ChatGPT settings Still under **Apps & Connectors**, create a new connector. Name it "Userpilot", paste the server address above into the **MCP Server URL** field, and choose **OAuth** as the authentication method. Adding the Userpilot connector in ChatGPT Save the connector. Your browser opens the Userpilot sign-in — log in as you always do, then tick the access you want to grant and approve. Open a new conversation and switch on the Userpilot connector from the composer's tools menu. For deep research, pick Userpilot as a source. Switching on the Userpilot connector in a ChatGPT conversation ChatGPT can now use Userpilot in that conversation. ChatGPT's connector settings change often. If the menus no longer match, the parts that stay the same are: create a **custom MCP connector**, choose **OAuth**, and use the server address above. Open **Cursor Settings → MCP → Add new MCP server**, or edit `~/.cursor/mcp.json` yourself: ```json theme={null} { "mcpServers": { "Userpilot": { "url": "https://mcp.userpilot.io/mcp" } } } ``` If that file already exists, add the `userpilot` entry inside the existing `mcpServers` object rather than replacing the file, so your other servers stay. To use Userpilot in one project only, create `.cursor/mcp.json` in that project folder instead. Restart Cursor, or refresh the list from **Settings → MCP**. The `userpilot` server appears there. The Userpilot server listed in Cursor's MCP settings Use the sign-in prompt on the `userpilot` entry. Your browser opens the Userpilot sign-in — log in as you always do, then tick the access you want to grant and approve. Choosing Userpilot permissions when connecting from Cursor Back in **Settings → MCP**, the `userpilot` entry lists the Userpilot tools it can use. Userpilot tools loaded in Cursor Cursor's agent can now use Userpilot in chat. Connecting Userpilot to Microsoft 365 Copilot goes through **Microsoft Copilot Studio**, where you build and publish the agent that end users chat with. Sign in to [Copilot Studio](https://copilotstudio.microsoft.com/). On the **Home** page, under **Start building from scratch**, select **Create an agent**, then give it a name, for example "Userpilot". Creating a new agent from Copilot Studio's Home page If your organization already has an agent you want to use instead, open it from **Agents** in the left navigation and skip to the next step. In the agent, select **Tools** in the left navigation, then **Add a tool** and **New tool**. Search for `Model Context Protocol` and select it, and the **Add a Model Context Protocol server** dialog opens. Adding a new Model Context Protocol server in Copilot Studio Name it "Userpilot", write a short description, and paste the server address above into **Server URL**. Under **Authentication**, choose **OAuth 2.0**, then **Dynamic discovery**. Userpilot supports OAuth 2.0 dynamic client registration, so there's nothing else to configure. Choosing OAuth 2.0 with Dynamic discovery for the Userpilot MCP server Select **Create**, then **Next**. On the **Add tool** dialog, select **Create a new connection**. Your browser opens the Userpilot sign-in: log in as you always do (SSO included), then tick the access you want to grant and approve. Choosing what the assistant can access Select **Add to agent** to finish. The Userpilot tool appears under the agent's **Tools** section. Select **Publish** at the top of the agent page, then **Publish** again to confirm. Go to **Channels**, select the **Teams and Microsoft 365 Copilot** tile, keep **Make agent available in Microsoft 365 Copilot Chat** checked, then select **Add channel**. Enabling the Teams and Microsoft 365 Copilot channel for the agent Once connected, open [Microsoft 365 Copilot](https://copilot.cloud.microsoft/), enter **@**, select your agent from the list, and start asking it about your Userpilot data. Microsoft 365 Copilot can now use Userpilot when your agent is mentioned. Any tool that supports remote MCP servers with OAuth sign-in can connect: 1. Add a remote (HTTP) MCP server in the tool's settings and paste the server address above. 2. When the tool prompts you, sign in with your Userpilot login and approve the permissions. The exact menu names vary by tool. Look for "MCP servers", "connectors", or "integrations" in its settings. ## Choose what the assistant can access When you connect, Userpilot shows a permission screen. You decide what the assistant can see and change: | Permission | What it allows | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | Read your product data, analytics, and reports | The foundation, always required: reports, dashboards, events, pages, features, flows, surveys, segments, and analytics results. | | Read individual user and company profiles | Profile details and activity for specific users and companies. Leave it unchecked to keep individual records out of AI conversations. | | Read session replay data | Session replay lists and activity summaries. | | Create and update user segments | New segments, and changes to existing ones. | | Create and update reports and dashboards | New reports and dashboards, and changes to existing ones. | | Create and update surveys (saved as drafts) | Survey drafts for you to review. Nothing reaches your users until you publish. | | Keep this connection active without re-login | Stay signed in between conversations. Without it, access ends about 15 minutes after each sign-in. | A few things to know: * **You can change your mind later.** To grant a permission you skipped, connect again from your AI tool: the permission screen appears and remembers what you approved before. * **Write permissions need the read permission.** The screen enforces this automatically. * **Changes are real.** Segments, reports, and dashboards the assistant creates or updates take effect immediately, just as if you made the change in the app. ## What the assistant can and can't do With the permissions you grant, the assistant can: * Run and read analytics: funnels, trends, retention, paths, saved reports, and dashboards. * Look up your product setup: flows, surveys, events, pages, features, segments, and more. * Read user and company lists and profiles. * Create and update segments, reports, dashboards, and survey drafts. * Go beyond the basics: when a question needs it, the assistant can search hundreds of additional read-only operations. It can never: * Build or publish in-app content such as flows and banners (content building stays in the Userpilot builder). * Delete anything. * Access team management, billing, account settings, or other administration areas. * Do anything your own Userpilot role doesn't allow. ### Working with multiple apps If your account has more than one app, the assistant can list the ones you have access to and ask which one to use. It remembers your choice for the connection, and you can tell it to switch at any time. ## Security and privacy * **Your login, your permissions.** The connection runs under your own Userpilot user. The assistant can only see and change what your role allows, in the apps you have access to. * **You control the scope.** The permission screen decides what is reachable; everything outside it is refused by Userpilot's servers, not by the assistant's judgment. * **No destructive access.** Delete operations and administration areas are not available through the connection at all. * **Built-in limits.** Rate limits automatically contain runaway or abusive usage. * **Disconnect anytime.** Remove the connector in your AI tool to stop new access. Without the "keep active" permission, access also expires on its own shortly after each sign-in. Data the assistant reads through this connection is processed by your AI provider (for example, Anthropic for Claude) under that provider's terms. Review your organization's AI policies before connecting tools to customer data. ### FAQs Any tool that supports remote MCP servers with OAuth sign-in. Claude, Claude Code, ChatGPT, Cursor, and Microsoft 365 Copilot are documented step by step above; for other tools, use the server address and follow the tool's own instructions for adding an MCP server or custom connector. You skipped that permission when connecting. Connect again from your AI tool. The permission screen appears with your earlier choices remembered; tick the missing one. Your access to that app changed. Ask the assistant to list your workspaces and pick one you can access. Only within the write permissions you granted, and never beyond them: segments, reports, dashboards, and survey drafts. It cannot delete anything, publish content, or touch account settings. If you grant no write permissions, the connection is read-only. Anyone with a Userpilot login. On Claude Team and Enterprise plans, a Claude admin adds the connector once for the organization; each member then connects and signs in as themselves, and their connection mirrors their own role and app access. Your AI tool keeps its own copy of the tool list. In Claude, open the Userpilot connector's settings and use **Refresh tools**; disconnecting and reconnecting alone does not refresh the list. Remove the connector in your AI tool. If you need a connection revoked on the Userpilot side (for example, for a teammate who left), contact support. For any questions or concerns please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Authentication Source: https://docs.userpilot.com/api-references/authentication Authenticate your API requests securely using API tokens. Userpilot APIs use API tokens to authenticate requests. You can view and manage your API key in the **Environment Page** of your Userpilot dashboard. ## How to Use Your API Key Include your API key in the `Authorization` header of every API request: ```http theme={null} -H 'Authorization: Token {{API_KEY}}' ``` Your API key carries many privileges. Keep it secure and do not share it in publicly accessible areas. ## Where to Find Your API Key 1. Log in to your Userpilot dashboard. 2. Go to the **Environment Page**. 3. Copy your API key from the API Key section. All API requests must be made over HTTPS. ## Security Best Practices * Never expose your API key in client-side code or public repositories. * Rotate your API keys regularly. * If you suspect your API key has been compromised, please reach out to [support@userpilot.com](mailto:support@userpilot.com) for regenerating it. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Bulk Identify/Update Companies Source: https://docs.userpilot.com/api-references/bulk-updates/companies Bulk identify and update company profiles using Userpilot's HTTP API for large-scale company data synchronization. The Bulk Identify Companies API allows you to create or update multiple company profiles in a single request. This is ideal for large-scale B2B data synchronization, initial company imports, or batch updates from your CRM or database systems. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. ## Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/companies/bulk_identify ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. ## Headers | Header | Value | Required | | --------------- | ----------------------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `Accept` | `application/json, text/plain, */*` | Yes | ## Request Body | Field | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------------------- | | `companies` | array | Yes | Array of company objects | | `company_id` | string | Yes | Unique identifier for the company | | `metadata` | object | No | Key-value pairs describing the company (primitives only) | ## JSON Payload Example ```json theme={null} { "companies": [ { "company_id": "company_001", "metadata": { "subscription_status": "active", "subscription_plan": "enterprise", "deal_size": "500000" } }, { "company_id": "company_002", "metadata": { "subscription_status": "trial", "subscription_plan": "basic" } } // ... Additional companies up to 10,000 total ] } ``` **Optimize Your Payload**: Use the full 10,000 record limit to maximize processing efficiency. The example above shows the structure for individual records - you can include up to 10,000 such records in a single request. ## Response A successful call returns a job object: ```json theme={null} { "job_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "status": "queued", "submitted_at": "2025-02-02T12:35:10Z" } ``` **Monitor Your Job**: Use the job ID from the response to track the status of your bulk update job. Remember that only one bulk update job (user or company) can run at a time. *** ## File Upload (NDJSON) For very large updates, you may upload NDJSON files containing company profiles. ### Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/companies/bulk_identify ``` ### Headers | Header | Value | Required | | --------------- | ----------------------------------- | -------- | | `Content-Type` | `multipart/form-data` | Yes | | `Accept` | `application/json, text/plain, */*` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | ### Request Body Submit the file using multipart/form-data. Include a key called `file` with your NDJSON file: ```bash theme={null} curl -X POST "https://analytex.userpilot.io/v1/companies/bulk_identify" \ -H "Authorization: Token {YOUR_API_KEY}" \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/your/file.ndjson" ``` Each line in the file should be a valid JSON object. File size is limited to 50 MB. Each request can contain up to 10,000 companies. *** ## Rate Limits The Bulk Updates API implements rate limiting to ensure efficient processing of large-scale company data operations while maintaining system stability. These limits help optimize performance for bulk company profile updates and synchronizations. ### Rate Limit Details * **Job Limitation**: **One job at a time** - The system processes only one bulk update job at a time (either user or company bulk update) * **Company Processing**: **1,800 companies per minute** service consumption rate * **JSON Payload**: **Up to 10,000 records per request** * **File Upload**: **Up to 50 MB file size** ### Error Responses When you exceed these limits, the API returns: * **`409 Conflict`**: Returned when attempting to create a new job while another is in progress * **`413 Payload Too Large`**: Returned when file size exceeds 50 MB or payload exceeds 10,000 records ### Best Practices **Check Job Status**: Always verify no existing bulk update jobs are running before initiating a new one. **Optimize Batch Sizes**: Use the full 10,000 record limit for JSON payloads to maximize efficiency. **Monitor Processing**: Track your company processing speed to stay within the 1,800 companies per minute limit. **Handle File Uploads**: For large datasets, use file uploads (up to 50 MB) instead of JSON payloads. *** ## Limitations * File size up to 50 MB (for file uploads). * JSON/NDJSON list up to 10,000 companies per request. * Only primitive types (string, number, boolean, null) are supported in metadata. * A company will not appear on the dashboard unless at least one user is associated with it. *** ## Best Practices * **Validate Your Data:** Ensure each record includes the required `company_id` and that metadata is formatted correctly. * **Monitor Jobs:** Always use the job monitoring endpoints to check the status of your bulk updates. * **Rate Limits and Retries:** If you experience rate limits or timeouts, batch your requests and monitor job statuses before submitting more. *** ## Troubleshooting * **Authentication Errors:** Verify your API token and that it is sent in the `Authorization` header. * **Invalid Payload:** Ensure your JSON/NDJSON is well-formed and required fields are present. * **Job Failures:** Use the job status endpoint to inspect error messages for failed records or processing issues. # Bulk Identify/Update Users Source: https://docs.userpilot.com/api-references/bulk-updates/users Bulk identify and update user profiles using Userpilot's HTTP API for large-scale user data synchronization. The Bulk Identify Users API allows you to create or update multiple user profiles in a single request. This is ideal for large-scale data synchronization, initial user imports, or batch updates from your CRM or database systems. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. ### Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/users/bulk_identify ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. ### Headers | Header | Value | Required | | --------------- | ----------------------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Accept` | `application/json, text/plain, */*` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | ### Request Body | Field | Type | Required | Description | | ------------ | ------ | -------- | ----------------------------------------------------- | | `users` | array | Yes | Array of user objects | | `user_id` | string | Yes | Unique identifier for the user | | `company_id` | string | No | Unique identifier for the company (if applicable) | | `metadata` | object | No | Key-value pairs describing the user (primitives only) | ### JSON Payload Example ```json theme={null} { "users": [ { "user_id": "user_001", "company_id": "comp001", "metadata": { "last_ticket_created": "2025-02-01T10:20:30Z", "tickets_created": "15", "tickets_resolved": "14", "tickets_pending": "1", "avg_resolution_time": "2h", "customer_satisfaction": "4.8", "escalation_count": "1" } }, { "user_id": "user_002", "company_id": "comp002", "metadata": { "last_ticket_created": "2025-01-31T09:15:00Z", "tickets_created": "8", "tickets_resolved": "7", "tickets_pending": "1", "avg_resolution_time": "3h", "customer_satisfaction": "4.5", "escalation_count": "0" } } // ... Additional users up to 10,000 total ] } ``` **Optimize Your Payload**: Use the full 10,000 record limit to maximize processing efficiency. The example above shows the structure for individual records - you can include up to 10,000 such records in a single request. ### Response A successful call returns `202 Accepted` with a job object: ```json theme={null} { "job_id": "bulk:jobs:{APP_TOKEN}:9536d797-7039-4d30-8c11-ac437367d732", "status": "queued", "start_time": "2025-02-02T12:34:56.000000", "end_time": null, "total_rows": 0, "file_size": 84, "filename": "{APP_TOKEN}_identify_user_9536d797-7039-4d30-8c11-ac437367d732.ndjson", "links": "/v1/background_jobs/bulk:jobs:{APP_TOKEN}:9536d797-7039-4d30-8c11-ac437367d732", "type": "identify_user" } ``` **Monitor Your Job**: Use the job ID from the response to track the status of your bulk update job. Remember that only one bulk update job (user or company) can run at a time. Row-level validation (e.g. a missing `user_id`) doesn't fail the request itself: the job is still accepted and queued. Invalid rows fail individually during processing; check the job status endpoint for a `reason_for_failure` field explaining what went wrong with each failed row. *** ## File Upload (NDJSON) For very large updates, you may upload NDJSON files containing user profiles. ### Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/users/bulk_identify ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. ### Headers | Header | Value | Required | | --------------- | ----------------------------------- | -------- | | `Content-Type` | `multipart/form-data` | Yes | | `Accept` | `application/json, text/plain, */*` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | ### Request Body Submit the file using multipart/form-data. Include a key called `file` with your NDJSON file: ```bash theme={null} curl -X POST "https://analytex.userpilot.io/v1/users/bulk_identify" \ -H "Authorization: Token {YOUR_API_KEY}" \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/your/file.ndjson" ``` Each line in the file should be a valid JSON object. File size is limited to 50 MB. Each request can contain up to 10,000 users. ### Response A successful call returns the same job object shape as the JSON payload endpoint above, with one difference: `filename` reflects the name of the file you uploaded instead of an auto-generated name. *** ## Rate Limits The Bulk Updates API implements rate limiting to ensure efficient processing of large-scale user data operations while maintaining system stability. These limits help optimize performance for bulk user profile updates and synchronizations. ### Rate Limit Details * **Job Limitation**: **One job at a time** - The system processes only one bulk update job at a time (either user or company operations) * **User Processing**: **1,800 users per minute** service consumption rate * **JSON Payload**: **Up to 10,000 records per request** * **File Upload**: **Up to 50 MB file size** ### Error Responses The API returns the following error responses: * **`401 Unauthorized`**: Returned when the API token is missing, invalid, or isn't a write/admin token * **`409 Conflict`**: Returned when attempting to create a new job while another is in progress * **`413 Payload Too Large`**: Returned when file size exceeds 50 MB or payload exceeds 10,000 records ### Best Practices **Check Job Status**: Always verify no existing bulk update jobs are running before initiating a new one. **Optimize Batch Sizes**: Use the full 10,000 record limit for JSON payloads to maximize efficiency. **Monitor Processing**: Track your user processing speed to stay within the 1,800 users per minute limit. **Handle File Uploads**: For large datasets, use file uploads (up to 50 MB) instead of JSON payloads. *** ### Limitations * File size up to 50 MB (for file uploads). * JSON/NDJSON list up to 10,000 users per request. * Only primitive types (string, number, boolean, null) are supported in metadata. *** ### Best Practices * **Validate Your Data:** Ensure each record includes the required identifiers (`user_id`) and that metadata is formatted correctly. * **Monitor Jobs:** Always use the job monitoring endpoints to check the status of your bulk updates. * **Rate Limits and Retries:** If you experience rate limits or timeouts, batch your requests and monitor job statuses before submitting more. *** ### Troubleshooting * **Authentication Errors:** Verify your API token and that it is sent in the `Authorization` header. * **Invalid Payload:** Ensure your JSON/NDJSON is well-formed and required fields are present. * **Job Failures:** Use the job status endpoint to inspect error messages for failed records or processing issues. * **Stuck Jobs:** If a job's processing time is taking much longer than expected, contact [support@userpilot.com](mailto:support@userpilot.com) for help. # Delete Users and Companies Source: https://docs.userpilot.com/api-references/delete/overview Delete users and companies from Userpilot to comply with data privacy regulations. Userpilot supports data deletion to comply with the [right to be forgotten](https://gdpr.eu/article-17-right-to-be-forgotten/) under [GDPR](https://gdpr-info.eu/). Under this right, a user can request to delete all their data. Userpilot supports this right for all users, not just those in Europe. You can use the Deletion APIs to schedule a job to delete user or company data. *** ## Authorization Userpilot API uses API tokens to authenticate requests. You can view your API key in the Environment Page. **Authentication Method:** Include your API key in the `Authorization` header: ```http theme={null} -H 'Authorization: Token {{API_KEY}}' ``` All API requests must be made over HTTPS. Your API key carries many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas. *** ## Version You must send the API version in the headers: ```http theme={null} -H 'X-API-Version: 2020-09-22' ``` *** ## Endpoints For most users, the HTTP API endpoint URL is `https://analytex.userpilot.io` as the examples show. If you are on Enterprise or EU hosting, refer to the Environment Page in the application to retrieve your dedicated endpoint. *** ### 1. Delete Users **Endpoint:** ```http theme={null} DELETE https://analytex.userpilot.io/v1/users ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. **Headers:** | Header | Value | Required | | --------------- | ---------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `X-API-Version` | `2020-09-22` | Yes | **Request Body:** | Field | Type | Required | Description | | ------- | ----- | -------- | ------------------------------ | | `users` | array | Yes | List of user IDs to be deleted | **Example Request:** ```bash theme={null} curl -X DELETE https://analytex.userpilot.io/v1/users \ -H 'Content-Type: application/json' \ -H 'Authorization: Token ' \ -H 'X-API-Version: 2020-09-22' \ -d '{"users": ["user_id", "user_id2"]}' ``` *** ### 2. Delete Companies **Endpoint:** ```http theme={null} DELETE https://analytex.userpilot.io/v1/companies ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. **Headers:** | Header | Value | Required | | --------------- | ---------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `X-API-Version` | `2020-09-22` | Yes | **Request Body:** | Field | Type | Required | Description | | ----------- | ----- | -------- | --------------------------------- | | `companies` | array | Yes | List of company IDs to be deleted | **Example Request:** ```bash theme={null} curl -X DELETE https://analytex.userpilot.io/v1/companies \ -H 'Content-Type: application/json' \ -H 'Authorization: Token ' \ -H 'X-API-Version: 2020-09-22' \ -d '{"companies": ["company_id", "company_id2"]}' ``` *** ## Response A successful request will schedule your delete job and return a `202 Accepted` status with a message indicating how many users or companies have been scheduled for deletion. **Example Response:** ```json theme={null} { "message": "2 users have been scheduled for deletion" } ``` Deletions are scheduled to be executed every 24 hours (daily at 2:00 AM UTC). *** ## Rate Limits The Delete API has the following rate limit: * **Delete Operations**: **1 request every 2 seconds** for delete operations If you exceed the rate limit, the API will return a `429 Too Many Requests` error. **Best Practice:** Implement exponential backoff and retry logic to handle rate limit errors gracefully. *** ## FAQs Yes, `DELETE /v1/users` and `DELETE /v1/companies` are separate endpoints with separate ID arrays (`users` vs `companies`); deleting a user does not automatically delete the company they belonged to, or vice versa. [For any questions or concerns, please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Bulk Companies Update Source: https://docs.userpilot.com/api-references/endpoints/bulk/companies POST /v1/companies/bulk_identify Create or update multiple company profiles in a single API request using the bulk_identify endpoint. # Bulk Users Update Source: https://docs.userpilot.com/api-references/endpoints/bulk/users POST /v1/users/bulk_identify Create or update multiple user profiles in a single API request using the bulk_identify endpoint. # Export Job Source: https://docs.userpilot.com/api-references/endpoints/export/export-job POST /api/v1/analytics/exports Create a bulk export job to extract user, company, or event data with customizable date ranges and filters. # Import Job Source: https://docs.userpilot.com/api-references/endpoints/import/import-job POST /v1/imports Create a bulk import job to upload historical user, company, or event data from external systems. # View Job ID Source: https://docs.userpilot.com/api-references/endpoints/jobs/job-id GET /v1/background_jobs/{{job_id}} Get the status, progress, and results of a specific background job by its unique identifier. # List Jobs Source: https://docs.userpilot.com/api-references/endpoints/jobs/list GET /v1/background_jobs Retrieve a paginated list of background jobs including imports and exports with their status and metadata. # Banners Source: https://docs.userpilot.com/api-references/endpoints/lookups/banners GET /api/v1/analytics/exports/lookups/banners List all banners with their IDs and names for filtering analytics exports by specific announcement campaigns. # Checklists Source: https://docs.userpilot.com/api-references/endpoints/lookups/checklists GET /api/v1/analytics/exports/lookups/checklists List all checklists with their IDs and names for filtering analytics exports by onboarding progress data. # Company Properties Source: https://docs.userpilot.com/api-references/endpoints/lookups/company-properties GET /api/v1/analytics/exports/lookups/company_properties Retrieve all available company properties and their metadata for use in analytics exports and B2B segmentation. # Embeds Source: https://docs.userpilot.com/api-references/endpoints/lookups/embeds GET /api/v1/analytics/exports/lookups/embeds List all embeds (banners and cards) with their IDs and names for filtering analytics exports by specific embed campaigns. # Features & Events Source: https://docs.userpilot.com/api-references/endpoints/lookups/features-events GET /api/v1/analytics/exports/lookups/features_events List all tracked features and events with their IDs for filtering analytics exports by specific user actions. # Flows Source: https://docs.userpilot.com/api-references/endpoints/lookups/flows GET /api/v1/analytics/exports/lookups/flows List all flows with their IDs and names for filtering analytics exports by specific in-app experiences. # Resource Center Modules Source: https://docs.userpilot.com/api-references/endpoints/lookups/resource-center-modules GET /api/v1/analytics/exports/lookups/resource_center_modules List all Resource Center modules with their IDs for filtering analytics exports by help content engagement. # Segments Source: https://docs.userpilot.com/api-references/endpoints/lookups/segments GET /api/v1/analytics/exports/lookups/segments List all user segments with their IDs and names for filtering analytics exports by specific audience groups. # Spotlights Source: https://docs.userpilot.com/api-references/endpoints/lookups/spotlights GET /api/v1/analytics/exports/lookups/spotlights List all spotlights with their IDs and names for filtering analytics exports by tooltip and hotspot interactions. # Surveys Source: https://docs.userpilot.com/api-references/endpoints/lookups/surveys GET /api/v1/analytics/exports/lookups/surveys List all surveys with their IDs and names for filtering analytics exports by feedback collection campaigns. # User Properties Source: https://docs.userpilot.com/api-references/endpoints/lookups/user-properties GET /api/v1/analytics/exports/lookups/user_properties Retrieve all available user properties and their metadata for use in analytics exports and segmentation filters. # Identify Company Source: https://docs.userpilot.com/api-references/endpoints/realtime/identify-company POST /v1/companies/identify Create or update a company profile with properties like name, industry, and size via HTTP POST request. # Identify User Source: https://docs.userpilot.com/api-references/endpoints/realtime/identify-user POST /v1/identify Create or update a user profile with properties like name, email, and custom attributes via HTTP POST request. # Track Event Source: https://docs.userpilot.com/api-references/endpoints/realtime/track-event POST /v1/track Record a custom event for a user with optional metadata properties via HTTP POST request. # Environment Source: https://docs.userpilot.com/api-references/environment Userpilot APIs are available at different endpoint URLs depending on your hosting environment, with dedicated endpoints for Enterprise and EU customers. Userpilot APIs are available at different endpoint URLs depending on your hosting environment. Most users will use the default endpoint, but Enterprise and EU customers may have dedicated endpoints. ### Default Endpoint For most users, the API endpoint is: ```bash theme={null} https://analytex.userpilot.io ``` ### Enterprise & EU Hosting If you are on Enterprise or EU hosting, your API endpoint may be different. You can find your dedicated endpoint on the **Environment Page** in your Userpilot application. Always check your Environment Page for the correct endpoint if you are unsure. ### How to Find Your Environment 1. Log in to your Userpilot dashboard. 2. Navigate to the **[Environment Page](https://run.userpilot.io/environment)**. 3. Copy the endpoint URL provided for your environment. Using the correct endpoint is essential for successful API requests, especially if your data residency or compliance requirements dictate a specific region. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Event Schema Source: https://docs.userpilot.com/api-references/export/event-schema A complete reference to the structure, attributes, and relationships of events exported from Userpilot. Welcome to the Userpilot Event Data Schema documentation! This guide provides a comprehensive overview of the structure, attributes, and relationships of events exported from Userpilot. It is designed to help data analysts, engineers, and business users understand and utilize Userpilot event data for integration, analytics, and reporting purposes. Below, you'll find detailed explanations of each event field, example payloads, and best practices for working with Userpilot data in your own systems. *** ## Event Structure | **Attribute** | **Type** | **Description** | | ------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `app_token` | String | Unique identifier for the app. | | `event_type` | String | Type of event (`identify_user`, `identify_company`, `interaction`, `track`, `track_feature`, `page_view`, `session_start`). | | `event_name` | String | Name of the event. For some types, this is empty or contains details (see below). | | `user_id` | String | Unique identifier for the user (for `identify_user` events). | | `company_id` | String | Unique identifier for the company (for `identify_company` events). | | `source` | String | Source of the event (`web-client`, `backend-http`, `backend-hubspot`, `backend-salesforce`, `backend-segment`). | | `inserted_at` | DateTime (UTC) | Timestamp of the event (microsecond precision). | | `internal_event_id` | String | Unique identifier calculated using xxHash64 of the composite key (`app_token`, `event_type`, `event_name`, `user_id`, `company_id`, `inserted_at`). | | `hostname` | String | Hostname where the event took place. | | `pathname` | String | Page path where the event occurred. | | `screen_width` | Integer | User's screen width (px). | | `screen_height` | Integer | User's screen height (px). | | `device_type` | String | Device type (`desktop`, `mobile`, etc.). | | `user_agent` | String | Browser's user agent string. | | `operating_system` | String | User's operating system. | | `browser` | String | Browser name (e.g., `Chrome`). | | `browser_language` | String | Browser language setting. | | `session` | String | Session number (for SDK events, auto-updated for `web-client`). | | `country_code` | String | 2-letter country code. | | `metadata` | Object | The attributes object varies depending on the `event_type` (see below). | ### Internal Event ID The `internal_event_id` is a unique identifier for each event, calculated using the xxHash64 algorithm on a composite key consisting of the following fields: * `app_token` * `event_type` * `event_name` * `user_id` * `company_id` * `inserted_at` This identifier provides a deterministic way to uniquely identify events based on their core attributes, which is useful for deduplication and event tracking across systems. ### Event Name & Type The `event_name` field tracks the name of the event and varies depending on the `event_type`: * **`For identify_user, identify_company, session_start, and page_view events:`** This field will be empty. * **`For track events:`** The value will represent the name of the event being passed programmatically or through the button-tracking feature. * **`For track_feature events:`** The value will contain the `id` of the tracked feature tag. * **`For interaction events:`** * The format is `{entity_type}:{entity_id}:{entity_interaction_status}` * Example: `checklist:2:SEEN`, `experience:448:DISMISSED`, `resource_center:1:ENGAGED`, `experiment:9:SEEN`. When a flow is part of an experiment, both `experiment:*` and `experience:*` events are generated to track experiment participation and flow interaction respectively. *** ### Source The `source` field indicates where the event was captured. The default value is `web-client`, but it can vary depending on the source of the event: * **web-client**: Captured through the web SDK. * **backend-http**: Captured via HTTP endpoints. * **backend-hubspot**: Captured through the HubSpot integration. * **backend-salesforce**: Captured through the Salesforce integration. * **backend-segment**: Captured through SegmentIO integration. *** ### Attributes Schema The `metadata` field varies depending on the event type: * **`For identify_user, identify_company, and track events:`** This field will contain custom attributes passed during the event tracking. * **`For page_view, session_start and track_feature events:`** This field will be an empty object. * **`For interaction events:`** Attributes vary based on the engagement entity type and provide specific interaction details (see below). *** ## Interaction Attributes Below are common interaction events and the relevant attributes associated with each. ### Surveys (`survey_module` events) | **Attribute** | **Type** | **Description** | | ----------------- | -------- | --------------------------------------------------------------------------------- | | `feedback` | String | Feedback provided by the user, often a unique identifier or actual feedback text. | | `interaction_id` | String | Unique ID of the survey module (e.g., `survey_module_49`). | | `is_dismissed` | String | Indicates whether the survey was dismissed by the user (`1` for yes, `0` for no). | | `parent_id` | String | The ID of the parent survey. | | `status` | String | Current status of the survey interaction (e.g., `COMPLETED`, `DISMISSED`). | | `survey_question` | String | The question presented to the user. | | `variant` | String | Survey type (e.g., `multiple_choice`, `open_text`). | **Example:** ```json theme={null} { "event_name": "survey_module:49:COMPLETED", "attributes": { "feedback": "318b72c9-b1ad-4bf6-854b-26d32ac9d281", "interaction_id": "survey_module_49", "is_dismissed": "0", "parent_id": "survey_13", "status": "COMPLETED", "survey_question": "", "variant": "multiple_choice" } } ``` ### Checklists (`checklist` and `checklist_task` events) | **Attribute** | **Type** | **Description** | | ---------------- | -------- | -------------------------------------------------------------------------------------------- | | `interaction_id` | String | Unique ID of the checklist or checklist task (e.g., `checklist_10`). | | `is_dismissed` | String | Indicates whether the checklist or task was dismissed by the user (`1` for yes, `0` for no). | | `parent_id` | String | The ID of the parent checklist, if applicable. | | `status` | String | Status of the checklist interaction (e.g., `SEEN`, `ENGAGED`). | **Example:** ```json theme={null} { "event_name": "checklist:10:SEEN", "attributes": { "interaction_id": "checklist_10", "is_dismissed": "", "parent_id": "", "status": "SEEN" } } ``` ### Resource Center and Articles (`resource_center`, `resource_center_article` events) | **Attribute** | **Type** | **Description** | | ---------------- | -------- | -------------------------------------------------------------------------------------------------- | | `article_title` | String | Title of the article the user engaged with. | | `article_url` | String | URL of the article. | | `interaction_id` | String | Unique ID for the resource center interaction or article (e.g., `resource_center_article_6FAA69`). | | `is_dismissed` | String | Indicates if the resource center or article interaction was dismissed. | | `parent_id` | String | The ID of the parent resource center entity (if applicable). | | `status` | String | Status of the interaction (e.g., `ENGAGED`). | **Example:** ```json theme={null} { "event_name": "resource_center_article:6FAA69EBAFEEDF5E641ACF6D52847FC98AC44437591FC39D8BE67BDCF4570023:ENGAGED", "attributes": { "article_title": "How to Delete a Flow - Userpilot Knowledge Base", "article_url": "https://docs.userpilot.com/", "interaction_id": "resource_center_article_6FAA69EBAFEEDF5E641ACF6D52847FC98AC44437591FC39D8BE67BDCF4570023", "is_dismissed": "0", "parent_id": "resource_center_1", "status": "ENGAGED" } } ``` ### NPS Events | **Attribute** | **Type** | **Description** | | -------------------- | -------- | ------------------------------------------------------------------------------ | | `feedback` | String | Feedback provided by the user (can be text or a unique ID). | | `follow_up_question` | String | A follow-up question posed to the user after providing the NPS score. | | `interaction_id` | String | Unique ID for the NPS interaction (e.g., `nps_1`). | | `score` | String | NPS score given by the user (typically between 0 and 10). | | `status` | String | Status of the NPS interaction (e.g., `SUBMITTED_FEEDBACK`, `SUBMITTED_SCORE`). | | `survey_question` | String | The specific NPS question posed to the user. | | `submission_id` | String | Unique identifier for the NPS submission. | **Example:** ```json theme={null} { "event_name": "nps:1:SUBMITTED_FEEDBACK", "attributes": { "feedback": "Great tool, highly recommended!", "follow_up_question": "Is there anything else we can improve?", "interaction_id": "nps_1", "score": "9", "status": "COMPLETED", "submission_id": "2024-05-02", "survey_question": "How likely is it that you would recommend us to a friend or colleague?" } } ``` ### Flow and Flow Steps (`experience`, `experience_step` events) | **Attribute** | **Type** | **Description** | | ----------------- | -------- | ------------------------------------------------------------------------ | | `interaction_id` | String | Unique ID of the experience or experience step (e.g., `experience_493`). | | `is_dismissed` | String | Indicates if the experience was dismissed (`1` for yes, `0` for no). | | `status` | String | The status of the experience (e.g., `COMPLETED`, `DISMISSED`). | | `total_dismissed` | String | The total number of times the experience was dismissed by the user. | **Example:** ```json theme={null} { "event_name": "experience:493:DISMISSED", "attributes": { "interaction_id": "experience_493", "is_dismissed": "1", "status": "DISMISSED", "total_dismissed": "1" } } ``` **Flows in Experiments:** When a flow is part of a test experiment, the system generates BOTH `experiment:*` and `experience:*` events: * `experiment:*` events track experiment participation and variant assignment * `experience:*` events track flow interaction ### Experiments (`experiment` events) When flows are used testing experiments, Userpilot tracks experiment participation through dedicated experiment events. These events capture which variant (test group) a user was assigned to. | **Attribute** | **Type** | **Description** | | ------------------ | -------- | ------------------------------------------------------------------------------------------------- | | `interaction_id` | String | Unique ID of the experiment (e.g., `experiment_9`). | | `is_dismissed` | String | Indicates whether the experiment interaction was dismissed by the user (`1` for yes, `0` for no). | | `never_show_again` | String | Indicates if the user chose to never see this again (`1` for yes, `0` for no). | | `status` | String | Current status of the experiment interaction (e.g., `SEEN`, `COMPLETED`, `DISMISSED`). | | `total_dismissed` | String | The total number of times the experiment was dismissed by the user. | | `variant` | String | The experiment group the user was assigned to. Contains the variant name (A, B, or C). | **Variant Values:** The `variant` attribute indicates which test group the user was assigned to. Possible values are "A", "B", or "C" depending on the experiment type (Controlled A/B Test, Head-to-Head A/B Test, or Controlled Multivariate Test). For more details on experiment types and how variants are assigned, see the [Experiments documentation](https://docs.userpilot.com/in-app-engagement/flows/use-cases/AB-testing). **Example:** ```json theme={null} { "event_name": "experiment:9:SEEN", "attributes": { "interaction_id": "experiment_9", "is_dismissed": "0", "never_show_again": "0", "status": "SEEN", "total_dismissed": "0", "variant": "B" } } ``` ### Workflows Workflow-related events are exported as `interaction` events, so they're included in your exported data automatically. Two types are captured: * **Workflow-level events** — track the overall workflow, e.g. `workflow:16:SEEN` and `workflow:16:COMPLETED`. * **Workflow node events** — track individual steps within a workflow, e.g. `experience_step:vagqc:SEEN` and `experience_step:vagqc:COMPLETED`. The workflow node events have the following meanings: * `SEEN` indicates that the user has completed the previous node and is ready to engage with the next node. * `COMPLETED` indicates that the user has completed the current node, either by interacting with it or because a configured delay for that node has elapsed. Additionally, content that is part of a workflow (for example, Flows or Surveys) follows the normal content interaction model. These events are exported the same way as if the content were used outside of a workflow. **Example:** ```json theme={null} { "event_name": "workflow:16:SEEN", "attributes": { "interaction_id": "workflow_16", "is_dismissed": "0", "never_show_again": "0", "status": "SEEN", "total_completed": "0", "total_dismissed": "0", "total_engaged": "0", "total_seen": "0" } } ``` ```json theme={null} { "event_name": "experience_step:vagqc:SEEN", "attributes": { "interaction_id": "experience_step_vagqc", "is_dismissed": "0", "never_show_again": "0", "parent_id": "experience_67", "status": "SEEN", "total_completed": "0", "total_dismissed": "0", "total_engaged": "0", "total_seen": "0" } } ``` *** ## Key Data Entities & Relationships * **Users:** Identified by `user_id`, with `metadata` (traits like `email`, `signup_at`, `plan_type`). * **Companies:** (B2B) Identified by `company_id`, with properties (e.g., `company_name`, `industry`). * **Events:** Actions or occurrences, each as a JSON line. * **Sessions:** Grouped events within a continuous user activity period, identified by `session`. ### Relationships * A **User** can perform many **Events**. * Multiple **Events** can occur within a single **Session**. * A **User** may belong to one **Company**. *** ## FAQs No, it depends on `event_type`. For `identify_user`, `identify_company`, and `track` events it holds custom attributes you passed in. For `page_view`, `session_start`, and `track_feature` events it's empty. For `interaction` events it holds engagement-specific details (survey, checklist, NPS, flow, etc.) When a flow is part of an A/B test, Userpilot emits both an `experiment:*` event (participation/variant assignment) and an `experience:*` event (the actual flow interaction) for the same user action, so you'll see two rows, not a duplicate. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Data Lookups Source: https://docs.userpilot.com/api-references/export/lookups The Lookups APIs allow you to retrieve metadata about various entities in your Userpilot account, such as user properties, company properties, features,. The Lookups APIs allow you to retrieve metadata about various entities in your Userpilot account, such as user properties, company properties, features, events, and more. These endpoints help you understand the structure and available fields in your exported data. *** ## User & Company Endpoints for retrieving user and company metadata, as well as segments. | Endpoint | Description | | ------------------------------------------------------ | ------------------------ | | `/api/v1/analytics/exports/lookups/user_properties` | Get user properties | | `/api/v1/analytics/exports/lookups/company_properties` | Get company properties | | `/api/v1/analytics/exports/lookups/segments` | Get segments (paginated) | *** ## Features & Events Endpoints for retrieving features, events, and event property metadata. | Endpoint | Description | | ----------------------------------------------------- | ------------------------------------------------------- | | `/api/v1/analytics/exports/lookups/features_events` | Get features & events | | `/api/v1/analytics/exports/lookups/events_properties` | Get trackable events' properties/attributes (paginated) | *** ## Experiences & UI Endpoints for retrieving experiences, UI elements, surveys, resource center modules, and checklists. | Endpoint | Description | | ----------------------------------------------------------- | ------------------------------ | | `/api/v1/analytics/exports/lookups/flows` | Get flows (experiences) | | `/api/v1/analytics/exports/lookups/banners` | Get banners | | `/api/v1/analytics/exports/lookups/embeds` | Get embeds (banners and cards) | | `/api/v1/analytics/exports/lookups/spotlights` | Get spotlights | | `/api/v1/analytics/exports/lookups/surveys` | Get surveys (with modules) | | `/api/v1/analytics/exports/lookups/resource_center_modules` | Get resource center modules | | `/api/v1/analytics/exports/lookups/checklists` | Get checklists (with tasks) | *** ## How to Use All endpoints require authentication via your API key: ```bash theme={null} curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/lookups/user_properties' \ --header 'Authorization: Token {{API_KEY}}' ``` ### Example Response ```json theme={null} [ { "display_name": "URL", "key": "url", "data_type": "string", ... } ] ``` ## Pagination Some endpoints (such as `events_properties` and `segments`) are paginated. The response includes a `cursor` object in the `metadata` section: * `after`: Cursor for fetching the next set of results. * `before`: Cursor for fetching previous results (if available). * `limit`: Number of results per request. * `total_count`: Total number of available records. ### Example Paginated Request ```bash theme={null} curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/lookups/events_properties?after_cursor=...' \ --header 'Authorization: Token {{API_KEY}}' ``` ### Example Paginated Response ```json theme={null} { "data": [ ... ], "metadata": { "cursor": { "after": "...", "before": null }, "limit": 50, "total_count": 53 } } ``` * Always check if `cursor.after` exists in the response before making the next request. * If `cursor.after` is `null`, you have reached the last page of data. * To modify the number of results per request, use the `limit` parameter in your query string (default is 50). # Bulk Data Export API Source: https://docs.userpilot.com/api-references/export/overview The Bulk Data Export API lets you asynchronously export raw event, user, and company data from Userpilot — filtered by date range, user, company, event type, or segment — as JSON or CSV files. This feature is available on the Enterprise plan only or as an add-on to the Growth plan. If interested in adding this feature please contact [support@userpilot.com](mailto:support@userpilot.com). The **Userpilot Export Analytics Data API** allows you to export analytics data from Userpilot, enabling you to analyze user behavior, engagement, and more. You can filter the data by date range, user, company, event type, and additional parameters. The API supports exporting data in JSON or CSV formats. *** ## Authorization Userpilot API uses an API key to authenticate requests. You can find your API key on the [Environment Page](https://run.userpilot.io/environment). **Authentication Method:** Include your API key in the `Authorization` header: ```http theme={null} Authorization: Token {{API_KEY}} ``` All API requests must be made over HTTPS. Your API key carries many privileges, so be sure to keep it secure! Do not share your secret API keys in publicly accessible areas. *** ## Rate Limits The Export API enforces rate limiting to ensure reliable data export operations and maintain system performance for all users. These limits help balance resource usage while enabling comprehensive analytics data retrieval. ### Rate Limit Details * **Job Limitation**: **One export job at a time** per application token ### Error Responses The API returns specific error codes when limits are exceeded: * **`409 Conflict`**: Returned when attempting to create a new export job while another is in progress ### Best Practices **Verify Job Status**: Always check for existing export jobs before initiating a new one to avoid conflicts. **Handle Conflicts Gracefully**: When encountering a 409 Conflict error, wait for the current job to complete before retrying. **Track Export Progress**: Use job status endpoints to monitor export completion and download files promptly. **Optimize Export Requests**: Use specific date ranges and filters to reduce data volume and improve performance. *** ## Data Restrictions * **Job Status Availability:** Once an export job is created, the job status and related information will be available for **3 days**. After this period, the job status will no longer be accessible via the API. * **File Download Expiry:** The URLs generated to download the exported data files will expire after **2 days**. Ensure you download the files within this time frame, as the links will no longer be valid afterward. Providing a valid email address in the request is recommended. You'll receive a notification with download links when the export is ready, eliminating the need to manually check job status. *** For the schema of exported events and data, see the [Event Schema](./event-schema) page. For details on available lookup endpoints and how to use them, see the [Data Lookups](./lookups) page. ## Data Schema Reference The data exported via the Userpilot Export Analytics Data API follows the Userpilot [Event Data Schema](./event-schema). This schema defines the structure, attributes, and relationships of all events, users, and companies included in your export. **Key points:** * Each exported event will include fields such as `app_token`, `event_type`, `event_name`, `user_id`, `company_id`, `source`, `inserted_at`, and more. * Auto-captured attributes (e.g., `hostname`, `device_type`, `browser`, etc.) and custom attributes (in the metadata object) are included as described in the schema. * The schema covers all event types (`identify_user`, `identify_company`, `track`, `track_feature`, `page_view`, `interaction`, `session_start`, etc.) and their specific attribute structures. Your exported data may include new or additional fields as the schema evolves. Please ensure your data processing pipelines can handle unexpected fields gracefully. *** ## API Endpoints ### 1. Trigger an Export Job #### Endpoint ```http theme={null} POST https://appex.userpilot.io/api/v1/analytics/exports ``` #### Description Creates an export job to extract analytics data based on the specified parameters. #### Parameters | Parameter | Type | Required | Description | Example | | ------------ | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | | `from` | `string` | Yes | Start date of the export in `YYYY-MM-DD` format. | "2024-05-02" | | `to` | `string` | Yes | End date of the export in `YYYY-MM-DD` format. | "2024-09-30" | | `emails` | `string[]` | No | List of email addresses to receive the exported data. If omitted, no email is sent. | \["[example@work.com](mailto:example@work.com)"] | | `event_type` | `string[]` | No | List of event types to filter. Defaults: see below. | \["track", "page\_view"] | | `user_id` | `string[]` | No | Specific user IDs to filter. If omitted, all users are included. | \["123456"] | | `company_id` | `string[]` | No | Specific company IDs to filter. If omitted, all companies are included. | \["13162551529"] | | `segment_id` | `string` | No | Filter data based on a specific segment. | "987654" | | `format` | `string` | No | Format of the exported data. Options: `json` (default) or `csv`. | "csv" | | `exclusions` | `boolean` | No | Exclude users/companies set in the web app - see [Exclude Users and Companies](../../configure/exclude-lists/exclude-user). Default: `false`. | true | **Default values:** * `event_type` defaults to `["identify_user", "identify_company", "page_view", "track", "track_feature", "interaction", "session_start"]` if not provided. * `user_id` and `company_id` default to empty arrays (`[]`), meaning all users or companies are included by default. * The default export `format` is `json`. #### Example Request ```bash theme={null} curl --location 'https://appex.userpilot.io/api/v1/analytics/exports' \ --header 'Authorization: Token {{API_KEY}}' \ --header 'Content-Type: application/json' \ --data-raw '{ "from": "2024-05-02", "to": "2024-09-30", "emails": ["example@work.com"], "event_type": ["identify_user", "identify_company", "page_view", "track"], "user_id": ["user_1"], "company_id": ["comp_2"], "segment_id": "9", "format": "csv", "exclusions": true }' ``` ```json theme={null} { "environment_app_token": "NX-51f4acf7", "environment_name": "production", "job_id": "86f4dd75-00c8-40cd-ac6a-3dce8440be0c", "links": "/api/v1/analytics/exports/jobs/86f4dd75-00c8-40cd-ac6a-3dce8440be0c", "start_time": "2024-10-06T10:44:50.999504" } ``` ```json theme={null} { "errors": [ { "details": "There is already an export job in progress, you can only have one export job in progress at a time.", "error": "Conflict", "error_code": "409", "message": "The request could not be completed due to a conflict with the current state of the target resource." } ] } ``` ```json theme={null} { "errors": [ { "details": "Your current plan for application NX-d7ce194a does not support the feature you are trying to access.", "error": "Unauthorized", "error_code": "401", "message": "You are not authorized to perform the requested action." } ] } ``` *** ### 2. Show Jobs #### Endpoint ```http theme={null} GET https://appex.userpilot.io/api/v1/analytics/exports/jobs ``` #### Description Retrieves a list of all export jobs triggered by your API token. #### Example Request ```bash theme={null} curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/jobs' \ --header 'Authorization: Token {{API_KEY}}' ``` ```json theme={null} [ { "elapsed_time": "44 seconds", "elapsed_time_seconds": 44, "end_time": "2024-09-22T11:20:58.006463Z", "job_id": "af257e48-c145-40aa-996c-dad64839acb1", "progress": "5 out of 5 partitions", "start_time": "2024-09-22T11:20:14.731634", "status": "completed" } ] ``` *** ### 3. Show Job by Job ID #### Endpoint ```http theme={null} GET https://appex.userpilot.io/api/v1/analytics/exports/jobs/{job_id} ``` #### Description Retrieves detailed information about a specific export job identified by its `job_id`. #### Path Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------- | | job\_id | String | Yes | The unique identifier of the export job | #### Example Request ```bash theme={null} curl --location 'https://appex.userpilot.io/api/v1/analytics/exports/jobs/{job_id}' \ --header 'Authorization: Token {{API_KEY}}' ``` ```json theme={null} { "app_token": "", "completed_chunks": ["2024-05-01", "2024-06-01"], "current_chunk": "2024-09-01", "end_time": "2024-09-22T13:18:11.558646Z", "job_id": "664314e1-ee60-48eb-a36a-5f38f4c524f1", "presigned_urls": [ {"filename": "2024-07-29.json.gz", "url": "https://..."} ], "progress": "2 out of 5 partitions", "start_time": "2024-09-22T13:17:26.864860Z", "status": "completed", "all_chunks": ["2024-05-01", "2024-06-01"], "type": "export" } ``` ```json theme={null} { "errors": [ { "details": null, "error": "Resource not found", "error_code": "404", "message": "Failed to retrieve job with id ...: job not found" } ] } ``` Ensure you retrieve job details within the **3-day** availability window to effectively monitor ongoing jobs. - Download links for exported data will expire after **2 days**, so make sure to download your data promptly. *** ## Understanding File Names and Date Ranges The Export API partitions data into files by weeks to avoid oversized files. It's important to understand how file names relate to the data they contain. ### File Naming Convention * **Weekly Partitioning:** Each file represents a weekly partition of data * **File Name Format:** Each weekly file's name is the date representing the **start of the week (Monday)** in `YYYY-MM-DD` format * **Data Filtering:** The file name does **not** indicate that the file contains all data from that entire week. The data within each file is still restricted to your requested date range filter ### Example Scenario If you request data for the date range **November 30, 2025 → December 2, 2025**, you may receive files with names that appear outside this range: * **File: `2025-11-24.json.gz`** * November 30, 2025 belongs to the week starting November 24, 2025 (Monday) * This file contains data for **November 30, 2025 only** (matching your filter) * The file name reflects the week start date, not the actual data range * **File: `2025-12-01.json.gz`** * December 2, 2025 belongs to the week starting December 1, 2025 (Monday) * This file contains data for **December 1, 2025 and December 2, 2025** (matching your filter) * Again, the file name reflects the week start date ### Key Points * File names represent the **week start date (Monday)** for organizational purposes * The actual data in each file is **filtered to your requested date range** * You may see file names with dates outside your requested range, but the data inside will only include events within your specified `from` and `to` dates * This partitioning approach helps manage file sizes while maintaining efficient data retrieval [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # User & Company Accumulative Properties Best Practices Source: https://docs.userpilot.com/api-references/import/best-practices When importing historical data, it is crucial to ensure the consistency and accuracy of user and company data in Userpilot. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. When importing historical data, it is crucial to ensure the consistency and accuracy of user and company data in Userpilot. Follow these guidelines to avoid potential issues in reporting or data analysis: 1. **Sequential Property Building:** Begin the import process with a subset of properties and gradually build up the profile until all properties are included. This ensures a smooth transition and avoids overwriting or omitting critical data. 2. **Consistent Property Lists:** Avoid submitting inconsistent sets of properties for the same user or company in sequential `identify_user` or `identify_company` events. Always include the full list of properties for each `identify` event. Populate known attributes and leave the remaining attributes as `null` or empty values. 3. **Avoid Overwriting with Partial Data:** Submitting partial data in subsequent `identify` calls can cause critical attributes to be overwritten with null values, leading to inaccurate reporting and inconsistent profiles. **Example Approach** | Attribute | First identify | Second Identify | Third Identify | | ---------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | | name | "John Doe" | "John Doe" | "John Doe" | | email | "[john@example.com](mailto:john@example.com)" | "[john@example.com](mailto:john@example.com)" | "[john@example.com](mailto:john@example.com)" | | location | null | "Dublin" | "Dublin" | | job\_title | null | null | "Architect" | * **Best Practice:** Gradually build up the user profile by adding properties in each step until the full profile is complete. This ensures the merge process maintains data consistency. * **Incorrect Practice:** Reducing the set of properties in subsequent calls. This may result in missing or overwritten data. **Why This Matters** Userpilot's data pipeline relies on the accuracy and completeness of historical imports. The merge tree logic aggregates data based on the most recent updates. Inconsistent or partial imports can disrupt this process, leading to incorrect data in reporting tools. By adhering to these best practices, you ensure reliable and comprehensive user and company profiles in Userpilot, maintaining the integrity of your analytics and insights. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Event Schema Source: https://docs.userpilot.com/api-references/import/event-schema This page documents the event types and required fields for importing data into Userpilot using the Import API. This page documents the event types and required fields for importing data into Userpilot using the Import API. Each record in your import file must conform to one of the following event schemas. Supported event types are `identify_user`, `identify_company`, `page_view`, and `track`. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. *** ## 1. Identify User Identifies or updates the attributes of a user. | Field | Type | Required | Description | | ------------ | ------------ | -------- | ---------------------------------------- | | event\_type | String | Yes | Must be `identify_user` | | user\_id | String | Yes | Unique identifier for the user. | | metadata | Object | Yes | Key-value pairs of user attributes. | | source | String | Yes | Indicates the origin of the event data. | | inserted\_at | String (ISO) | Yes | Timestamp of when the data was recorded. | **Example Payload:** ```json theme={null} { "event_type": "identify_user", "event_name": "", "source": "web-client", "user_id": "user_id", "company_id": "company_id", "hostname": "example.com", "pathname": "/users/list", "country_code": "UK", "screen_width": 859, "screen_height": 746, "operating_system": "Mac", "browser": "Chrome", "browser_language": "en-US", "user_agent": "Chrome - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", "device_type": "Desktop", "inserted_at": "2024-07-28 08:55:35.874555", "metadata": { "name": "John Doe", "email": "john.doe@example.com", "job_title": "Solution Architect", "department": "Engineering", "squad": "CORE Squad", "branch_location": "Dublin, Ireland", "sign_up_date": "2023-11-01 14:35:36.173103", "total_logins": 28, "days_since_last_login": 7 } } ``` *** ## 2. Identify Company Identifies or updates the attributes of a company. | Field | Type | Required | Description | | ------------ | ------------ | -------- | ---------------------------------------- | | event\_type | String | Yes | Must be `identify_company` | | company\_id | String | Yes | Unique identifier for the company. | | source | String | Yes | Indicates the origin of the event data. | | metadata | Object | Yes | Key-value pairs of company attributes. | | inserted\_at | String (ISO) | Yes | Timestamp of when the data was recorded. | **Example Payload:** ```json theme={null} { "event_type": "identify_company", "source": "web-client", "company_id": "company_id", "inserted_at": "2024-07-28 08:55:35.874555", "metadata": { "name": "Acme Labs Inc.", "industry": "Software Solutions", "branches_count": 3, "Headquarter": "Dublin, Ireland" } } ``` *** ## 3. Page View Logs a page view by a user. | Field | Type | Required | Description | | ------------ | ------------ | -------- | ---------------------------------------- | | event\_type | String | Yes | Must be `page_view` | | user\_id | String | Yes | Unique identifier for the user | | hostname | String | Yes | Hostname of the page (e.g., example.com) | | pathname | String | Yes | Pathname of the page (e.g., /dashboard) | | source | String | Yes | Indicates the origin of the event data | | inserted\_at | String (ISO) | Yes | Timestamp of when the page view occurred | **Example Payload:** ```json theme={null} { "event_type": "page_view", "event_name": "", "source": "web-client", "user_id": "user_id_10", "company_id": "company_id_60", "hostname": "example.com", "pathname": "/dashboard/", "country_code": "US", "screen_width": 859, "screen_height": 746, "operating_system": "", "browser": "", "browser_language": "en-US", "user_agent": "Chrome - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", "device_type": "Desktop", "inserted_at": "2024-07-28 08:55:34.229738" } ``` *** ## 4. Track Event Tracks a custom user action or event. | Field | Type | Required | Description | | ------------ | ------------ | -------- | -------------------------------------------- | | event\_type | String | Yes | Must be `track` | | user\_id | String | Yes | Unique identifier for the user. | | event\_name | String | Yes | Name of the event (e.g., button\_click). | | source | String | Yes | Indicates the origin of the event data. | | metadata | Object | No | Key-value pairs of event-specific attributes | | inserted\_at | String (ISO) | Yes | Timestamp of when the event occurred. | **Example Payload:** ```json theme={null} { "event_type": "track", "event_name": "account_upgraded", "source": "web-client", "user_id": "user_id_123", "company_id": "", "hostname": "example.com", "pathname": "/subscription/plans", "country_code": "UK", "screen_width": 859, "screen_height": 746, "operating_system": "Mac", "browser": "Chrome", "browser_language": "en-US", "user_agent": "Chrome - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", "device_type": "Desktop", "inserted_at": "2024-12-01T08:55:43.220396", "metadata": { "old_plan": "Basic", "new_plan": "Premium", "upgrade_date": "2024-12-01T08:55:43.220396" } } ``` # Events Bulk Import Source: https://docs.userpilot.com/api-references/import/overview The Import API allows you to import historical user data from other platforms into Userpilot. With this API, you can migrate data related to user and company. The Import API allows you to import historical user data from other platforms into Userpilot. With this API, you can migrate data related to user and company identification, page views, and custom events. This enables a seamless transition and continuity of insights, providing a comprehensive view of user interactions. This feature is available on the Enterprise plan only or as an add-on to the Growth plan. If interested in adding this feature please contact [sales@userpilot.com](mailto:sales@userpilot.com) or your designated Customer Success Manager (CSM). ### Use Cases 1. **Data Migration:** Migrate historical data from other analytics platforms to Userpilot, ensuring no loss of valuable insights. 2. **Retrospective Analysis:** Analyze historical user behavior and feature engagement by importing past data on user actions, page views, and events. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. If you're migrating from another provider, complete the import process **before** installing the SDK. This ensures historical data is ready for analysis once Userpilot starts tracking live events. The Import API does not merge with a user's or company's existing (or live) property state, unlike real-time Identify calls. Each imported event is written as-is, so it's meant for one-time historical backfill, not ongoing updates to current property values. If a user is later identified in real time, that identify can overwrite properties you imported. To keep current property values in sync, use the [Bulk Update API](../bulk-updates/users) instead. *** ### Authorization See the [Authentication](../authentication) and [Environment](../environment) pages for details on API key usage and endpoint URLs. **Authentication Method:** Include your API key in the `Authorization` header: ```http theme={null} Authorization: Token {{API_KEY}} ``` All API requests must be made over HTTPS. Your API key carries many privileges, so be sure to keep it secure! Do not share your secret API keys in publicly accessible areas. *** ## Rate Limits The Import API implements rate limiting to maintain system stability and ensure fair resource allocation across all users. These limits help prevent system overload while allowing efficient data migration workflows. ### Rate Limit Details * **Job Limitation**: **One import job at a time** per application token * **File Size**: **Up to 1 GB** file size for import operations ### Error Responses * **`401 Unauthorized`**: Returned when the API token is missing, invalid, or isn't a write/admin token * **`409 Conflict`**: Returned when attempting to create a new import job while another is in progress * **`413 Payload Too Large`**: Returned when file size exceeds 1 GB ### Best Practices **Check Job Status First**: Always verify no existing import jobs are running before initiating a new one. **Implement Retry Logic**: When encountering a 409 Conflict error, wait for the current job to complete before retrying. **Monitor Job Progress**: Use the job status endpoints to track import progress and avoid conflicts. **Optimize File Sizes**: For very large datasets, consider splitting files to stay within the 1 GB limit. *** ## Endpoints For most users, the HTTP API endpoint URL is `https://analytex.userpilot.io`. If you are on Enterprise or EU hosting, refer to the [Environment](../environment) page in the application to retrieve your dedicated endpoint. ### 1. Request Data Import #### Endpoint ```http theme={null} POST {{ENDPOINT}}/v1/imports ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. #### Description Initiates a data import job. Accepts a file in **CSV** or **NDJSON** format containing historical data. #### Headers | Header | Value | Required | | --------------- | --------------------- | -------- | | `Content-Type` | `multipart/form-data` | Yes | | `Authorization` | `Token {{API_KEY}}` | Yes | #### Request Parameters | Parameter | Type | Required | Description | | --------- | ---- | -------- | ------------------------------------------------------------------------------------------------- | | file | File | Yes | The CSV or NDJSON file containing the data to be imported. See the event schema for more details. | #### Data Format The imported data should conform to a list of events. See the [Import API Event Schema](./event-schema) for details on supported event types and required fields. Required fields vary by `source`. For example, `source: web-client` events require `hostname` and `pathname` (or a `url` field in their place), plus `user_agent`. #### Example Import File ```json file.ndjson theme={null} {"event_type": "identify_user", "source": "backend-http-import", "user_id": "user_123", "inserted_at": "2024-07-28T08:55:35.874555", "metadata": { "name": "John Doe", "email": "john.doe@example.com", "location": "Dublin, Ireland" },"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"} {"event_type": "identify_company", "source": "backend-http-import","company_id": "company_123","inserted_at": "2024-07-28T08:55:35.874555","metadata": {"name": "Acme Labs Inc.","industry": "Software","size": "200-500","location": "San Francisco, CA"}} ``` ```csv file.csv theme={null} event_type,event_name,source,user_id,company_id,hostname,pathname,country_code,screen_width,screen_height,operating_system,browser,browser_language,user_agent,device_type,inserted_at,metadata identify_user,,web-client,User-7320-001,Company-607-001,campfire-example.userpilot.io,/profile/settings/,DE,1086,696,Mac,Edge,de-DE,Edge - Mozilla/5.0 (Mac) AppleWebKit/537.36,Mobile,2023-12-26 14:36:15.453703,"{""created_at"": ""1694172975"", ""name"": ""User-Alice"", ""prop_0"": ""value_743"", ""prop_1"": ""value_927""}" page_view,,web-client,User-9491-002,Company-973-002,campfire-example.userpilot.io,/home/,DE,832,809,iOS,Chrome,fr-FR,Chrome - Mozilla/5.0 (iOS) AppleWebKit/537.36,Mobile,2024-04-13 14:36:15.453788,"{}" track,created_project,web-client,User-6267-003,Company-584-003,campfire-example.userpilot.io,/profile/settings/,PS,1114,704,iOS,Safari,en-US,Safari - Mozilla/5.0 (iOS) AppleWebKit/537.36,Mobile,2024-05-05 14:36:15.453813,"{""created_at"": ""1730810175"", ""name"": ""User-Bob"", ""prop_0"": ""value_17""}" ``` **Uploading the File** ```bash theme={null} curl -X POST "{{ENDPOINT}}/v1/imports" \ -H "Authorization: Token {{API_KEY}}" \ -F "file=@/path/to/import_data.ndjson" ``` #### Response ```json theme={null} { "end_time": null, "file_size": 2234, "filename": "2024-10-28.ndjson", "job_id": "imports:jobs:NX-51f4acf7:f681073b-21ac-4276-9af5-c662dc05fb25", "links": "/v1/background_jobs/imports:jobs:NX-51f4acf7:f681073b-21ac-4276-9af5-c662dc05fb25", "start_time": "2024-11-28T10:34:11.376662", "status": "queued", "total_rows": 0, "type": "import" } ``` ```json theme={null} { "errors": [ { "details": null, "error": "Conflict", "error_code": "409", "message": "The request could not be completed due to a conflict with the current state of the target resource." } ] } ``` *** ### 2. Get All Import Job Statuses #### Endpoint ```http theme={null} GET {{ENDPOINT}}/v1/background_jobs ``` #### Description Fetches the status of all import jobs, allowing users to monitor the progress of multiple imports at once. #### Headers | Header | Value | Required | | --------------- | ------------------- | -------- | | `Authorization` | `Token {{API_KEY}}` | Yes | #### Example Request ```bash theme={null} curl -X GET "{{ENDPOINT}}/v1/background_jobs" \ -H "Authorization: Token {{API_KEY}}" ``` #### Response Returns a list of job objects, each with details such as job\_id, status, start\_time, end\_time, total\_rows, and reason\_for\_failure (if any). `status` can be `queued`, `pending_refresh` (data written, finalizing before completion), `completed`, or `failed`. ```json theme={null} [ { "elapsed_time": 6, "end_time": "2025-05-19T07:23:00.354452", "file_size": 757, "filename": "2024-10-28.ndjson", "job_id": "imports:jobs:NX-ac54070e:c6f91301-54c1-4df7-a077-b34715c38875", "links": "/v1/background_jobs/imports:jobs:NX-ac54070e:c6f91301-54c1-4df7-a077-b34715c38875", "start_time": "2025-05-19T07:22:54.409499", "status": "completed", "total_rows": 3, "type": "import" }, { "elapsed_time": 0, "end_time": "2025-05-19T07:09:49.883288", "file_size": 416, "filename": "2024-10-28.ndjson", "job_id": "imports:jobs:NX-ac54070e:1fd8f0d4-cd97-432f-86fe-3df9effc1912", "links": "/v1/background_jobs/imports:jobs:NX-ac54070e:1fd8f0d4-cd97-432f-86fe-3df9effc1912", "reason_for_failure": [ "Required field `user_id` not provided in the row: %{\"event_name\" => \"\", \"event_type\" => \"identify_user\", \"metadata\" => %{\"avg_resolution_time\" => \"2h\", \"customer_satisfaction\" => \"4.8\", \"escalation_count\" => \"1\", \"last_ticket_created\" => \"2025-02-01T10:20:30Z\", \"tickets_created\" => \"15\", \"tickets_pending\" => \"1\", \"tickets_resolved\" => \"14\"}}" ], "start_time": "2025-05-19T07:09:49.880967", "status": "failed", "total_rows": 0, "type": "import" } //... more jobs ] ``` *** ### 3. Get Job Status by ID #### Endpoint ```http theme={null} GET {{ENDPOINT}}/v1/background_jobs/:job_id ``` #### Description Fetches the status of a specific import job using its `job_id`, useful for tracking a single import job. #### Headers | Header | Value | Required | | --------------- | ------------------- | -------- | | `Authorization` | `Token {{API_KEY}}` | Yes | #### Path Parameters | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------- | | job\_id | String | Yes | The unique identifier of the import job | #### Example Request ```bash theme={null} curl -X GET "{{ENDPOINT}}/v1/background_jobs/:job_id" \ -H "Authorization: Token {{API_KEY}}" ``` #### Response Returns job details including job\_id, status, start\_time, end\_time, total\_rows, and reason\_for\_failure (if any). ```json theme={null} { "elapsed_time": 6, "end_time": "2025-05-19T07:23:00.354452", "file_size": 757, "filename": "2024-10-28.ndjson", "job_id": "imports:jobs:NX-ac54070e:c6f91301-54c1-4df7-a077-b34715c38875", "links": "/v1/background_jobs/imports:jobs:NX-ac54070e:c6f91301-54c1-4df7-a077-b34715c38875", "start_time": "2025-05-19T07:22:54.409499", "status": "completed", "total_rows": 3, "type": "import" } ``` *** For required validation rules for your import file, see the [Row Validation Rules](./row-validation) page. For best practices on importing user and company data, see [Best Practices for Accumulative Properties](./best-practices). [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Row Validation Rules Source: https://docs.userpilot.com/api-references/import/row-validation When preparing your HTTP import file, ensure that each row adheres to the following validation rules:. When preparing your HTTP import file, ensure that each row adheres to the following validation rules: 1. **Default Metadata:** If an event does not include the `metadata` key, it will be automatically assigned an empty object (`{}` ). 2. **Identify Company Event Rules:** For events with `event_type` set to `identify_company`, only the following keys are processed: `company_id`, `source`, `inserted_at`, `metadata`. Any additional keys will be ignored. 3. **URL Parsing:** If the entry has a `url` key present, the `hostname` and `pathname` fields will be overridden based on the parsed values of the `url`. 4. **Auto Properties:** Fields like `browser` and `operating_system` are automatically derived from the `user_agent` property if included in your data. 5. **Allowed Values for `source`:** * `web-client`: Events come directly from a web client SDK, such as a browser or a front-end application. Must include `hostname`, `pathname`, and `user_agent`. You can provide a `url` field instead of `hostname` and `pathname`. * `backend-http`: Events captured from backend systems via direct HTTP integration. * `backend-hubspot`: Events imported from HubSpot integration. * `backend-salesforce`: Events imported from Salesforce integration. * `backend-segment`: Events forwarded through Segment integration. * `backend-http-import`: Events imported through the HTTP Bulk Import API. # Userpilot API Documentation Source: https://docs.userpilot.com/api-references/overview Welcome to Userpilot's comprehensive API suite! This guide helps you understand the different ways to integrate with Userpilot, choose the right API for your needs, and get the most out of our platform's capabilities.
} title="Real-time APIs" href="/api-references/real-time/overview">

Live user tracking & events

Use cases:

  • Live user identification
  • Real-time event tracking
  • Instant personalization
  • Up-to-the-minute analytics
} title="Bulk Updates" href="/api-references/bulk-updates/users">

Update multiple profiles efficiently

Use cases:

  • CRM data synchronization
  • Batch profile updates
  • Large-scale data sync
  • Company information updates
} title="Import Data" href="/api-references/import/overview">

Historical data migration

Use cases:

  • Platform migration
  • Historical data backfill
  • Data warehouse replays
  • One-time data imports
} title="Export Data" href="/api-references/export/overview">

Analytics & reporting

Use cases:

  • Custom analytics
  • Data warehouse integration
  • Compliance reporting
  • External analysis tools
} title="Delete Data" href="/api-references/delete/overview">

Privacy compliance

Use cases:

  • GDPR compliance
  • User data removal
  • Privacy regulations
  • Data cleanup requests
# Identify Company Source: https://docs.userpilot.com/api-references/real-time/identify-company Identify and update company profiles in real time or in bulk using Userpilot's HTTP API. The Identify Company API allows you to create or update company profiles in real time, either individually or in bulk. Use this API to keep your company data in sync with Userpilot for analytics, segmentation, and B2B engagement. **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. ## Individual Identify ### Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/companies/identify ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. ### Headers | Header | Value | Required | | --------------- | ----------------------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `Accept` | `application/json, text/plain, */*` | Yes | ### Request Body | Field | Type | Required | Description | | ------------ | ------ | -------- | ------------------------------------------------------------------- | | `company_id` | string | Yes | Unique identifier for the company | | `metadata` | object | No | Key-value pairs describing the company (e.g., name, industry, etc.) | ### Example ```json theme={null} { "company_id": "company_001", "metadata": { "name": "Acme Corporation", "industry": "SaaS", "plan": "Enterprise", "monthly_spend": 1000 } } ``` ### Response A successful identification returns HTTP status code 200 OK. The `company_id` field is required. Metadata values must be primitive types (string, number, boolean, null). *** ## Bulk Operations For bulk company identification and updates, see the dedicated documentation: [**Bulk Identify Companies**](https://docs.userpilot.com/api-references/bulk-updates/companies#bulk-identify-update-companies) - For bulk company operations These articles provide comprehensive details on endpoints, authentication, request/response examples, limitations, best practices, and troubleshooting for large-scale data synchronization. *** [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Identify User Source: https://docs.userpilot.com/api-references/real-time/identify-user The Identify User API allows you to create or update user profiles in real time, either individually or in bulk. Use this API to keep your user data in sync with Userpilot for analytics, segmentation, and personalized experiences. ## When to Use Use the HTTP Identify API when: * Creating users from server-side code (e.g., after signup in your backend) * Updating user properties without a page load * Syncing user data from external systems * Your application doesn't run in a browser (backend services, mobile apps without SDK) **PII Data Notice** Before passing any Personally Identifiable Information (PII) such as names, emails, or other sensitive user data to Userpilot: * **Security & Compliance:** Verify internally with your legal, security, and compliance teams that doing so aligns with your organization's data privacy policies and applicable regulations (e.g., GDPR, CCPA). * **Data Type Mapping:** Ensure correct data type mapping for all properties. Userpilot supports String, Numeric, and Date types. Make sure dates are in ISO8601 format and numeric values are properly formatted. Incorrect type mapping can cause issues with segmentation, analytics, and debugging. * **Debugging:** Proper data formatting is crucial for effective debugging and troubleshooting. Verify that your data maps correctly to Userpilot's expected formats before implementation. **Use the JavaScript SDK instead** when: * Users are interacting with your web application in a browser * You need to display Userpilot content immediately after identification ## Prerequisites * Userpilot API Key (not App Token) from [Settings > Environment](https://run.userpilot.io/environment) * Knowledge of your API environment (US or EU) ## Individual Identify ### Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/identify ``` The endpoint URL uses the `analytex` environment. For EU data residency, use `analytex-eu` instead. See [Environment Settings](https://run.userpilot.io/environment) for your specific endpoint. ### Headers | Header | Value | Required | | --------------- | ---------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `X-API-Version` | `2020-09-22` | Yes | ### Request Body | Field | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------------------- | | `user_id` | string | Yes | Unique identifier for the user | | `metadata` | object | No | Key-value pairs describing the user | | `company` | object | No | Object with at least an `id` field for company association | ### Example ```json theme={null} { "user_id": "user_001", "metadata": { "name": "Jane Doe", "email": "jane@example.com" }, "company": { "id": "company_001" } } ``` ### Response A successful identification returns HTTP status code 202 Accepted. The `user_id` field is required. If you include a `company` object, it must have at least an `id` field. *** ## Bulk Operations For bulk user identification and updates, see the dedicated documentation: * **[Bulk Identify Users](../bulk-updates/users)** - For bulk user operations These articles provide comprehensive details on endpoints, authentication, request/response examples, limitations, best practices, and troubleshooting for large-scale data synchronization. *** ## Common Issues | Error | Cause | Solution | | ------------------ | -------------------- | -------------------------------------------------------- | | 401 Unauthorized | Invalid API key | Verify API key (not App Token) from Environment settings | | 400 Bad Request | Missing `user_id` | Include `user_id` field in request body | | 400 Bad Request | Company without `id` | If `company` object included, it must have `id` field | | User not appearing | Wrong environment | Verify endpoint matches your environment (US vs EU) | ## Related * [Track Event API](/api-references/real-time/track-event) - Track user actions * [Identify Company API](/api-references/real-time/identify-company) - Create/update companies * [Bulk Identify Users](/api-references/bulk-updates/users) - High-volume user operations * [Data Model Reference](/reference/data-model) - User and company schema details * [JavaScript SDK identify()](/developer/installation/web) - Browser-based identification [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Overview Source: https://docs.userpilot.com/api-references/real-time/overview Real-time HTTP APIs for user and company identification and event tracking in Userpilot. These APIs allow you to identify users and companies, update their profiles in bulk, and track custom events in real time. Integrate these endpoints with your backend or service to keep your Userpilot data up-to-date and actionable. ## Endpoints * [**Identify User**](./identify-user): Create or update individual user profiles, or update multiple users in bulk. Useful for onboarding, profile updates, and large-scale data syncs. * [**Identify Company**](./identify-company): Create or update individual company profiles, or update multiple companies in bulk. Ideal for B2B platforms and company-level analytics. * [**Track Event**](./track-event): Record custom events for users to monitor engagement, feature usage, and more. ## Rate Limits The real-time HTTP APIs enforce rate limiting to ensure optimal performance and fair usage across all applications. Understanding these limits helps you design robust integrations that work efficiently within the platform's constraints. ### Rate Limit Details * **HTTP Identify API**: **600 requests per minute** per application token * **HTTP Track Events API**: **600 requests per minute** per application token ### Error Responses When you exceed these limits, the API returns: * **`429 Too Many Requests`**: Returned when you exceed the 600 requests per minute limit ### Best Practices **Implement Exponential Backoff**: When you receive a 429 error, wait progressively longer before retrying (e.g., 1s, 2s, 4s, 8s). **Monitor Your Usage**: Track your request patterns to stay within limits and optimize your integration performance. **Handle Errors Gracefully**: Always implement proper error handling for rate limit responses in your applications. # Track Event Source: https://docs.userpilot.com/api-references/real-time/track-event The Track Event API allows you to record custom events for users in real time. Use this API to monitor user actions, feature usage, and engagement for analytics and personalized experiences. ## When to Use Use the HTTP Track API when: * Recording events from server-side code (e.g., payment completed, subscription changed) * Tracking actions that don't happen in a browser * Syncing events from external systems (CRM, billing, support) **Use the JavaScript SDK `userpilot.track()` instead** when: * User performs action in your web application * You need the event immediately available for content triggering ## Prerequisites * User must already exist in Userpilot (identified via SDK or API) * Userpilot API Key from [Settings > Environment](https://run.userpilot.io/environment) ## Endpoint ```http theme={null} [POST] https://analytex.userpilot.io/v1/track ``` ## Headers | Header | Value | Required | | --------------- | ---------------------- | -------- | | `Content-Type` | `application/json` | Yes | | `Authorization` | `Token {YOUR_API_KEY}` | Yes | | `X-API-Version` | `2020-09-22` | Yes | ## Request Body | Field | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------------- | | `user_id` | string | Yes | Identifier of the user associated with the event | | `event_name` | string | Yes | Name of the event to track | | `metadata` | object | No | Key-value pairs providing additional event details | ## Example ```json theme={null} { "user_id": "unique_user_id", "event_name": "user_subscribed", "metadata": { "plan": "free", "created_at": "1519205055" } } ``` ## Example cURL Command ```bash theme={null} curl -X POST https://analytex.userpilot.io/v1/track \ -H 'Content-Type: application/json' \ -H 'Authorization: Token {YOUR_API_KEY}' \ -H 'X-API-Version: 2020-09-22' \ -d '{ "user_id": "unique_user_id", "event_name": "user_subscribed", "metadata": { "plan": "free", "created_at": "1519205055" } }' ``` ## Response A successful event tracking returns HTTP status code 202 Accepted. Only primitive types (string, number, boolean, null) are supported in metadata. Use this endpoint to track any custom event relevant to your analytics or engagement workflows. *** ## Common Issues | Error | Cause | Solution | | ---------------------------- | --------------------------------- | ------------------------------------------------------- | | 401 Unauthorized | Invalid API key | Verify API key from Environment settings | | 400 Bad Request | Missing `user_id` or `event_name` | Both fields are required | | Event not appearing | Processing delay | Events may take up to 15 minutes to appear in dashboard | | Event not triggering content | User not identified | Ensure user exists before tracking events | ## Related * [Identify User API](/api-references/real-time/identify-user) - Create users before tracking events * [JavaScript SDK track()](/developer/installation/web) - Browser-based event tracking * [Events Dashboard](/data-events/events-dashboard) - View tracked events * [Funnel Reports](/product-analytics/reports/funnels) - Analyze event sequences ## FAQs Use the Track Event API for server-side events, actions that don't happen in a browser and use the JavaScript SDK's userpilot.track() when the action happens in your web app and you need the event available immediately for content triggering. Events may take up to 15 minutes to appear due to processing delay. If an event still hasn't shown up after that, check that the request returned 202 Accepted and that user\_id matches an already-identified user. Only primitive types such as string, number, boolean, or null are supported currently and 
nested objects/ arrays aren't supported.
[For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Building your Workflow Source: https://docs.userpilot.com/building-your-workflow Workflows in Userpilot allow you to design and automate multi-step user journeys across your product. ## Overview Workflows in Userpilot allow you to design and automate multi-step user journeys across your product. Using a drag-and-drop builder, you can connect content, data updates, and logic into a single, easy-to-understand sequence — complete with branching conditions, time delays, and automatic property updates. Whether you're guiding new users through onboarding or re-engaging customers at key moments, Workflows lets you orchestrate the right experience at the right time. Workflows are only available for Growth and Enterprise plans. ### Use cases * **Build guided onboarding journeys:** Create step-by-step onboarding experiences that adapt based on user actions, progress, or attributes. * **Drive feature adoption:** Trigger targeted flows, tooltips, or checklists after users complete key milestones or engage with specific features. * **Automate lifecycle communication:** Send surveys, emails, or in-app messages at strategic moments, including delayed follow-ups days or weeks after an event. * **Personalize user experiences:** Branch journeys dynamically based on user behavior, company data, or engagement with previous content. * **Track and update user data automatically:** Trigger events or update user properties as users progress through a workflow to keep data accurate and actionable. * **Improve retention and re-engagement:** Reconnect with inactive users through time-based nudges, reminders, or contextual experiences. * **Coordinate cross-channel journeys:** Combine in-app content with email and mobile experiences to create cohesive, multi-touch user journeys. * **Experiment and optimize journeys:** Visualize dependencies between steps to identify bottlenecks, test variations, and continuously improve outcomes. Image ## Get started To get started, simply navigate to the **Workflows** page from the navigation bar — here, you’ll see a table of all your created Workflows or have the option to create a new one. ## Define your Start and Exit Settings Before building your workflow steps, you’ll need to configure the start and end settings. These settings determine **who enters the workflow, when they enter, and when they exit**. Image ### **1. Define start settings** Start settings control how users are enrolled into the workflow. **Enrollment options** Choose how users should enter the workflow: * **Match condition** — Users are enrolled automatically once they meet the defined audience conditions. * **Event occurrence** — Users enter the workflow immediately after performing a specified event. * **Only-manually** — Users are added after triggering manually through other Userpilot content, a permalink or programatically. **Audience settings** Define which users are eligible to enter the workflow by configuring audience conditions such as user properties, company data, segments, events, or behaviors. Only users who meet these criteria will be enrolled. * **All Users:** Any identified user will be enrolled. * **Only Me:** Only enrolls users who have access to your Userpilot account (useful for testing). * **Saved Segment:** Use a predefined user segment to enroll a specific group. * **Custom Conditions:** Create a targeted subset of users by setting specific rules. **Environment selection** Select the environment where the workflow should run (i.e. production or staging). This is helpful for testing the workflow in your staging environment before making it live for all users. Image ### **2. Define exit settings** Exit settings determine when a user exits the workflow and whether they can enter again in the future. **Goal:** Define a goal to measure how your flow impacts user behavior and track key interactions. **Workflow exit rules:** Choose when users should exit the workflow: * **Reach the end** — Users remain in the workflow until they move through the final step. * **Complete a goal** — Users exit as soon as they achieve the defined goal, even if they haven’t reached the final step. **Re-enroll:** Control whether users can enter the workflow again after completing or exiting. This is useful for recurring processes such as periodic surveys, or lifecycle campaigns. ## Build your workflow Begin designing the workflow itself by adding steps to the canvas. Workflow steps define what happens after a user enters the workflow and allow you to create structured, behavior-driven journeys. IMAGENEW 1 There are three types of steps you can add: ### 1. Content steps Content steps allow you to trigger user-facing experiences at specific points in the workflow. These steps help you guide, educate, or engage users throughout their journey. You can trigger Flows, Spotlights, Banners, Checklists, Emails or Surveys. * **Create New or Clone:** Decide whether to build your content from scratch or duplicate an existing experience. When cloning, all content and configuration settings are copied from the original, (except for environment and audience, which are controlled by the workflow’s start settings). * **Skip logic:** From the step node’s ‘More actions’ menu, you can configure skip logic to move users to the next step if the content isn’t triggered within a defined time period. Image ### 2. Logic steps Logic steps control the flow and timing of the workflow. They help you create personalized paths and ensure users move through the journey in the intended order. * **True / False branches** — Split the workflow into different paths based on conditions such as user data or behaviour, company data, segments, or content engagement. * **Time delays** — Pause the workflow before the next step occurs for the user. Delays can be set for a specific duration (minutes, hours, days, weeks, or sessions) or until a specific date and time. ### 3. Data steps Data steps allow you to trigger backend actions without showing user-facing content. These steps help you keep your data accurate and track workflow progress. * **Track event** — Send an event when a user reaches a specific point in the workflow. * **Update property** — Update a user property with a predefined value when the step is reached. Image [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # AI Assistant Source: https://docs.userpilot.com/ce-basics/ai-assistant Use Userpilot's AI Assistant to generate, refine, and optimize in-app copy instantly, improving clarity, engagement, and consistency across flows. ## Overview Userpilot's AI writing assistant is a powerful copywriting tool that helps you enhance your content effortlessly. Whether you're refining existing text or creating something entirely new, the AI assistant leverages natural language processing to generate, improve, and optimize your writing. It offers a fast, reliable way to perfect your copy without needing expert-level writing skills or a dedicated content team. ## Use Cases * Instantly generate or refine UI text (tooltips, modals, banners) without relying on your content team. * Enhance existing onboarding flows by using AI to generate relevant copy, summarize, or extend content for clarity and engagement. * Automatically fix spelling, grammar, and punctuation errors in your copy, ensuring professionalism and accuracy. * Simplify and optimize onboarding flows by eliminating redundant or unnecessary steps in your copy. ## Guide Using the AI writing assistant is quick and simple. Here's how to get started: #### Starting from Scratch 1. In any text box within modals, tooltips, banners, or similar UI elements, press **'space'** to open the prompt field. 2. Type your desired prompt (e.g., "). 3. The AI will generate the relevant text for you, which you can tweak as needed. Animation #### Enhancing Your Existing Text If you already have some content, you can ask the AI to refine it or make adjustments: * **Continue writing:** If you're unsure how to finish your copy, ask AI to continue the text. It will seamlessly build upon your existing message. * **Fix spelling and grammar:** With a single click, the AI will automatically correct spelling and grammar mistakes, ensuring a polished output. * **Summarize:** If your content is lengthy, AI can summarize the key points, keeping it concise and to the point. * **Improve writing:** Let AI enhance your writing by rephrasing your sentences to be clearer, more engaging, or more professional. * **Make longer:** Need to elaborate on an idea or explain something in greater detail? The AI will add extra content to expand on your existing text. * **Make shorter:** Ideal for space-limited UI, such as tooltips, AI will condense your message while maintaining its core meaning. Animation2 Once the AI generates the new text, you can either accept the suggestion, tweak it as needed, or discard it and revert to your original draft. If discarded, your text will return to its initial state. ### Best Practices * **Be Specific with Prompts:** The more specific your prompt, the more tailored the AI output will be. For example, instead of "write a message," try "write a friendly welcome message for first-time users." * **Use AI for Quick Iterations:** Don't be afraid to experiment with different prompts to generate multiple variations of content, allowing you to choose the best fit for your app. * **Adjust AI Suggestions as Needed:** While the AI is a powerful tool, it may still need a human touch. Feel free to make small edits to ensure the tone and message align with your brand. *** ### FAQs The AI assistant is powered by OpenAI's advanced language models, making it highly accurate in grammar, structure, and style. However, for optimal results, it's best to review the content to ensure it matches your brand's tone and specific context. There is no strict limit to the amount of text the AI can generate. However, for readability and UI constraints, you may want to ensure that the generated text fits within your design requirements. The AI writing assistant can generate content in multiple languages, with the output depending on the language used in the input text. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Button Actions Source: https://docs.userpilot.com/ce-basics/button-actions Create seamless user journeys by assigning actions to buttons across your in-app experiences. ## Overview Button actions in Userpilot allow you to trigger specific actions when a user interacts with a button. These actions can help guide the effort experience, navigate through steps, or trigger external events, such as navigating to URLs or executing JavaScript functions. Button actions provide flexibility in customizing user interactions and can be used across different flows and steps to create a seamless experience. ## Use Cases * Guide users through multiple steps in a flow or jump to a specific step. * Redirect users to a specific URL or dynamic link based on user attributes. * Activate external flows, surveys, or JavaScript functions for more complex interactions. * Customize user experience by skipping groups or dismissing flows. ## Button Action Types Userpilot provides a variety of button actions to help you control the flow of the user experience. Each action can be used to perform specific tasks, such as navigating, triggering flows, or managing user settings. Screenshot 2026 06 02 At 11 40 43 PM This action will automatically navigate the user to the next step in the current flow. Redirect users to an external URL when they click the button. This is perfect for sending users to a webpage, a documentation page, or any external resource. If the URL is dynamic, make sure to pass the dynamic part as a user property. Then, replace the dynamic portion of the URL with the property placeholder to ensure each user is directed to the correct personalized URL. images/Screenshot2025-03-21at1.13.00PM.png If users need to go back to the previous step, this action allows them to reverse direction and revisit the prior screen in the flow. Instead of progressing step-by-step, you can jump to any specific step in the flow. This action allows more flexibility when creating non-linear user journeys. You can trigger a different flow when the user clicks the button. This is useful for connecting flows that may run independently but need to be linked based on user actions. Triggering Userpilot content from a button will not work in preview mode. To test it, you need to publish both the content and the flow, then test it live. Use this action to trigger a survey, allowing you to gather user feedback or conduct surveys at specific points in your flow. This action enables you to run a custom JavaScript function when the button is clicked. It’s ideal for integrating custom behaviors or triggering external scripts as part of the flow. If your flow is organized into groups, this action will let the user skip over the current group of steps and move directly to the next group. Great for skipping optional steps or providing an expedited flow. 1. **No Action** This button action simply closes the current flow without taking any other action. It is useful for offering users a way to dismiss or cancel the flow. 2. **Never Show This Flow Again** By selecting this action, users will be opted out of seeing the same flow in the future. It’s a good option for scenarios where users are familiar with the flow and don’t need to see it again. The settings in the button action will override the flow’s frequency settings. For example, if the flow is set to trigger every time but the button action is set to "Never show this flow again," the flow will not trigger again after the button action is clicked. 3. **Show This Flow in the Next Session** If you want the user to see the flow again at a later time, this action will ensure that the flow is shown to them in the next session. A new session is defined when a user returns to interact with the app after being inactive for more than 30 minutes. This means that actions like logging in or out, or closing and reopening the tab, do not automatically start or end a session. 4. **Mark Flow as Completed** This action marks the flow as complete for the user, meaning they will no longer see the flow again unless manually triggered. 5. **Unsubscribe User from Folder** In certain cases, you may want to unsubscribe a user from receiving further messages or updates from a folder. This action allows you to manage user subscriptions directly from the flow. ## Additional Functionality ### Update Properties and Track Events In addition to triggering the actions listed above, you can also update user properties and track events directly from the button actions. * **Update Properties:** You can update an already passed user property (such as a user’s status, role, or preferences) when a button is clicked. For example, you might update a user’s progress or completion status after they finish a flow. * **Track Events:** You can trigger specific events that will be logged for future analysis, helping you track how users interact with the flow and their behaviour during the process. This is especially useful for gathering data on button clicks or flow interactions to improve the overall user experience. ### FAQs If a user dismisses a flow, you can set the flow to show again in their next session or re-trigger it using specific conditions. If you've selected "Never Show This Flow Again," the user will not see it again unless manually re-triggered. You can surely achieve that by adding "userpilot.next();" to your Javascript code. You can align two buttons by first adding a button next to an existing button.  1. Open your Flow. 2. Hover the mouse pointer over the UI pattern, next to the existing button. A purple (+) button displays. 3. Click the purple (+) button and choose "button" [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Embeds Source: https://docs.userpilot.com/ce-basics/embeds Embed third-party tools like Calendly, Loom, Typeform, and Synthesia directly into Userpilot flows to deliver rich, interactive in-app experiences. ### Overview Userpilot's embed feature allows you to enhance user experiences by seamlessly integrating content from popular platforms directly into your flows. With just a click, you can embed tools like **Calendly, Loom, Typeform, and Synthesia**, making it easier to engage users, collect feedback, and provide dynamic content, all without leaving your site. ### Use Cases * Embed **Calendly** to let users book meetings instantly within Userpilot content. * Use **Loom** to embed explainer videos, tutorials, or support responses. * Integrate **Typeform** to collect feedback and insights effortlessly. * Add **Synthesia** videos to deliver personalized and scalable video content. * Adjust width, height, and padding for a fully tailored experience. Card settings Card design panel ## Embedding Options
### Calendly Easily integrate your **Calendly booking flow** into your Userpilot content, allowing users to schedule meetings without navigating away from your platform. This is ideal for product demos, customer support calls, or onboarding sessions, making scheduling frictionless and efficient. ### Loom Embed **Loom videos** into Userpilot modals to create engaging training materials, provide personalized support, showcase product demos, or deliver internal updates. By embedding Loom, you can add a human touch to your interactions and improve user engagement. ### Typeform Gather valuable insights with **Typeform's interactive forms and surveys**. Whether you're collecting user feedback, running customer satisfaction surveys, or building engaging quizzes, Typeform’s drag-and-drop editor makes it easy to design visually appealing and effective forms. Its modern design and flexibility make it one of the most user-friendly survey tools available. ### Synthesia Elevate your content with **AI-generated videos from Synthesia**. This tool allows you to create high-quality videos featuring AI-powered presenters, without the need for actors, filming, or editing. Use it for product walkthroughs, training sessions, or marketing videos. You can also scale personalized videos using Synthesia’s API integration. ### Customization To ensure a seamless fit with your design, Userpilot allows you to adjust the **width, height, and padding** of your embedded content, ensuring an optimal user experience. *** ### FAQs Yes! Embedded content is designed to be mobile-friendly and will adjust to different screen sizes for a smooth user experience. Additionally, you can control its visibility by selecting the Hide section for mobile option if needed. While embedded content is not tracked natively within Userpilot, most platforms (like Loom and Typeform) provide their own analytics to measure engagement. You would need to check the z-index in the card settings and ensure it's set correctly on the page to avoid being overlapped by another DOM element. If the issue persists, please reach out to [support@userpilot.com](mailto:support@userpilot.com). [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com) # Personalize Content Source: https://docs.userpilot.com/ce-basics/personalize-content Personalize Userpilot flows with dynamic variables to show tailored content for each user, increasing relevance, engagement, and overall product adoption. ## **Overview** Personalization allows you to dynamically display content within your flow. This feature helps make your interactions feel more personalized and tailored to each user, boosting engagement and enhancing their experience with your product. ## **Use Cases** * Use dynamic content like the user's name to make the experience feel more personalized and inviting. * Add personalized messaging throughout your flows to increase relevancy. * Personalizing content based on user data can create a stronger connection and encourage continued use. ### **Sending and Using Variables in Personalization** To use personalization in your flows, you must first send custom user property data to Userpilot during the installation process. This allows you to pass variables (such as the user’s first name) through the snippet, which will then be dynamically inserted into your UI patterns. ### **Inserting Dynamic Variables into Your Flows** 1. **Create your UI pattern**: Design the flow and add the necessary text sections as you usually would. 2. **Use the personalization icon**: In the text toolbar, click on the personalization icon to insert a dynamic variable. 3. **Select the dynamic user property**: Choose the variable (like the user's first name) you want to substitute in that part of the text. Screenshot2025 07 10at12 58 12 Pn ### **Setting Up Fallback Text** Sometimes, a user property may be missing (e.g., the user's first name hasn't been set). In this case, you can specify a fallback value. Simply type the fallback text in the "Fallback value" box. This ensures that if the dynamic data isn’t available, a default message (like “Hello, valued user!”) is shown instead. *** ### **FAQs** Absolutely! You can preview your flows with dynamic variables to see how the personalization will look in action, ensuring that everything displays correctly before going live. You can also set the flow to "Only Me" for testing. Anonymous users don’t have passed properties, so personalization cannot be applied to them since they don't have a name or a userid. [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com) # Create & Preview Content Source: https://docs.userpilot.com/ce-basics/preview-content Creating, managing, and previewing content can be done directly with the Userpilot Chrome Extension on your web app for Flows, Spotlights, Embeds, and Events. ### Overview Creating, managing, and previewing content can be done directly with the [Userpilot Chrome Extension](https://chromewebstore.google.com/detail/userpilot/ecmjjdafjebhegfhjincbdhgfonpibfm) on your web app for Flows, Spotlights, Embeds, and Events Labeling. After installing the extension on your browser, simply open your web app and run the extension to start your content building. ### Use Cases * Create content based on your web application and preview it directly there * Check how the user journey looks like in your end user's shoes * Make adjustments and preferences that suit your use case based on how your web app is built ### Desktop & Mobile Preview After building the content there is an option to preview/test it. For flows, we provide a full-flow preview and certain steps preview as well. Each step can be clicked on to adjust the related settings, add steps into groups, page changes within the same flow, localization, and logic. Our builder also supports responsive screens, previewing content on Mobile view can be done by switching the screen to a mobile browser in addition to hiding certain sections to keep things neat, make reading simpler, and remove any extra clutter for smaller screens. Only the related content can be viewed, triggering other content cannot be tested in preview under the selected one (f.e. setting a certain button to trigger another flow) ### FAQs This can be done by setting the Device Type under the Audience settings. Currently it's only supported for Flows, with the potential of adding it for other content types if needed. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Select The Right Element Source: https://docs.userpilot.com/ce-basics/select-element Learn how to accurately select and detect UI elements in Userpilot to ensure flows, tooltips, and product tours attach to the right components. ## Overview Detecting the right element in Userpilot is crucial for providing a personalized user experience through product tours, tooltips, and flow steps. Proper element selection ensures that the right features are highlighted and tracked for user engagement. The platform allows automatic detection of elements, with an option for manual adjustments when needed, ensuring accurate implementation of onboarding flows. ## Use Cases * Highlighting specific elements on a web application interface. * Continuing a flow even when the element is not visible on the page. * Modifying element detection to ensure proper onboarding functionality. ## Main Section ### What is a CSS Selector? A **CSS selector** is a pattern used to select and target HTML elements on a web page. These selectors allow Userpilot to accurately identify and interact with page elements. CSS selectors can target elements based on their ID, class, type, or other attributes. Inspecting the element with your browser’s "**Inspect**" tool can help you find the CSS selectors used by a particular element. ### How Userpilot Detects Elements Automatically When adding a new step in Userpilot, the builder automatically detects elements and selects the best CSS selector for them. It visually highlights the element on the page with a rectangle around the target. Based on this, Userpilot determines the optimal placement for UI patterns, such as tooltips or driven actions, on your app. ### When to Manually Adjust CSS Selectors Manual adjustments should only be made when automatic detection doesn’t work as expected, which occurs in rare cases. These include situations where: * The element is not detected properly, possibly due to dynamic content or complex page structures. * There are too many similar elements, causing the wrong one to be selected. ### How to Adjust CSS Selectors Manually 1. Choose the **'Manual'** option under the **Element** menu. 2. Once enabled, you can edit the CSS selectors for better precision. 3. To ensure that multiple similar elements are handled correctly, consider adjusting the **element order** or adding a text string filter to further specify the element. Screenshot 2026 07 10 122335 If the selected element contains dynamic selectors that may change with each page load or interaction, Userpilot provides an **Exclude List** feature to help mitigate this issue. By working with your development team, you can exclude dynamic selectors from being added when Userpilot detects the element. This ensures that once the dynamic selectors are added to the exclude list, any future element selections containing those selectors will be automatically ignored by Userpilot. Elements previously selected with dynamic selectors won't be automatically excluded. You'll need to manually reselect them after adding the CSS selectors to the Exclude List to ensure proper tracking. ### FAQs If you encounter this issue, manually adjust the CSS selectors by specifying the correct element using its unique attributes or text content. [For any questions or concerns please reach out to support@userpilot.com](mailto:support@userpilot.com) # Switching Themes Source: https://docs.userpilot.com/ce-basics/switching-themes Customize your flows with themes for consistent branding and flexible styling. ## Overview Switching themes in Userpilot allows you to customize the look and feel of your flow, either globally or on a per-step basis. You can maadoption se themes to provide a cohesive experience for your users or tailor the design for each individual step. The flexibility to adjust themes within the builder provides you with full control over how your content is presented. ## Use Cases * **Global Theme:** Set a consistent theme across the entire flow by adding a global theme, ensuring a unified visual style. * **Step-Specific Theme:** Modify individual steps with custom themes for more dynamic and tailored user experiences at specific points. ## Global Theme In Userpilot, you can apply a global theme to the entire flow. This theme is visible when you click the pen icon in the builder, giving you access to the global settings for the flow's design. Any changes made here will apply to all steps in the flow, ensuring consistency across the user journey. ## **How to Set a Global Theme** * Open the flow in the Userpilot builder. * Click on the pen icon at the top of the flow to access the global theme settings. * Choose your desired theme from the available options, and it will automatically apply to every step in the flow. Screenshot 2026 06 08 At 11 45 22 PM ## Switching Theme for Individual Steps You also have the ability to customize the theme for each individual step in the flow. By selecting a specific step, you can change its theme independently of the global theme to create variation when needed. This is ideal for highlighting specific steps or offering unique experiences for different parts of the flow. ### **How to Change Theme for a Selected Step** * In the flow builder, click on the step you wish to modify. * In the step settings panel, look for the theme option and select the desired theme for that step. * This theme will override the global theme for that particular step, giving it a distinct style. ### Understanding "Custom" Theme When a step has the theme labeled as "Custom," it means that manual adjustments have been made to the theme for that step. **Why the "Custom" Label Appears** * When you manually adjust the styling for a step, the theme will be marked as "Custom" to differentiate it from global theme. * This helps you keep track of which steps have unique design customizations. ### FAQs Manual changes override theme settings. For instance, if you change the font color manually, applying a new theme won’t affect it. To revert, you’ll need to manually reset those changes. No, changing the theme for an individual step will only affect that step and will not change the global theme or any other steps. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # UI Templates Source: https://docs.userpilot.com/ce-basics/ui-templates Save and reuse UI pattern templates in Userpilot to apply consistent styles, layouts, and settings across multiple flow steps and experiences. ## Overview Saving a UI pattern template allows you to reuse custom styles and settings across multiple steps. This feature helps streamline the design process and ensures consistency in user interfaces, saving time when creating similar patterns. By creating templates, you can focus more on design and less on repetitive tasks. ### Use Cases * **Rapid Deployment:** Quickly apply consistent UI patterns across multiple steps or projects. * **Branding Consistency:** Ensure uniformity in design by saving your preferred theme. * **Efficiency in Development:** Reduce time spent manually adjusting settings for every new step or page by reusing templates. * **Customization Across Projects:** Ideal for teams working on similar experiences but with slight variations in branding or layout.
## How to Save a UI Template Follow these steps to save a UI pattern template for future use: ### Step-by-Step Process Start by designing and adjusting your UI pattern according to your needs. Once you're satisfied with your design, go to the tool settings section and click on the "Save Template" button. This action stores the UI pattern for reuse.
After saving, you can easily access your templates anytime by navigating to the "SAVED" tab. When creating a new step of the same type, simply select your saved template from the list.
### What Settings Are Saved The following settings are saved when you save a template: * **Style Settings:** Customizations like background color, font size, and button actions are stored. Note: Some of these style settings may not be saved depending on the specific UI pattern and its implementation (e.g., Cards). * **Layout & Element Preferences:** Settings related to elements such as alignment, padding, and spacing. ### What Settings Are Not Saved The following settings are not saved when you save a template: * **Side-Panel Settings:** Elements like beacons, box configurations, element placement, and backdrop settings won’t be stored in the template. ### Managing Your Saved Templates You have full control over your saved templates. If you want to delete or rename a template: * Navigate to the "SAVED" tab. * Hover over the template to reveal the three horizontal dots icon. * Click on the icon to access options to either delete or rename your template.
![]() ### FAQs Yes, you can save as many templates as needed and organize them for different steps or project types. They are all stored in the "SAVED" tab for easy access. To make changes to a saved template, select it from the "SAVED" tab, modify the design, and save it again under the same name. You can also rename or delete templates as needed. [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com) #### # Data Capture & Privacy Source: https://docs.userpilot.com/configure/data-capture-and-privacy/data-capture-and-privacy The Data Capture & Privacy settings allow you to configure how user interaction data is collected, recorded, masked, and restricted across features like Session Replay and Auto-capture (raw events). ### Use Cases * **Control what user data is collected** – Decide which interactions, inputs, and sessions are captured to balance insights with privacy requirements. * **Protect sensitive information** – Mask or exclude specific elements, text inputs, URLs, or pages to prevent PII from being recorded. * **Enable secure session replays** – Observe real user behavior while ensuring sensitive fields and actions are hidden or excluded. * **Optimize session replay usage** – Make the most of your sessions allowance by recording only users or segments that are relevant to your analysis. * **Support compliance and governance** – Configure capture rules that align with GDPR, CCPA, or internal data-handling policies. ## Key Controls & Options Before getting started, navigate to the ‘Data Capture & Privacy’ tab within your settings. Screenshot2025 12 18at15 16 25 Screenshot2025 12 18at15 16 25 ### 1. Core data capture settings * **Automatically capture frontend events** - Enable Userpilot’s **autocapture** feature (raw events) to record frontend interactions automatically: clicks, text input changes, and form submissions. When enabled, Userpilot will start collecting this data once the SDK is active in your app. * **Session playback toggle** - Enable or disable **Session Replay** entirely. If turned off, Userpilot won’t store or display replayable session data * **Capture text input** - Enable text capture if you want typed interactions to show up in replays; if disabled, all text inputs are masked. * **Detection of Frustrations** - Automatically flags signals that indicate a user struggled. It detects dead clicks, rage clicks, u-turns, form abandonment, and error clicks during a session. * **Network & Console Capturing** - Records network errors, console errors, and uncaught exceptions and syncs them to the session replay in the built-in Dev Tools panel, so you can debug without pulling in engineering. Screenshot2025 12 18at15 24 07 Screenshot2025 12 18at15 24 07 ### 2. Element capture restrictions Use element-level rules to control how specific UI elements are captured in auto-captured events and session replays. * **Mask elements** — Hide the text content of selected elements in session replays. Masked elements remain visible in replays, but their content is replaced so sensitive information isn’t exposed. * **Exclude elements** — Fully exclude selected elements from data capture. Interactions, text, and metadata related to these elements won’t be recorded in raw events or session replays. * **Exclude attributes** — You can also exclude specific **attributes** (for example, `value`, `placeholder`, or custom data attributes) to prevent sensitive or unnecessary information from being captured. Screenshot2025 12 18at15 32 29 ### 3. Data capture restrictions Data capture restrictions allow you to limit where auto-captured events and session data are collected. * **Restrict by domain** - Exclude specific domains or subdomains from being recorded. This is useful for omitting sensitive areas such as authentication flows, billing pages, or internal tools. * **Restrict by user location** - Control data capture based on a user’s physical location (for example, country or region). This helps you align data collection with regional privacy requirements or internal policies. * **Ignore Frustrations and errors** - Set rules to exclude specific interactions from frustration and error detection. Pick a frustration or error type (e.g. rage click), scope it to where it occurred (e.g. Path equals /checkout/payment), and Userpilot will stop flagging that interaction in sessions. Screenshot2025 12 18at15 45 01 Screenshot2025 12 18at15 45 01 Screenshot 2026 07 22 At 12 19 06 AM ### 4. Session replay restrictions Session replay restrictions let you control *whose* sessions are recorded and stored. * **Segment-based recording** — Limit session replays to specific user or company segments (for example, paid users, users on a certain plan, or users in a specific region). Screenshot2025 12 18at15 46 01 Screenshot2025 12 18at15 46 01 ## See also * [Data Retention](/configure/data-retention/data-retention) — control how long Userpilot stores your analytics events and session replays. ### FAQs No, Userpilot would not capture the text of masked elements. So the text associated with the masked elements would not be saved in our database.  [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Data Retention Source: https://docs.userpilot.com/configure/data-retention/data-retention Control how long Userpilot stores your analytics events and session replays. Configurable on Growth and Enterprise plans, fixed on all other plans. Custom retention windows are available on **Growth** and **Enterprise** plans. All other plans use fixed retention values described below. ## Overview Data retention controls how long Userpilot stores the analytics events and session replays captured for your application. Each Userpilot organization has two independent retention windows: * **Tracked data and interactions** — how long Userpilot keeps analytics events (page views, tracked events, autocaptured raw events, content interactions) available for reporting. * **Recorded sessions** — how long Userpilot keeps session replay recordings available for playback. Aligning these windows with your needs helps you balance long-term trend analysis against compliance, privacy, and storage cost requirements. ## Use Cases * **Compliance and governance** – Configure shorter retention to align with GDPR, CCPA, or internal data-handling policies. * **Long-term trend analysis** – On Growth and Enterprise plans, extend retention to compare year-over-year product usage. * **Cost-aware operations** – Keep only the data you actively use for reporting, reducing the surface area of stored personal data. * **Audit and incident review** – Define a retention window long enough to reconstruct user journeys when investigating bugs or incidents. ## Retention by plan | Plan | Tracked data and interactions | Recorded sessions | Configurable? | | ---------- | ------------------------------------------- | --------------------- | ------------------------------------- | | Starter | **1 year** reportable (3 years stored) | **30 days** | No (fixed) | | Growth | **3 years** storage and reporting (default) | **30 days** (default) | Yes — contact your CSM representative | | Enterprise | **3 years** storage and reporting (default) | **30 days** (default) | Yes — contact your CSM representative | On Growth and Enterprise, both windows can be extended on request. Your current values are always visible in **Settings → Subscription → Plan details**. ## What's covered Retention windows apply to: * Tracked events (custom and built-in) * Autocaptured raw events * Content interactions (flow steps, checklist items, NPS / surveys responses, etc.) * Session replay recordings ## Where retention shows up in the product Retention windows are enforced consistently across the product. You'll see their effects in the following places. ### Settings → Subscription → Plan details The **Plan details** card now shows a **Data retention** section with two rows: **Tracked data and interactions** and **Recorded sessions**. The values reflect either your fixed plan limits or your custom configuration. Data retention section on the Plan details card Hover the info icon next to **Data retention** to see a tooltip with a **Change** button. Data retention tooltip with Change button ### Reports and Dashboards date pickers Date pickers in Reports and Dashboards are bounded by your analytics retention window. The earliest selectable date is the start of your retention window, and period presets that fall outside the window are hidden. When a previously selected start date falls outside your current retention window, Userpilot automatically adjusts it to the boundary and surfaces a tooltip that reads: **The date has been adjusted to stay within your data retention window.** ### Sessions date picker and filters The Sessions date picker, playlists, and saved filters are bounded by your **session replay** retention window — independent from analytics retention. ## Changing your retention period Changing retention is available on **Growth** and **Enterprise** plans only. 1. Open **Settings → Subscription → Plan details**. 2. In the **Data retention** section, hover the info icon and click **Change**. 3. A scheduling page opens so you can book a call with your Userpilot support representative to discuss the new retention values. If you're on Starter, or Trial, upgrade to Growth or Enterprise to unlock configurable retention. ## What happens when data expires * The cleanup job runs once per month, on the **first Saturday of the month at 03:30 UTC**. It is irreversible — expired data cannot be recovered. * Analytics events older than your configured window are deleted from storage in the partitions that match the expiry boundary. * Session replay recordings are tagged at capture time with their organization's retention window, and expire automatically through storage lifecycle policies. ## FAQs No. Once the monthly cleanup runs, expired analytics events and session replays are permanently removed and cannot be restored. If you need a longer retention window, change it before your data expires (Growth and Enterprise only). Yes. Only data still within your retention window is available to export. Data that has expired through the monthly cleanup is no longer available through the Export API. No. Monthly Active Users (MAU) counts and billing are independent from retention. Changing your retention window does not change how MAU is calculated. Date pickers across Reports, Dashboards, and Sessions are bounded by your retention window. The earliest selectable date is the start of that window. To go further back, you'd need a longer retention window (Growth and Enterprise only). Unless your organization has a custom agreement, the defaults are **3 years** for **tracked data and interactions** (how long events are stored and available for reporting) and **30 days** for **recorded sessions** (session replay storage). Your exact values are always shown at **Settings → Subscription → Plan details** in the **Data retention** section. Changes apply immediately for new data. Existing data that falls outside the new (shorter) retention window is removed at the next monthly cleanup. Existing data that fits within the new (longer) retention window stays available for reporting and replay. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Excluding Dynamic Class Names, IDs and Attributes Source: https://docs.userpilot.com/configure/exclude-lists/dynamic-attributes Dynamically generated class names, IDs, and attributes in JavaScript frameworks like React.js and Ember.js can hinder Userpilot's ability to target elements. ## Overview Dynamically generated class names, IDs, and attributes in JavaScript frameworks like React.js and Ember.js can hinder Userpilot's ability to target elements accurately. This article guides users on configuring Userpilot to exclude such dynamic attributes using regular expressions, ensuring more reliable element targeting. These patterns are variable and might change on every page load or deployment. Some examples of such patterns : ```css theme={null} .sc-1fzu5ml-0 // styled-component .jss514 // React.js #ember45 // ember.js ``` To improve targeting, Userpilot lets you exclude attributes using Regex in the Exclude Lists under Settings. You can access it by navigating to the [Exclude Lists](https://run.userpilot.io/settings/exclude-lists) under your Settings. ## **Example frameworks and how to exclude them** **Material-UI** Example: Excluding the auto-generated portion in the class with the format .jss514 ``` jss(.+?)$ ``` ``` css(.+?)$ ``` **Styled-components** Example: Using a regular expression to only match the stable portion of the class .sc-1fzu5ml-0 ``` sc-(.+?)-(.+?)buffer_3lt; ``` ``` ^[a-zA-Z]{6}buffer_4lt; ``` **Ember** Example: Excluding the number in the Id #ember45 ``` ember(.+?)$ ``` Screencapture Run Userpilot Io Settings Exclude Lists 2025 12 15 21 42 56 Pn # Exclude Users and Companies Source: https://docs.userpilot.com/configure/exclude-lists/exclude-user Exclude specific users or companies from Userpilot analytics or from seeing in-app messages to keep your reports accurate and ensure insights reflect real end-user behavior. ## Overview You can exclude users and companies in two different ways, depending on your goal.\ The first option is to exclude them from analytics only, this keeps your reports focused on real end-user behavior, but those users can still see Userpilot in-app messages. Excluded traffic is still recorded in the background and can be re-included in analytics at any time.\ The second option is to exclude users or companies from seeing Userpilot in-app messages, which prevents them from being targeted by in-app experiences such as flows, checklists, or surveys. ## Use cases * **Excluding internal team members** - If your internal teams (Product, QA, Support, Sales) use your product regularly, excluding them helps prevent their activity from skewing analytics and feedback. * **Filtering out rest or QA accounts** - During testing, staging, or content validation, test users often generate high volumes of artificial engagement. * **Cleaning up historical analytics** - If certain users or companies were mistakenly included in the past, excluding them helps restore confidence in reports and long-term trends. * **Hide experiences from internal/test accounts** - Run targeted experiments, or avoid showing beta content to certain customers. ## Exclude users and companies from Userpilot analytics * Go to [****Settings > Exclude Lists → Internal Users****](https://run.userpilot.io/settings/exclude-lists) in your Userpilot dashboard * Click **+ Add User ID** under List of excluded User IDs * Enter the **User ID** and select the user ID Screenshot2025 12 15at21 55 40 Pn * To exclude a company, click **+ Add Company ID**, enter the **Company ID**, and select the company ID Screenshot2025 12 15at22 02 47 Pn Excluding users or companies **does not affect live experiences**. Excluded users will still: * See in-app messages in **live mode** * Trigger engagement events * Generate notifications related to in-app message interactions This behavior is intentional today, and we’re considering enhancements in the future to provide more control over live delivery and notifications for excluded users. ## Exclude users and companies from seeing Userpilot in-app messages * Go to [**Settings > Exclude Lists → Internal Users**](https://run.userpilot.io/settings/exclude-lists) in your Userpilot dashboard * Under Excluded user IDs from Userpilot content, click **+ Add User ID** * Enter the **User ID** and select the user ID Screenshot2026 03 17at14 37 41 * To exclude a company, go to Excluded company IDs from Userpilot content, click **+ Add Company ID**, enter the Company ID, then select it from the list Screenshot2026 03 17at14 37 18 * Changes are applied **automatically**; no additional save action is required. You can also exclude **multiple User or company IDs in bulk** by selecting the **Wildcard** option. Enter the User or company ID, replace the dynamic part with an **asterisk (\*)**, and then click **+ Add User/company ID**. Screenshot2025 12 15at21 59 52 Pn [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Digest notification Source: https://docs.userpilot.com/configure/notifications/digest Use Digest notifications in Userpilot to receive scheduled summaries of key product insights, engagement metrics, and feedback via email or Slack. ## Overview The **Digest** in Userpilot helps you stay on top of your key product insights automatically.\ It sends a **customized summary email or Slack notification** containing updates on the most important user activities and engagement metrics.\ Instead of checking multiple reports, you can get everything that matters in one simple, scheduled summary. With the Digest, every team member can **customize their own summary**, decide what to include, and choose how and when to receive it. ## Use cases 1. Get weekly insights into how users engage with flows, pages, or checklists. 2. Receive a summary of survey or NPS responses to track satisfaction trends. 3. Review engagement data on spotlights, embeds, and campaigns. 4. Get a quick overview of user activity and performance without logging in. ## What Userpilot offers in the Digest Userpilot’s **Digest** gives you full control over your notification preferences and structure: 1. **Custom delivery** - Choose how often you want to receive the summary: **daily, weekly, or monthly**, and send it via **email** or **Slack**. 2. **Category control** - Enable or disable categories like **Data**, **Feedback**, and **Engagement** using toggles. 3. **Granular filters** - Select whether to include **all content**, **only content you created**, or set **custom filters**. 4. **Personalized structure** - Rearrange the order of sections in your Digest using **drag-and-drop**, so your most relevant insights always appear first. 5. **User-Level configuration** - The Digest is fully personal. Each team member can set up their own Digest preferences, and notifications are sent **only to the logged-in user**. digest-overview ## How percentages and trends are calculated in the digest email The Digest email calculates metrics by comparing performance in the current period with the previous equivalent period. #### Weekly digest \ If the digest is scheduled to be sent on a Wednesday, the current period covers the time from that Wednesday to the following Wednesday. The previous period covers the Wednesday of the prior week up to the current Wednesday. The system then compares the data between these two time frames to show trends. #### Monthly digest \ If the digest is scheduled to be sent on the 21st of April, the current period runs from the 21st of March to the 21st of April. The previous period runs from the 21st of February to the 21st of March. The system compares these periods to highlight changes in performance. * In the Survey report, the Completed column indicates the number of users who have answered all survey questions. * For NPS, the percentage represents the number of users who selected a specific score divided by the total number of users who submitted an NPS response. Please note that all percentage values reflect trends in the data. The trend reflects the number of survey **completed** event. Screenshot2026 03 18at17 40 45 Screenshot2026 03 18at17 41 03(1) ## Notification examples 1. Slack notification Screenshot2025 10 07at16 22 49 Pn 2. Email notification Screenshot2025 10 07at16 25 19 Pn [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Get started with notifications Source: https://docs.userpilot.com/configure/notifications/get-started-with-notifications Get started with Userpilot notifications to stay aligned on product updates, performance insights, and system alerts via in-app, email, or Slack. ## **Overview** Userpilot Notifications help your team stay aligned and take action faster by centralizing updates from your workspace. You can receive notifications through **three types** of notifications, **System Notifications, Digests, and Signals**, and choose how they’re delivered: 1. **In-app:** Receive alerts directly inside Userpilot while working 2. **Email:** Get summarized updates or alerts sent to your inbox 3. **Slack:** Instantly share key updates with your team through connected Slack channels ## **Use cases** 1. Get notified when new flows, checklists, or experiments are published. 2. Receive a weekly or monthly summary of product usage, flow performance, and engagement. 3. Notifications can be automatically routed to Slack or email, helping Growth and CS teams act quickly. 4. Share insights directly in Slack to spark discussions or follow-ups. 5. Choose what you want to be notified about and how (e.g., only critical system alerts via Slack, performance digests via email). 6. Each teammate can customize their notification settings from Settings → Notifications. ## Next steps To start using notifications: 1. Go to **Settings → Notifications.** 2. Select the notification type you would like to receive: **System Notifications**, **Signals**, or **Digest**. 3. Select the **channels** (In-App, Email, Slack) you want to use. 4. Adjust your **preferences** based on the types of alerts or digests you want to receive. Screenshot2025 10 07at14 28 07 Pn **Slack Notifications**\ To receive notifications in Slack, first **enable the Slack integration** from the **Integrations page** in Userpilot and follow the setup steps.\ Once connected, you will start getting **System Notifications**, **Signals**, and **Digests** directly in Slack. Screenshot2025 10 07at14 40 48 Pn # Signal notifications Source: https://docs.userpilot.com/configure/notifications/signals Use Signal notifications in Userpilot to alert your team about key in-app events in real time or on a schedule via in-app, email, or Slack. ## Overview Signals in Userpilot allow you and your teammates to stay informed about key in-app activities through automated notifications.
You can configure personalized signals to alert your team when important events occur, such as when a flow is completed, a survey is submitted, or an NPS response is received, without needing to constantly monitor dashboards. Signals can be delivered **in real-time** or on a **scheduled basis (hourly, daily, weekly)** through multiple channels: * **In-app (Inbox)** - visible directly within Userpilot. * **Email** - sent to selected recipients or teams. * **Slack** - posted to designated Slack channels for instant visibility. This flexibility ensures your team never misses critical product or user insights. ## Use cases 1. Get notified when a flow or a checklist is completed to measure adoption. 2. Stay informed the moment a user submits an NPS score and feedback. 3. Track page views or campaign engagement in real-time. 4. Monitor survey submissions or forms to identify customers who need follow-up. ## What Userpilot offers in signals Userpilot’s **Signals** feature is built for control, flexibility, and collaboration: 1. **Multi-channel delivery**: send alerts via **in-app**, **email**, or **Slack channel(s)**. 2. **Event-based triggers**: choose from **flows**, **checklists**, **surveys**, **forms**, **NPS**, **pages**, or **events** to trigger notifications. 3. **Custom frequency**: send alerts in **real-time** or as summaries **hourly**, **daily**, or **weekly**. 4. **Team visibility**: share notifications across team members to align actions across functions. Signals Pn Signals Pn ## How to create a signal 1. Go to **Settings → Notifications → [Signals](https://run.userpilot.io/settings/notifications/signals)** 2. Click **Create Signal** 3. Select the type of event that should trigger your signal.
You can choose from: 1. **Flows** - when a user starts, completes, or skips a flow 2. **Checklists** - when a checklist is completed 3. **Surveys or NPS** - when a user submits a response 4. **Pages or Events** - when a user performs a specific action 4. Select the **Channel** where you want your signal to be sent: 1. **Slack** - sends an alert to your selected Slack channel 2. **Email** - sends an email notification to specific recipients 3. **In-App (Inbox)** - delivers the signal directly inside Userpilot 5. Select the users or team members who should receive the notification. You can choose individuals, teams, or connected Slack channels. 6. Set the **Frequency** by choosing how often you’d like the signal to be sent: 1. **Real-time** (as soon as the event happens) 2. **Hourly**, **Daily**, or **Weekly** summaries 7. Click **Save** to finalize your setup. Your new signal will appear in the list; you can toggle it **on/off** anytime. Hjj Pn You can create one signal per event type. For example, you can’t use a single signal to receive notifications from both **Flows** and **Events**. If you’d like to track multiple event types, simply create a separate signal for each one. ## Permissions and access control Workspace account owners can manage who can **create** or **delete** signals through the **Permissions** settings. This ensures that only authorized users can modify or manage signals, keeping your workspace notifications organized and consistent. Screenshot2025 10 07at16 02 54 Pn ## Notification examples 1. Slack notification Frame20 Pn 2. Email notification Email Notifications6 Pn 3. In-app (inbox) 41 Pn If you prefer to receive signal notifications in **real-time,** **hourly, daily, or weekly**, Userpilot will automatically **aggregate your notifications** and deliver them in a single bulk update based on your selected frequency while creating the Signal. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # System notifications Source: https://docs.userpilot.com/configure/notifications/system-notifications Use System Notifications in Userpilot to stay informed about data health, content updates, and engagement events via in-app, email, or Slack alerts. ## Overview System Notifications in Userpilot keep you informed about key activities, data issues, and content updates within your workspace.\ They’re designed to help you **stay in control** of your app’s health, from monitoring data flow to tracking content status, so you can act before small issues become big ones. System Notifications are **user-level**, which means only the logged-in user will receive them through their preferred channel: * **In-app (Inbox)** - notifications appear directly inside your Userpilot workspace. * **Email** - updates are sent to your registered email address. * **Slack** - alerts can be sent to your connected Slack account (once integration is enabled). ## Use cases 1. **Monitor data flow health:** Get notified when a page, mobile screen, or event hasn’t received data for over 21 days. 2. **Get alerted on flow issues:** Get notified when a tooltip or driven action doesn’t appear as expected. 3. **Stay updated on engagement:** Receive alerts when an experiment ends or content you created is published/unpublished. 4. **Track feedback responses:** Be informed when a new survey, NPS, or form response is submitted. 5. **Reduce noise:** Choose exactly what you want to be notified about, all content, only your content, or custom selections. ### How to set up system notifications 1. Go to **Settings → Notifications → System Notifications.** 2. Toggle on the sections you want to receive alerts for (**Data**, **Engagement**, **Feedback**). 3. Choose the content scope: * **All content** * **Only content I created** * **Custom** 4. Select how you want to receive alerts: **In-app**, **Email**, or **Slack**. 5. For Slack, ensure you’ve completed the **Slack integration** under **Settings → Integrations** (this is a one-time setup). Screenshot2025 10 07at15 06 30 Pn ## Notification types Within the **System Notifications** tab, notifications are grouped into three main categories: #### **1. Data** Stay informed when data stops flowing to your workspace. * Page hasn’t received data for 21 days * The mobile screen hasn’t received data for 21 days * The event hasn’t received data for 21 days\ You can set these alerts for *all content*, *only the ones you created*, or *custom selections*. #### **2. Engagement** Get notified when content is published, unpublished, or encounters an error. * When your content (flows, checklists, Resource center, mobile content, banners, spotlights ) is published/unpublished. * When an experiment ends. * When content encounters errors or disruptions, Userpilot will notify you when content breaks, for example, if a specific step stops displaying in a flow. #### **3. Feedback** Keep track of all incoming user feedback. * When a survey or NPS response is received. * When a form submission is made. * When feedback-related content you created is published or unpublished. Screenshot2025 10 07at14 28 07 Pn You can stop receiving all notifications by turning off a category.\ Or, if you prefer to receive specific types of notifications on certain channels, customize your preferences by selecting the checkboxes for the channels you want: **In-app**, **Email**, or **Slack**. ## Notification schedule | **Channel** | **Time** | | :---------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Slack | Real-time notifications for all notification types | | In-app | Real-time notifications for all notification types | | Email | 1. Aggregate responses from surveys, NPS, and form submissions, and send them in a batch every 3 hours
2. Aggregate all errors and send a summary at the end of each day | ## System notification permission If a team member doesn’t have permission to receive Survey or NPS notifications, Userpilot will prevent them from enabling these notification types and display a message prompting them to contact their account owner to request access. Screenshot 2025-10-07 at 15.39.46.png ## Notification examples 1. Slack notification 67 Pn 2. Email notification Email Notifications6 Pn 3. In-app (inbox) 41 Pn ## FAQs No, each teammate would be able to manage their own notification preferences from the account settings and it wouldn't be possible to turn off notifications for other teammates. For any questions or concerns please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Two-Factor Authentication (2FA) Source: https://docs.userpilot.com/configure/team-and-roles/2fa Enable Two-Factor Authentication (2FA) in Userpilot to add an extra layer of security and protect your workspace from unauthorized access. ## **Overview** Two-Factor Authentication (2FA) adds an extra layer of security to your Userpilot account by requiring users to verify their identity using a passcode generated from an authentication app (such as Google Authenticator, 1Password, or Authy).\ This ensures that even if a password is compromised, your workspace remains protected. ## Use cases 1. You want to enhance workspace security across all teammates 2. You are working with sensitive product data or customer information 3. You are required to meet internal compliance or security guidelines 4. You use SSO and want an additional verification layer 5. You want to ensure only verified users access your Userpilot setup ## Enable 2FA 1. You can enable 2FA settings from [******Settings → Team → Authentication → Mandatory Two-Factor Authentication******](https://run.userpilot.io/settings/team/authentication) 2. Toggle **“Require all teammates to authenticate via 2FA”** on By default, 2FA is **not required**, and teammates can log in normally. Admins can choose to enforce it for the entire team Screenshot2025 12 14at10 45 54 Pn 3. Once enabled: * All existing teammates will receive an **invitation to enroll in 2FA** * New teammates will be required to set up 2FA immediately after creating their password Screenshot2025 12 14at10 51 04 Pn Screenshot2025 12 14at10 53 31 Pn * Users can't access the workspace until they complete their 2FA setup * A 2FA icon appears next to their name in the Teammates table Screenshot2025 12 14at11 02 46 Pn Admins can disable 2FA for a teammate if the user is locked out of their account. For example, after losing access to their authentication device. Screenshot2025 12 14at11 04 10 Pn **Note:**\ Team members can enable Two-Factor Authentication from **Settings → User** by scanning a QR code and activating 2FA on their account. However, if an admin has enforced **mandatory 2FA** for the entire workspace, users will **not** be able to disable it themselves. Only admins have permission to disable 2FA for a teammate. Screenshot2025sss12 14at11 22 08 Pn # Access and activity logs Source: https://docs.userpilot.com/configure/team-and-roles/access-and-activity-logs Use Access and Activity Logs in Userpilot to monitor workspace access, track admin actions, and maintain security with detailed, auditable records. Activity logs are available with Enterprise plan. Kindly reach out to [support@userpilot.com](mailto:support@userpilot.com) if you need any assistance. ## Overview Managing a workspace often requires more than assigning roles and permissions; you also need visibility into who is accessing your account and what actions are taking place inside it.\ Userpilot provides two dedicated logs to help you monitor workspace activity and maintain security: **Access Logs** and **Activity Logs**. Both logs are available under **Settings → Team**, each serving a different purpose depending on the level of insight you need. ## Access Log The **Access Log** focuses on workspace entry and permission changes. It answers the question: * Who accessed my workspace * What admin-level changes did they make? **You can see these details in the access log page:** * **Login activity** - Shows which teammate logged into your Userpilot workspace. * **Role changes** - Tracks who changed another teammate’s role and when. * **Provisioning activity** - Records teammates being added, removed, or having their role changed, whether through [SCIM directory sync](/configure/team-and-roles/scim), [JIT provisioning](/configure/team-and-roles/jit), [CSV import](/configure/team-and-roles/csv-import), or a manual invite. Each entry shows the role before and after, who or what triggered it, the application, and the reason. * **IP addresses** - Helps you verify where the login originated from. * **Timestamps** - Displays the exact date and time of each action. **When this is useful** * Monitoring unauthorized or unusual logins * Keeping track of administrative changes * Reviewing account access for audits or security checks * Troubleshooting permission-related issues The Access Log is especially helpful for admins and account owners who need transparency into how workspace access is being managed. ### Filtering the Access Log To find a specific change quickly, filter the Access Log by: * **Source** - where the change came from: **Web app**, **SCIM provisioning**, **SSO sign-in**, or **CSV import**. (SCIM scheduled syncs and directory webhooks share the single **SCIM provisioning** source.) * **Activity** - the type of change: **Member provisioned**, **Member deprovisioned**, **Changed a member's role**, or **Role sync skipped (set manually)** - plus sign-in, 2FA, and SSO events (Signed in, Invited a member, Removed a member, Enabled/Disabled SSO, and so on). You can also search by teammate name or email. This makes it easy to audit, for example, every teammate your identity provider added last week, or why a particular role change was skipped during a sync. Screencapture Run Userpilot Io Settings Team Access Log 2025 12 11 22 11 26 Pn ## **Activity Log** The **Activity Log** tracks in-product activity, specifically, actions performed inside the Userpilot workspace. It answers the question: * What changes were made to the content * Who made them? ### **What you can see in the Activity Log** * **Publish actions** - Shows when a flow, checklist, or other content has been published. * **Unpublish actions** - Shows when content has been taken down or disabled. * **Content titles and types** - Easily identify which flow, checklist, survey, or element was updated. * **IP addresses and timestamps** - For added traceability. ### **When this is useful** * Tracking content changes across your workspace * Understanding who published or unpublished flows * Reviewing collaboration activity within your team * Maintaining compliance or internal documentation * Troubleshooting unexpected content updates The Activity Log is particularly valuable for teams working on multiple flows or onboarding experiences at the same time, helping ensure nothing goes live or offline without visibility. Screencapture Run Userpilot Io Settings Team Activity Log 2025 12 11 22 15 56 Pn For any questions or concerns please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Bulk Teammate Import (CSV) Source: https://docs.userpilot.com/configure/team-and-roles/csv-import Invite many teammates to Userpilot at once by uploading a CSV with a role per application. ### Overview The CSV import lets you invite many teammates to your Userpilot applications from a single file, instead of inviting people one at a time. You upload a CSV, review a validation preview, and confirm. Userpilot then invites each teammate with the role you specified. This is one of three ways to add teammates, alongside manual invites and automated provisioning through [SCIM](/configure/team-and-roles/scim) and [JIT](/configure/team-and-roles/jit). Unlike SCIM and JIT, importing is an invite action and is available on every plan. You can run the import from two places: * **Settings > Team** imports teammates into the application you are currently viewing. * **Admin Console > Team** imports across your whole organization, with each row naming its target application. ### Requirements * Permission to invite teammates, the same permission used for single invites. * To assign a given role, you must hold a role with at least that level of access in the target application. CSV import is disabled whenever SCIM directory sync is active - in every role-management mode, not only when the IdP owns roles (see [SCIM role management](/configure/team-and-roles/scim#choosing-who-owns-roles)) - and while a sync is in progress. Once SCIM is on, teammate membership comes from your IdP. ## Importing teammates On **Settings > Team** (or the Admin Console's **Team** page), click **Import** to open the importer drawer. Import teammates from CSV drawer In the **Start with the template** card, click **Download .CSV** to get a correctly formatted file (`userpilot-teammates-template.csv`). The template matches the importer you opened it from, so you can fill it in and upload it as is. In the Admin Console importer, the drawer also lists **Your applications**, with each application's name and token for reference. Drag and drop your `.csv` onto the dropzone, or click to browse. Files must be `.csv` and up to 2 MB. Userpilot validates every row and groups them into up to three tables, each showing the teammate, role, and application: * **Rows with errors.** Invalid rows (bad email, missing or unassignable role, and so on), each with the reason. Fix the file and re-upload - these are not imported. * **Rows won't be imported.** Rows skipped because the person already exists as a teammate, or the row is a duplicate within the file. * **Rows ready to import.** Valid rows that will be invited when you confirm. Click **Invite Teammates** to invite everyone in the **Rows ready to import** list. Importing runs in the background, and rows that fail do not stop the others. ## CSV format ### Admin Console importer The org-wide import needs these columns, with exactly these headers: | Column | Required | Notes | | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `email` | Yes | The teammate's email address. | | `first_name` | Yes | May be left blank. | | `last_name` | Yes | May be left blank. | | `application` | Yes | The application token, shown in the importer under "Your applications". Application names are also accepted, but tokens are safer because they are unique. | | `role` | Yes | A role that exists in that application. | Roles are set per application. To add someone to multiple applications, add one row per application, with the same email but a different application token and role on each row. ```csv theme={null} email,first_name,last_name,application,role jane.doe@example.com,Jane,Doe,NX-abc123,Admin john.smith@example.com,John,Smith,NX-abc123,Publisher john.smith@example.com,John,Smith,NX-def456,Analyst ``` Rows can also target the Admin Console itself. For those rows, use one of the Admin Console roles: `Admin`, `Billing`, `View Only`, or `Account Owner`. ### Team page importer The importer on **Settings > Team** always targets the application you are viewing, so the `application` column is dropped: ```csv theme={null} email,first_name,last_name,role jane.doe@example.com,Jane,Doe,Admin john.smith@example.com,John,Smith,Publisher ``` Account Owner can be assigned via CSV, but only if you are an Account Owner yourself. In general, you can only assign roles whose access is within your own role's permissions. The same applies to the [JIT](/configure/team-and-roles/jit) and [SCIM](/configure/team-and-roles/scim) default roles, which can also be set to Account Owner. ## Validation and limits Each row is checked before anything is invited: * **Email** must be a valid address. If it already belongs to a different Userpilot organization, that row is rejected with a clear message and no invite is sent for it. * **Application** must exist in your organization (Admin Console importer). * **Role** must exist in that application, and you must be allowed to assign it. * **Seat limits** are enforced per application. A row that would exceed your plan's seats is blocked, while the rest of the import continues. * **File size** is capped at 2 MB and 50,000 rows. Re-importing a teammate who already exists is treated as already invited and is skipped, so running the same file twice will not create duplicates. ## After import Each successfully imported teammate: * Receives an invitation to their application or applications, with the role from the CSV. * Is created without a password if your organization enforces [SSO](/configure/team-and-roles/sso). In that case they sign in through your identity provider. * Is recorded in the Access Logs with the source CSV, so you can audit exactly who was added and by whom. See [Access and activity logs](/configure/team-and-roles/access-and-activity-logs). CSV import is available only while SCIM is off (or in orgs without SCIM). A CSV teammate's role is flagged as manually set, so if you later enable SCIM, a hybrid-mode sync keeps that role. But CSV teammates are not in your IdP directory, so mapping or re-mapping your groups removes them like any other non-IdP member. Role protection covers the role, not membership. ## FAQs It is hidden or disabled whenever SCIM directory sync is active (in any role-management mode - manage teammates in your IdP), while a SCIM sync is running, or if you do not have permission to invite teammates. No. Invalid rows are listed under "Needs attention" and skipped, and valid rows still import. Rows that fail during processing, for example by hitting a seat limit, do not stop the rest. Use the Admin Console importer and add one row per application, with the same email but a different application token and role on each row. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Just-in-Time (JIT) Provisioning Source: https://docs.userpilot.com/configure/team-and-roles/jit Automatically create Userpilot teammates the first time they sign in with SSO, using your verified identity-provider domains. This feature is available on the Enterprise plan and requires [SSO](/configure/team-and-roles/sso) to be enabled. ### Overview Just-in-Time (JIT) provisioning creates a Userpilot account for a teammate the first time they sign in through SSO. No manual invite or prior sync is required. Without JIT, a person who signs in with SSO but has no account is turned away. With JIT, their account is created during sign-in and given a default role. JIT is the simplest way to onboard a team. It works alongside the other provisioning methods: * **JIT** handles individual first-time sign-ins. * **[SCIM](/configure/team-and-roles/scim)** keeps whole groups of users and their roles in sync with your identity provider. * **[CSV import](/configure/team-and-roles/csv-import)** invites a known list of teammates in bulk. JIT and SCIM work well together. JIT gives a teammate immediate access on first login, and a later SCIM sync can move them into a mapped group and update their role. ### Requirements * [SSO](/configure/team-and-roles/sso) enabled for the organization. * An Account Owner role, or a role with the Manage SSO permission. ## Enabling JIT provisioning JIT is configured on the **Just-in-time provisioning** card under **Settings > Team > [Authentication](https://run.userpilot.io/settings/team/authentication)**. The card appears once SSO is enabled. Switch on **Create teammates automatically on first SSO login**. Set **Default role on first SSO login**. This role is granted when a teammate signs in via SSO for the first time, until SCIM assigns them a mapped role. The available roles are Admin, Publisher, Analyst, and Account Owner. Because this role applies to everyone JIT creates, pick Account Owner only if every teammate who signs in through your verified SSO domains should have full ownership. JIT stays off until you choose a default role. Set **Default application**. This is where auto-created teammates land on their first SSO login, and on logins started from your IdP tile. Just-in-time provisioning settings ## How it works The first time a teammate signs in through SSO without an existing account, Userpilot does the following: 1. Confirms the sign-in came through your organization's verified SSO connection. 2. Checks that the teammate's email domain is one of your verified SSO domains. 3. Creates the account, assigns the default role, and places the teammate in the default application. If SCIM later places a JIT-created teammate into a mapped group, that group's role replaces the JIT default role on the next sync. The JIT default is a starting point, not a permanent assignment. The one exception is the Userpilot [role-management mode](/configure/team-and-roles/scim#choosing-who-owns-roles), where SCIM never changes roles. ## IdP-initiated SSO JIT provisioning supports IdP-initiated SSO, so teammates can reach Userpilot straight from your identity provider without being invited beforehand. There are two ways to start an SSO sign-in, and JIT works with both: * **Service-provider-initiated.** The teammate starts from Userpilot, enters their work email, and is redirected to your identity provider to authenticate before being sent back to Userpilot: `Userpilot → Identity provider → Userpilot` * **IdP-initiated.** The teammate opens the Userpilot tile from their identity provider's app dashboard and is sent straight to Userpilot, where JIT provisioning creates their account and completes the sign-in: `Identity provider → Userpilot` Identity provider app dashboard showing application tiles With JIT enabled, an eligible teammate has their Userpilot account created during their first SSO login from either flow, as long as their email domain is one of your verified SSO domains. A manual invitation or prior SCIM sync is not required. New teammates land in the [default application](#enabling-jit-provisioning) you set for JIT. ## JIT and SSO are linked JIT only runs during an SSO sign-in, so its availability follows SSO: * Disabling SSO automatically turns JIT off. * Deleting the SSO configuration turns JIT off and clears the JIT default role. If you re-enable SSO later, re-enable JIT and select its settings again. ## FAQs Check that JIT is on, that a default role and default application are set, and that the teammate's email domain is one of your verified SSO domains. Yes. Account Owner is selectable as the JIT default role, the same as in [CSV import](/configure/team-and-roles/csv-import). Because the default role applies to every teammate JIT creates, choose it only when that is what you intend. Not necessarily. JIT alone is enough to onboard teammates on first login. Add SCIM when you also want roles and de-provisioning to stay in sync with your IdP groups. Yes. When a teammate opens the Userpilot tile in your identity provider (an IdP-initiated login), JIT creates their account and signs them in, the same as a sign-in started from Userpilot. No prior invite or SCIM sync is needed. [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com) # Managing your team in Userpilot Source: https://docs.userpilot.com/configure/team-and-roles/managing-your-team-in-userpilot Manage teammates in Userpilot by inviting users, assigning roles and permissions, tracking activity, and securing access with authentication controls. ### Overview You can manage who has access to your Userpilot workspace by inviting your colleagues and assigning them roles with the right permissions. This gives you flexibility in defining each person’s responsibilities. Userpilot provides predefined roles such as Admin, Account Owner, Publisher, and Analyst, and you can also create custom roles to tailor permissions exactly to your team’s needs. You can also review [access and activity logs](/configure/team-and-roles/access-and-activity-logs) to monitor who has logged in and what actions they have taken, ensuring everything remains secure and well-tracked. From the **Authentication** tab, you can also enable [2FA](/configure/team-and-roles/2fa), [SSO login](/configure/team-and-roles/sso), [Just-in-Time provisioning](/configure/team-and-roles/jit), and [SCIM directory sync](/configure/team-and-roles/scim) for enhanced security and automated user management. Custom roles, access logs, activity logs, and advanced authentication options are only available on the Enterprise plan. If you’re on a lower plan, you’ll need to [upgrade](https://userpilot.com/pricing/) to access these features. ### Teammates The **Team** tab in Userpilot allows you to control who has access to your workspace, assign the right permissions, and keep track of activity. Whether you're collaborating with product managers, designers, analysts, or engineers, this section helps you manage roles and maintain workspace security with ease. * **Filters and role tags** - At the top, you will find role-based filters that help you quickly sort teammates by their responsibilities or permission levels. * **Search** - Use the search bar to find teammates instantly by typing their name or email. * **User List** - This section shows all workspace members, and you can easily update their roles or manage their permissions directly from here. Team tab showing the list of teammates with roles and filters If a teammate hasn’t accepted their invitation yet, Userpilot will show a red clock icon beside their name. You can resend the invitation to keep your workspace setup on track. Resend Invite option for a teammate with a pending invitation ### Adding teammates There are three ways to add people to your workspace: * **Invite individually** - Click **Invite Teammates**, enter the email, and choose a role and application. * **[Bulk import via CSV](/configure/team-and-roles/csv-import)** - Upload a CSV to invite many teammates at once, with a role per application. * **Automated provisioning** - On the Enterprise plan, let your identity provider manage teammates with [SCIM directory sync](/configure/team-and-roles/scim), or create them automatically on first SSO login with [JIT provisioning](/configure/team-and-roles/jit). Whenever SCIM directory sync is active - in every role-management mode, not only when the IdP owns roles - inviting and importing teammates directly in Userpilot is disabled, and membership comes from your IdP. It is also paused while a directory sync is in progress. ### Roles By default, Userpilot offers four predefined roles: | **Role** | **Description** | **Access level** | | :---------------- | :----------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------ | | **Account Owner** | Automatically assigned to the first user who creates the workspace | Full access to everything, including billing and authentication settings | | **Admin** | Day-to-day administration without account-level controls | Everything except billing, authentication settings (MFA, SSO, and SCIM), and assigning the Account Owner role | | **Publisher** | Focused on content creation and publishing | Creates and publishes content, and manages users, companies, segments, events, and themes | | **Analyst** | Works with analytics and reporting | Access to reports, session replay and playlists, and feature, page, and mobile screen tagging | If SCIM is connected, roles are assigned automatically based on your identity provider’s group mappings and can’t be changed from the Userpilot UI. To update a teammate’s role, make the change in your IdP instead. #### Custom Roles You can also create **Custom Roles** (Enterprise plan only) if you need more control.\ Just click **+ Add Role**, then choose exactly which permissions to enable or restrict. Create Role panel showing permission options If you want to view or edit the permissions for a specific role, simply click on the role and then select View. View button for an existing role's permissions Userpilot’s premade roles (Account Owner, Admin, Publisher, and Analyst) can’t be edited. If you need different permissions, create a Custom Role instead, since custom roles can be edited at any time. ### How roles work with automated provisioning When teammates are created automatically, their role comes from one of three settings, depending on how they arrive: * **JIT default role.** A teammate created on their first SSO login gets the [JIT default role](/configure/team-and-roles/jit) you chose on the Authentication page. This is a starting point: a later SCIM sync can replace it with a mapped role. * **SCIM group mapping.** With [SCIM](/configure/team-and-roles/scim) enabled, teammates get the role mapped to their IdP group. A teammate in several mapped groups gets the highest-privilege role among them. * **SCIM default role.** Teammates who belong to no mapped group follow the **Individuals** row in your group mapping. Pick a role there to provision them, or choose Skip to leave them out of Userpilot. Roles assigned by a group mapping take precedence over both defaults. Whether a role you change by hand survives the next sync depends on your [role management mode](/configure/team-and-roles/scim#choosing-who-owns-roles): in the recommended hybrid setup, manual changes are kept; with strict IdP enforcement, every sync resets roles to match your IdP. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # SCIM Integration Source: https://docs.userpilot.com/configure/team-and-roles/scim Automate user provisioning and deprovisioning in Userpilot using SCIM with identity providers like Okta and Azure AD. This feature is available on the Enterprise plan and requires [SSO](/configure/team-and-roles/sso) to be enabled. ## Overview As organizations grow, managing user accounts across applications becomes complex. Adding and removing teammates, changing roles, and revoking access all take time and are easy to get wrong. SCIM (System for Cross-domain Identity Management) solves this by making your identity provider (IdP) the single source of truth. You map your IdP groups to Userpilot roles once, and Userpilot keeps teammates and their access in sync automatically. It provisions new users, updates roles, and removes people who leave. ### Use cases 1. Automatically create, update, and remove Userpilot teammates as your IdP changes. 2. Keep roles consistent by mapping IdP groups (from Okta, Microsoft Entra ID, and others) to Userpilot roles. 3. Revoke access promptly when employees leave or change teams. 4. Eliminate manual teammate management across multiple applications. ### Prerequisites 1. An Account Owner role, or a role with the Manage SCIM permission. 2. [SSO](/configure/team-and-roles/sso) configured and enabled. 3. An active subscription with a SCIM-capable IdP. 4. A Userpilot organization on the Enterprise plan. *** ## Roles in Userpilot Userpilot ships four built-in system roles that you can map IdP groups to: | Role | Access | | ----------------- | -------------------------------------------------------------------------------------------------------------- | | **Account Owner** | Full access, including billing, authentication, and SCIM configuration. | | **Admin** | Everything except billing, authentication settings (MFA, SSO, and SCIM), and assigning the Account Owner role. | | **Publisher** | Creates and publishes content, and manages users, companies, segments, events, and themes. | | **Analyst** | Reports, session replay and playlists, and feature, page, and mobile screen tagging. | You can also map groups to any custom roles you have created in an application. The Admin Console has its own role set (Admin, Billing, View Only, and Account Owner). For more on roles and permissions, see [Managing your team in Userpilot](/configure/team-and-roles/managing-your-team-in-userpilot). *** ## Enable SCIM for the organization SCIM builds on SSO. If you have not already, go to **Settings > Team > [Authentication](https://run.userpilot.io/settings/team/authentication)**, click **Enable** on the SSO card, and connect your identity provider. Set up SSO Select your identity provider SSO enabled In the **Directory sync (SCIM)** card, click **Setup SCIM** and follow your IdP's instructions for adding SCIM provisioning. Click **Map Roles** to open the mapping wizard: 1. **Add Groups.** Select the IdP groups you want to give access to the organization. Select IdP groups 2. **Map groups with application roles.** Align each IdP group with a role in each application. When you have multiple applications, you can map the same group to different roles in each one. Map groups to application roles 3. **Review changes.** Userpilot shows a preview of exactly what will happen. Nothing is applied until you confirm, and going back changes nothing. Confirm the preview to apply the mapping. Provisioning runs in the background and is durable: it survives restarts and retries automatically. When it finishes, your teammates appear under the **[Team](https://run.userpilot.io/settings/team)** page. Teammates list After SCIM is successfully configured, SSO Mandatory Login is enforced for everyone in the organization. While SCIM is enabled, SSO cannot be disabled. Disable SCIM first if you need to. ### Creating a custom role While mapping groups, you can create a new role. Click **Create Role**, enable the permissions you want, and click **Create**. The new role becomes available for mapping. Create a custom role ### Default role for unmapped groups Each application's mapping table ends with an **Individuals** row. This row covers IdP users who belong to no mapped group (and users whose groups are all unmapped). Pick a role to provision them automatically, or choose **Skip - don't add to Userpilot** to leave them out. With Skip, teammates who later leave all of their mapped groups are removed from Userpilot. Choose a role in the **Individuals** row instead if you want to keep them. You can select any application role here, including Account Owner. Since it applies to every groupless and unmapped user, pick Account Owner only when that is intended. Group mapping with the Individuals default-role row ### What if a teammate is in multiple groups? If a teammate belongs to several mapped groups, Userpilot resolves their role automatically by granting the highest-privilege role among those groups. You do not need to restrict people to a single group in your IdP. *** ## Choosing who owns roles The **Role management** cards let you decide whether your IdP or Userpilot controls teammate roles: * **Identity provider.** Your directory controls who has access and their roles. Map each group to a role, and unmapped users follow the "All other groups" default. * Leave **Strictly enforce IdP roles** off (recommended) for hybrid behavior. Roles come from your IdP groups, but any role you change in Userpilot is kept across syncs. * Turn **Strictly enforce IdP roles** on for fully provider-owned behavior. Every sync replaces all roles to match your IdP, overwriting changes made in Userpilot. * **Userpilot.** SCIM provisions and removes users but never changes roles. You manage every teammate's role in Userpilot. Role management mode cards: Identity provider and Userpilot, with the Strictly enforce IdP roles option Whenever SCIM is active, inviting or importing teammates directly in Userpilot is disabled in every role-management mode, not only when the identity provider owns roles. Teammate membership comes from your IdP. Role management is separate: manual role edits are still allowed in hybrid and Userpilot modes, as described above. *** ## Syncing users Use **Sync Users** on the Authentication page to re-sync all mapped groups on demand. Before anything is applied, a preview shows exactly what will change, grouped by application: * **Will be added.** New teammates and their roles. * **Role changes.** The current role and the new role. * **Not applied (kept as-is).** Memberships that are skipped, with the reason. * **Not found in your IdP.** Listed for information only. A manual sync never removes anyone. Removals happen only when you re-map. Confirm the preview to apply the changes. SCIM change preview showing additions, role changes, and removals before they are applied *** ## Real-time directory events Once SCIM is set up, Userpilot stays in sync with your IdP in real time by listening to directory events: | Event | What Userpilot does | | ----------------------------- | --------------------------------------------------------------------------------------------------- | | **User added to a group** | Provisions the teammate, or updates their role, for the mapped application. | | **User removed from a group** | Removes the teammate from that application if they are no longer in any mapped group. | | **User updated** | Updates the teammate's profile. | | **User deleted** | Removes the teammate from the organization. | | **Group created** | Surfaces the new group so you can map it. A banner on the Team page notifies admins of IdP changes. | | **Group deleted** | Removes the group and its mapping. | Group-change banner These events are processed durably and idempotently. Each event is queued and retried until it succeeds, so nothing is lost on a restart, and Userpilot reconciles against the current directory state. This means that out-of-order or duplicate deliveries always converge to the correct result. For example, a "removed" and an "added" event that arrive in the wrong order during a role change still resolve correctly. Directory events take effect only after you complete the initial group mapping. While SCIM is connected but not yet mapped, changes in your IdP do not add, remove, or re-role anyone in Userpilot. The last remaining Account Owner is always protected and is never removed by a sync. *** ## Audit log Every provisioning action is recorded in the organization's access logs, alongside sign-ins, invites, and role changes, with one entry per change. You can filter by Source (Web app, SCIM provisioning, SSO sign-in, CSV import) and Activity (Member provisioned, Member deprovisioned, Changed a member's role, Role sync skipped (set manually), plus sign-in, 2FA, and SSO events), and search by teammate. Each entry shows the teammate, the role before and after, who triggered it, the application, and the reason. See [Access and activity logs](/configure/team-and-roles/access-and-activity-logs) for more. ### When a sync fails If a provisioning run fails, the Authentication page surfaces the error and the SCIM card shows a failure banner. Provisioning is durable and retries automatically, so transient failures usually clear on their own; you can also re-run **Sync Users** or re-map your groups to recover. Retrying removes no teammates. *** ## Disable SCIM Disabling SCIM has the following effects: 1. SCIM configuration and all group mappings are removed from Userpilot. 2. The connection to your IdP directory is disconnected. 3. Manual teammate management is unlocked again. 4. Teammates already provisioned through SCIM keep their access. 5. SSO Mandatory Login remains enforced. **Important.** While SCIM is enabled, teammates created through your IdP have no password. If you later disable SSO, those teammates lose access until they set a password, and they receive an email guiding them to do so. SCIM must be disabled before SSO can be disabled. ## FAQs No. The last remaining Account Owner is always protected and is never removed by a sync, even if their IdP group changes. It depends on your role-management mode. In hybrid mode (Identity provider selected, strict enforcement off), manual role edits survive syncs. With Strictly enforce IdP roles on, every sync overwrites roles to match your IdP. In Userpilot mode, SCIM never touches roles. Userpilot grants the highest-privilege role among their mapped groups. You do not need to limit teammates to a single IdP group. [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # SSO Source: https://docs.userpilot.com/configure/team-and-roles/sso Enable Single Sign-On (SSO) in Userpilot to let users authenticate securely with a single set of credentials via Okta, Azure, Google, or other identity providers. This feature is available on the Enterprise plan. ### Overview Single Sign-On (SSO) lets a user authenticate once, with a single set of credentials, across several related but independent systems. When SSO is enabled, your team signs in to Userpilot through your identity provider (IdP) instead of a separate Userpilot password. Userpilot's SSO supports more than 12 identity providers across both SAML and OIDC, including Okta, Microsoft Entra ID (Azure AD), Google, OneLogin, and Ping. You connect your IdP once, and your team signs in securely from then on. ### Requirements * An active Userpilot subscription on the Enterprise plan. * An Account Owner role, or a role with the Manage SSO permission. * A third-party identity provider, such as [Okta](https://www.okta.com/), [Microsoft Entra ID](https://azure.microsoft.com/en-us/products/active-directory), or [Google](https://cloud.google.com/architecture/identity/single-sign-on). ### Where to configure SSO All authentication settings are under **Settings > Team > [Authentication](https://run.userpilot.io/settings/team/authentication)**. From this page you can enable SSO, require SSO for everyone, and, once SSO is on, set up [Just-in-Time provisioning](/configure/team-and-roles/jit) and [SCIM directory sync](/configure/team-and-roles/scim). Organization authentication page showing SSO, JIT, and SCIM If your Userpilot instance has access to the Admin Console, you can also manage these settings on the [Admin Console's Authentication page](https://run.userpilot.io/admin-console/team/authentication), under Team. ## Enabling Single Sign-On Confirm you have an Account Owner role (or the Manage SSO permission), then go to **Settings > Team > Authentication**. In the **Single sign on (SSO)** card, click **Enable**. Userpilot opens the SSO setup portal in a new window. In the setup portal you will: 1. Add and verify the email domains your team signs in with, such as `acme.com`. Domain verification is what lets Userpilot route each teammate to the right IdP. 2. Choose your protocol (SAML or OIDC) and identity provider. 3. Follow the provider-specific steps to finish the connection. Once the connection is active, Userpilot marks SSO as enabled and stores your provider and connection type. The Authentication page shows **Current SSO Provider** with your connection. SSO enabled You configure the actual IdP (Okta, Entra, and so on) in the setup portal, not inside Userpilot. Userpilot stores only the connection reference and never sees your users' IdP passwords. ## Signing in with SSO Userpilot supports both sign-in started from Userpilot and sign-in started from your identity provider. On Userpilot's sign-on form, choose **Continue with Enterprise SSO** and enter your work email. Userpilot detects your domain, finds the matching connection, and redirects you to your IdP to authenticate. If your IdP shows a Userpilot tile (an IdP-initiated login), opening it signs you in directly. Newly created teammates land in your organization's default application. **New teammates without an account yet.** If a teammate does not have a Userpilot account, sign-in normally fails. They must first be invited, [imported via CSV](/configure/team-and-roles/csv-import), or synced through [SCIM](/configure/team-and-roles/scim). To create accounts automatically on first SSO login instead, enable [Just-in-Time (JIT) provisioning](/configure/team-and-roles/jit). ## Require SSO (SSO Mandatory Login) You can make SSO the only way your team signs in. On the **Single sign on (SSO)** card, turn on **Require all teammates to sign in with SSO**. When enforcement is on: * Password login is disabled for everyone in the organization. Teammates who used a password must sign in with SSO from then on. * Teammates created by SCIM or JIT are created without a password. When SCIM is enabled, SSO enforcement is applied automatically and cannot be turned off on its own, and SSO cannot be disabled while SCIM is enabled. Disable SCIM first if you need to change these settings. To turn enforcement off, switch **Require all teammates to sign in with SSO** off. Teammates who were passwordless receive an email with instructions to set a password so they can sign in without SSO again. ## Disabling or deleting SSO The **Single sign on (SSO)** card offers two actions: * **Disable** turns SSO off but keeps your SSO connection so you can re-enable it later. Disabling SSO also turns off JIT provisioning, because JIT only runs during SSO sign-in. * **Delete SSO Configuration** removes the SSO connection entirely. JIT settings, including the default role, are cleared as well. Neither action is available while SCIM is enabled, so disable SCIM first. Teammates who were created without a password (through SCIM or JIT) lose access if SSO is removed. They receive an email with instructions to set a password and regain access. ## FAQs Userpilot supports more than 12 providers across SAML and OIDC, including Okta, Microsoft Entra ID (Azure AD), Google, OneLogin, and Ping. You choose and configure your provider in the SSO setup portal. Yes. Both [SCIM directory sync](/configure/team-and-roles/scim) and [JIT provisioning](/configure/team-and-roles/jit) build on SSO and require it to be enabled first. Password login is disabled for the organization. If you later turn enforcement off, passwordless teammates receive an email with a link to set a password. [**For any questions or concerns please reach out to support@userpilot.com**](mailto:support@userpilot.com) # Get started Source: https://docs.userpilot.com/configure/themes-and-design-library/get-started Get started with Userpilot Themes and Design Library to create brand-aligned, consistent in-app experiences across modals, tooltips, banners, surveys, and more. ## Overview Userpilot enables you to deliver in-app experiences that not only work for your users but also look and feel like an extension of your brand. Through its **Themes** and **Design Library** features, Userpilot gives you advanced and highly flexible options to ensure every modal, tooltip, banner, survey, or email you create is fully aligned with your design system, brand personality, and UI guidelines. Below is a detailed overview of how these features work and how you can use them to maintain brand consistency across all your in-app experiences. ## Themes: Systematic, brand-aligned styling Userpilot's Themes system acts as the master style guide for your in-app content. A theme is a set of shared styling rules that automatically apply to all your Userpilot content (flows, spotlights, banners, emails, checklists, etc.) for a consistent user experience. Modals (2).png ## Design Library: Your single source of styling truth The Design Library is built to give you and your team maximum flexibility and control over your in-app content style. It lets you organize design tokens into groups for easy management and supports a wide range of options you can define and reuse later from your themes, Chrome Extension, or when building custom themes for in-app experiences like surveys, checklists, or the Resource Center. colors (5).png ## Best practices for Userpilot themes and design library Here’s how to get the most out of these features: * **Map your brand system first**: Collect your color palette, typography rules, spacing standards, and assets. * **Create multiple themes if needed**: For example, one theme for light mode, another for dark mode, or create your own custom one. * **Use the design library to enforce consistency**: Don’t rely on ad hoc color picking; use saved tokens. Users on any paid plan can access Themes and create multiple themes to match their brand. However, the Design Library is available exclusively to Enterprise plan users. Users on the Growth or Starter plan will need to upgrade to Enterprise to unlock this advanced flexibility and fully transfer their design system into Userpilot. # Set up a design library Source: https://docs.userpilot.com/configure/themes-and-design-library/set-up-a-design-library Set up a Design Library in Userpilot to centralize brand styles, reuse approved design tokens, and maintain consistent, on-brand in-app experiences at scale. ## Overview The Design Library works as a powerful extension to the theme system, giving users more dynamic and flexible options to bring their company’s design system, crafted by the design team, into Userpilot content seamlessly. The idea is similar to how design teams organize and manage styles in Figma. Just like in Figma, where teams define and reuse components such as typography, colors, spacing and sizes, shadows, and assets, the Design Library provides a centralized place in Userpilot to set up these elements. You can create groups of styles that your team can consistently use across all Userpilot content, including the Chrome Extension, Checklists, Resource Center, NPS, and Surveys. This ensures your in-app experiences always feel cohesive and on-brand without needing to manually adjust styles every time. By setting up your Design Library, you give your entire team easy access to approved, reusable design tokens, making it faster and easier to maintain visual consistency, brand integrity, and a polished user experience at scale. With this approach, your Userpilot content isn’t just functional, it becomes a true extension of your product’s design system, mirroring the same careful planning and detail your team puts into your primary design tools. If you're on the **Enterprise plan**, you'll have access to the **Design Library** by default. Users on the **Starter** plan will need to **upgrade to Enterprise** or **Growth** to unlock this feature and start building their design library, giving them greater flexibility and control over their content styles. ## Use cases * **Brand consistency:** ensure all in-app messages follow approved colors, fonts, and spacing for a unified look. * **Centralized management:** update design tokens in one place and apply changes across all Userpilot content. * **Team collaboration:** give teams access to shared, brand-approved styles for easy, consistent creation. * **Faster creation:** save time by reusing pre-defined style groups instead of manual styling every time. * **Multi-brand support:** manage separate style groups for different brands, products, or regions. * **Cross-channel consistency:** apply the same design tokens to Chrome Extension, Checklists, Resource Center, and NPS. ## **How to create a design library** The Design Library lets you organize your design tokens into Groups for easy reuse. You can create Groups for Colors, Typography, Spacing & Sizes, Shadows, and Assets. You can start creating your theme by navigating to [Configure > Themes](https://run.userpilot.io/themes) from settings icon. themes-location Click on **Design Library** to begin adding your design style groups to your design library. design-library-location When you click on the Design Library button, you'll see several tabs at the top of the screen, including: * **Colors** * **Typography** * **Spacing & Sizes** * **Shadows** * **Assets** Choose the tab you want (e.g., Colors, Typography) design-library To begin adding your design system styles, simply click on **Create Group**. create-group Then a **side panel** will open where you can start adding styles that match your **design system,** and then enter a **Group Name** and add your items. create-group-1 You can add an unlimited number of items by clicking the “Add” button. Once you've finished adding your types, simply click **Create** to save your changes. example ## Design library tabs explained ### **Colors** * Use Groups to organize color tokens by theme (e.g. Primary, Grayscale, Status). * Define color names and HEX values. colors ### **Typography** * Use Groups to save font styles (e.g. Headings, Body). * Define font family, weight, size, and line height. typography ### **Spacing & Sizes** * Use Groups to save spacing scales or size presets. * Define pixel or rem values. spacing-and-sizes ### **Shadows** * Use Groups to save shadow presets. * Define offset, blur, color, and opacity. shadows ### **Assets** * Use Groups to organize images, logos, or icons. * Upload and categorize assets. assets After setting up your design library, you can use these **token groups** throughout your Userpilot **content**, including the **Theme**, **Chrome Extension**, **Resource Center**, **Emails**, **Mobile content**, etc., to ensure a **consistent** and **unified experience** and **reduce creation time** by simply selecting **predefined styles**. example-on-content-builder The design library currently supports the web app themes and content. We’ll expand its capabilities to include the mobile app theme and content next. For any questions or concerns, please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Set up a mobile app theme Source: https://docs.userpilot.com/configure/themes-and-design-library/set-up-a-mobile-app-theme Set up a mobile app theme in Userpilot to customize colors, fonts, and buttons, ensuring consistent, on-brand mobile experiences across devices. ## Overview Userpilot makes it easy to customize your mobile content theme so your mobile experiences look and feel consistent on any device. You can control colors, fonts, and button styles, ensuring your brand remains cohesive and professional across all operating systems. With these flexible styling options, you can deliver a seamless, on-brand experience without needing to manually adjust each guide for mobile users. ## **How to create a mobile theme** You can start creating your theme by navigating to [Configure > Themes](https://run.userpilot.io/themes) from the sidebar. 2. Select Email from the list of items (4).png 2. Select Email from the list of items (4).png You'll see two tabs, Web and Mobile, allowing you to customize your theme for each supported platform. To get started, simply click on **Mobile,** then **Create Theme,** and begin designing your custom theme mobile (2).png Userpilot provides default Light and Dark themes to help you get started quickly. You can start creating your theme by giving it a **clear**, **memorable name** to help you **organize** and **easily find** it when building your Userpilot content. Userpilot will also use the **primary color** you choose as the **foundation** to help **customize** your theme automatically. mobile (3).png ## Carousels and Slideouts tabs The Carousel Theme in Userpilot lets you fully customize the appearance of your mobile carousels so they match your brand and deliver a seamless, engaging user experience on mobile devices. This ensures your onboarding and feature tours feel consistent with the rest of your app. Sections in the carousel include: * **General:** set the font family and content alignment to ensure text displays clearly and aligns properly on mobile screens. * **Color:** choose the background color, title color, and text color to match your brand’s palette for a consistent look. * **Button:** customize the background color, label color, border color, border width, and border radius to keep buttons on-brand and easy to interact with. * **Dismiss Carousel:** adjust the color and icon color for the dismiss button to make exiting the carousel clear and consistent with your design. * **Progress:** set the progress indicator color to align with your brand and provide users with clear visual feedback on their place in the carousel. * **Slideouts only - Backdrop:** set the backdrop color and opacity to create focus by dimming the background when the slideout is active. Carousels (1).png Slideout (1).png ## Surveys tab The Mobile Survey Theme allows you to customize the look of your surveys on mobile screens, giving you control over colors, fonts, progress indicators, and backdrops so your surveys stay on-brand and easy for users to navigate. * **General:** set the background color, primary color, corner radius, and survey position on mobile screens to match your brand and control layout. * **Font:** choose the font family and text color to ensure readability and consistent typography on mobile devices. * **Progress Bar:** select the progress type and set its color to guide users visually through multi-step surveys. * **Backdrop:** define the backdrop color and opacity to focus user attention by dimming the background behind your survey. Surveys (1).png You can view your changes in both **iOS** and **Android** layouts by clicking the icons above the mobile mockup in the preview area. This lets you see exactly how your designs will look on each platform. Font family is set by default to **“System Default”**, which Userpilot automatically maps to **San Francisco on iOS and Roboto on Android**. If you want to use your own brand font instead, you can easily upload it using the Upload Custom Font option. **General notes:** * Your Userpilot account must always have one **default theme** to use when creating content, but you can change it anytime. * The **default theme can’t be deleted**. * To delete the current default theme, first set another theme as the default, then you can remove the one you no longer want. * If you’ve created content using a specific theme, you can’t delete that theme until you **unlink all content** by changing its theme assignments. * You can view all content linked to a theme using the **“View content using this theme”** option in the theme’s action menu. Screenshot 2025-06-29 at 22.29.44 (3).png * You can **duplicate**, **rename**, and **update** themes anytime. * Click the **“Save”** button to keep your changes, since the theme page doesn’t autosave like other areas in Userpilot. ## FAQs No. Themes are platform-specific, the Themes page has separate **Web** and **Mobile** tabs, and a mobile theme only applies to mobile content (carousels, slideouts, surveys). You'll need to create and customise them independently. For any questions or concerns please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Set up a web app theme Source: https://docs.userpilot.com/configure/themes-and-design-library/set-up-a-web-app-theme Set up a web app theme in Userpilot to customize colors, fonts, and UI styles, ensuring consistent, brand-aligned in-app experiences. ## **Overview** Userpilot allows you to customize your theme to match your brand’s identity effortlessly. You can control colors, fonts, button styles, and other design elements to ensure a consistent user experience. With flexible styling options, you can maintain brand consistency across all in-app experiences without needing constant design updates. ## **How to create a theme** You can start creating your theme by navigating to [Configure > Themes](https://run.userpilot.io/themes) from the settings icon on the top-right side. Image You'll see two tabs, Web and Mobile, allowing you to customize your theme for each supported platform. To get started, simply click on **Web,** then on **Create Theme,** and begin designing your custom theme. Image Userpilot provides default Light and Dark themes to help you get started quickly. You can start creating your theme by giving it a **clear**, **memorable name** to help you **organize** and **easily find** it when building your Userpilot content. Userpilot will also use the **primary color** you choose as the **foundation** to help **customize** your theme automatically. Image ## General Through the General tab, you have a centralized location to apply changes across all theme elements, including flows, spotlights, banners, checklists, emails, and surveys. If you'd like to customize settings for a specific feature, simply navigate to that feature and apply custom style settings. These changes will apply only to that feature and will override the settings in the General tab. General (2).png The General tab includes multiple sections that provide advanced options to help you customize your content and ensure it matches your design system, such as: * **Container:** Set the background color and z-index for your content container to control layering and base styling. * **Font:** Choose the default font family and font color to ensure text matches your brand’s typography guidelines and meets accessibility contrast requirements. * **Link:** Customize link color and hover color, and choose whether links open in a new browser tab for better user control and clarity. * **Box & Border:** Adjust border type, shadow, and corner radius to style your content’s container with depth and rounded edges. * **Progress Bar:** Configure the progress bar for Flow UI patterns with a group of steps, setting its type, color, padding, and position to guide users clearly through multi-step experiences. * **Backdrop:** Set the backdrop color and opacity to create focus and separation from the underlying UI when displaying overlays. * **Close button:** Customize the icon, size, color, hover states, background, and position of the close button to ensure it aligns with your brand and is easy for users to find. **Useful terms to know** * **Z-index** Z-index decides which elements appear on top of others on your screen. Think of it like stacking sheets of paper; whatever has a higher z-index is on top of the pile and will be visible above other parts of your app. * **Why use it?** When you set the z-index in Userpilot, you make sure related content like modals, banners, or checklists don’t get hidden behind your app’s content. It helps keep your messages clear and easy for users to see. ## **Customizing Your Font** To customize your content’s font, search for the **Font** section and click the drop-down menu. Choose **Custom** and select **Add New Custom Font**. Screenshot 2025-06-29 at 22.16.09 (1).png A pop-up will appear where you can name your Font Family. The Custom CSS will be pre-filled in *comment* mode (with slashes), so it won't be active yet. Screenshot 2025-06-29 at 22.17.53 (1).png To activate the CSS, simply remove the slashes (/) and then click the **Add Font** button. ## Button styles Through the Button Styles tab, you can create multiple button styles tailored to your use cases and design system. This saves time by eliminating the need to customize button settings each time you create content in Userpilot. Your saved styles will always be ready to use whenever you build content in flows, banners, emails, and surveys. buttons (4).png To create a new button style, click **Create Button**, and Userpilot will then add a new section where you can fully customize your button’s appearance to match your brand. buttons (5).png The Button section has lots of options to help you style your buttons so they match your design system, like: * **Background color:** Set the button’s default color to match your brand palette. * **Background color on hover:** Choose the color the button changes to when hovered for clear interactive feedback. * **Text color:** Define the label color for strong readability and brand consistency. * **Text color on hover:** Customize the label color when hovered to maintain contrast and visibility. * **Default state contrast ratio:** Check accessibility contrast between background and text in the default state. * **Hover state contrast ratio:** Verify accessibility contrast in the hover state for better usability. * **Padding:** Control the internal spacing to ensure balanced and comfortable button labels. * **Corner radius:** Adjust the roundness of the button’s corners to match your design system. * **Typography:** Select the font style and weight to keep buttons consistent with your brand’s typography. * **Border:** Enable or disable borders and define their style for outlined or solid button designs. * **Border color:** Set the border color for the button’s default state to align with your palette. * **Border color on hover:** Choose the border color when hovered to enhance interactive feedback. * **Border thickness:** Define the border width for subtle or bold visual effects. To save time, create a primary button style, then duplicate it and tweak the colors for your secondary button if they share a similar design. ## Flows Under the Flows tab, you’ll find a variety of options for customizing each Userpilot UI pattern to match your design system. We know that small design details can make a big difference in user experience and engagement, so Userpilot gives you the flexibility to fine-tune even the finer points to make your content more visually appealing and on-brand. The available UI pattern tabs include: * **Modals** * **Slideouts** * **Tooltips** * **Driven Actions** Each UI pattern has its own customization options and sections similar to the general settings shown here (like background color, font, box & border, progress bar, backdrop, buttons, and close button). This consistent structure makes it easy to apply cohesive styles across all your in-app flows while tailoring details for each pattern. Feel free to explore each tab to unlock maximum customization and deliver a polished, engaging user experience. Modals (3).png ## Spotlights Under the Spotlights tab, you can customize your in-app spotlight experiences to perfectly match your brand and design system. The Spotlights tab is split into two subtabs: * **Native Tooltips & Hotspots** * **General:** Customize background color, content alignment, z-index, and padding for consistent positioning and layering. * **Box & Border:** Set border type, shadow, and corner radius to match your brand’s depth and shape standards. * **Badge:** Configure icon, shape, size, opacity, fill colors (default and hover), and border styles to draw attention to hotspots without clashing with your design system. * **Label:** Style the text container of tooltips by adjusting background and hover colors, font settings, padding, border, and corner radius, with built-in contrast checking for accessibility. * **Hotspot:** Define hotspot color, size, animation type, and behavior (like pulse animation) to make it stand out without being distracting. Native tooltips (1).png * **Buttons** * **General:** Set background and hover colors, padding, corner radius, and z-index for button placement. * **Font:** Choose text color and hover color, typography, and ensure accessibility with built-in contrast ratio checks. * **Border:** Customize border type, shadow or solid, color, and corner radius to match your design system perfectly. ## Embeds The Embeds tab lets you customize in-app notification for both Banners and Cards to match your brand and design system, ensuring important messages look polished and consistent. Banners & Cards style sections: * **General:** Set background color, font color, z-index, and position, with contrast checks for accessibility. * **Box & Border:** Customize border style, width, shadow, corner radius, and choose full-width or container layout. * **Buttons:** Style the primary button with options for background and hover colors, text colors, padding, corner radius, typography, and borders, all with contrast checks. * **Close Button:** Adjust icon, size, background and hover colors, corner radius, position, icon color, and default behavior. Image ## Checklists The Checklists tab lets you fully customize the look and feel of your in-app task lists to match your brand, making onboarding experiences clear, engaging, and consistent. It’s divided into two subtabs: * **Widget** * **General:** Set header, background, progress, carets, CTA, and completion colors, with an option to auto-open the widget for smoother onboarding. * **Text:** Customize font family and header/body font colors with contrast checks for clear, accessible reading. * **Minimize Button:** Style the caret and close icons with control over colors, hover states, size, and corner radius to match your brand. widget (1).png * **Beacon** * Select beacon type (icon in circle, square, text only, or icon & text). * Set color, background color, position on the page, and z-index. * Adjust position easily for perfect placement in your app layout. beacon (1).png ## Surveys The Surveys tab lets you customize the look and feel of your in-app surveys to keep them consistent with your brand and visually engaging for users. * **General:** Set primary color, background color, and position to control where your survey appears and ensure it matches your brand. * **Box & Border:** Customize border type, shadow color, and corner radius \*\*\*\*to style the survey container consistently. * **Font:** Choose font family and text color, with contrast checks to keep text clear and accessible. * **Progress Bar:** Select progress type and set the bar color to visually guide users through multi-step surveys. * **Backdrop:** Define color and opacity to create focus by dimming the background behind your survey. * **Close Button:** Style the close icon with background and hover colors, icon color, size, and corner radius for a polished, on-brand look. Screenshot 2025-06-29 at 21.55.59 (1).png **Note** If you're on the Enterprise plan, you get even more flexibility with your themes by using the Custom CSS tab and the [Design Library](https://docs.userpilot.com/configure/themes-and-design-library/set-up-a-design-library). Once you've set up your Design Library, you'll see extra options under colors, font family, and spacing, letting you either choose from pre-defined library groups or customize styles on the spot with the custom option. buttons (7).png **General notes:** * Your Userpilot account must always have one **default theme** to use when creating content, but you can change it anytime. * The **default theme can’t be deleted**. * To delete the current default theme, first set another theme as the default, then you can remove the one you no longer want. * If you’ve created content using a specific theme, you can’t delete that theme until you **unlink all content** by changing its theme assignments. * You can view all content linked to a theme using the **“View content using this theme”** option in the theme’s action menu. Screenshot 2025-06-29 at 22.29.44 (2).png * You can **duplicate**, **rename**, and **update** themes anytime. * Click the **“Save”** button to keep your changes, since the theme page doesn’t autosave like other areas in Userpilot. For any questions or concerns please reach out to [**support@userpilot.com**](mailto:support@userpilot.com) # Theme Switching Source: https://docs.userpilot.com/configure/themes-and-design-library/switching-themes Learn how to switch themes like light and dark mode in Userpilot using userpilot.theme() to match your app UI in real time. ### Overview Theme Switching in Userpilot allows you to dynamically adapt in-app experiences, such as modals, tooltips, banners, and checklists, to match your application’s active theme (for example, light mode or dark mode). This is especially useful for products that support multiple visual themes and want Userpilot content to feel native, consistent, and seamless within the host application. By using the `userpilot.theme()` function, you can control which theme Userpilot uses at runtime, ensuring that content shown in live mode always aligns with your product’s UI state. ### Use cases * **Light/Dark mode support:** When your application allows users to toggle between light and dark modes, Userpilot content should adapt automatically to avoid visual clashes or accessibility issues. * **Brand or tenant-based theming:** For multi-tenant or white-labeled products, different customers may use different brand themes. Theme Switching ensures the right Userpilot theme is applied per tenant or account. * **Improved accessibility and readability:** Ensuring correct contrast, background, and typography based on the theme improves usability and WCAG compliance. ### How theme switching works in Userpilot Userpilot supports theme control via a JavaScript API method, `userpilot.theme()`. This method tells Userpilot which theme should be active so that all live content (flows, tooltips, banners, etc.) renders using the correct theme styles. Important: Theme switching affects **content shown in live mode**. It does not change your app’s theme, only how Userpilot content is displayed. ### How to switch between themes for live content 1. First, make sure you have created the relevant themes (e.g. `light`, `dark`) in your Userpilot theme settings. 2. Your application should already know which theme is active (for example, from user preferences, system settings, or a global state). 3. When the theme changes (or on initial page load), call the Userpilot API with the appropriate theme name: ```javascript theme={null} userpilot.theme('dark'); ``` or ```javascript theme={null} userpilot.theme('light'); ``` 4. Once set, any Userpilot content that appears in live mode will automatically render using the selected theme, without needing to reload the page or re-trigger flows. * You can dynamically change the primary color of a theme using `userpilot.theme({ primary: "PRIMARY_COLOR" })`. This allows you to customize the primary color per user or account without the need to create and maintain 20+ separate themes. It’s especially useful for applications that support color customization or white-labeling. * You can disable the applied theme at any time by calling `userpilot.theme(0)`. This stops the selected theme from rendering on live Userpilot content without needing a page reload or flow re-trigger. ### Applying themes to the Resource Center Resource Center and NPS surveys don’t have their own dedicated Userpilot themes, so they don’t automatically adapt when you call `userpilot.theme()`. Currently, you can adapt Resource Center content to your active theme by passing a second argument with a `resource_center_schema` matching your theme name: ```javascript theme={null} userpilot.theme('dark', { resource_center_schema: 'dark' }); ``` This adds a `[data-app-theme="dark"]` attribute you can use to scope your custom CSS, prefixing it before your existing Resource Center element selectors. For example: ```css theme={null} [data-app-theme="dark"] #navigation-bar, [data-app-theme="dark"] #userpilot-resource-centre, [data-app-theme="dark"] #widget-headers { /* your dark-mode styles */ } ``` ### Best practices 1. Call `userpilot.theme()` early in your app lifecycle (e.g. after user login or app initialization) 2. Re-call the method when the theme changes, especially if users can toggle themes at runtime 3. Keep theme naming consistent between your app and Userpilot (e.g. `light`, `dark`, `high-contrast`) 4. Test in live mode, not just previews, to ensure the behavior matches real user experiences [For any questions or concerns please reach out to **support@userpilot.com**](mailto:support@userpilot.com) # Mobile Event Auto-Capture Source: https://docs.userpilot.com/data-events/autocapture/mobile-events-autocapture Automatically capture supported mobile user interactions with the Userpilot SDK without manual event instrumentation. Mobile event auto-capture allows Userpilot to automatically collect supported user interactions inside your mobile app, without requiring developers to manually instrument every event. Once enabled, Userpilot starts capturing common interactions such as taps, text changes, and screen views, giving your team a foundation of behavioral data from day one. ## Overview With mobile event auto-capture, the Userpilot SDK listens for supported native interactions and records them automatically as raw events. These raw events can then be labeled in Userpilot to turn them into named, trackable events, ready to use in analytics, reports, segments, and mobile experiences. This differs from manual event tracking, where developers write a tracking call for each individual event. Auto-capture removes that overhead for common interactions, while labeling gives your team control over which raw events matter and what they should be called. Auto-capture is enabled at the SDK level using two flags: ```swift theme={null} // iOS enableScreenAutoCapture() enableInteractionAutoCapture() // Android enableScreenAutoCapture = true enableInteractionAutoCapture = true ``` ## Use cases 1. **Understand how users interact with key mobile screens:** see which elements users tap, change, or engage with, without pre-defining every event 2. **Build reports based on common mobile interactions:** use auto-captured events as the basis for funnel, trend, or engagement reports 3. **Create segments based on mobile behavior:** group users by the interactions they've completed, such as tapping a specific button or reaching a particular screen 4. **Reduce the need for manual event instrumentation:** cover a broad set of interactions automatically, so engineering effort can focus on more complex or custom tracking needs 5. **Identify drop-offs or friction points in mobile journeys:** spot where users stop interacting or abandon a flow by reviewing which events fire and which don't ## How mobile event auto-capture works After installing and configuring the Userpilot mobile SDK, auto-capture begins collecting raw interaction data in the background. Here's the general flow: 1. **Install or update the Userpilot mobile SDK** and enable auto-capture using the SDK flags above 2. **Userpilot starts collecting raw events** - supported interactions across your app are captured automatically 3. **Raw events appear in Userpilot** - navigate to [Data → Explore raw events](https://run.userpilot.io/events/explore-raw-events?tab=mobile) to review what has been captured Screenshot 2026 06 03 At 22 31 02 4. **Label raw events** A **Mobile Labeled Event** turns a raw, auto-captured interaction into a named, trackable event. You define it in a right-hand slideout with two tabs: **Details** and **Targeting**. **Targeting** The **Targeting** tab contains two independently toggle-able blocks - **iOS** and **Android**. A single labeled event can target one platform or both. The platform you originally captured the event on is shown first and comes pre-filled. For each enabled platform, you define three things: **Screen:** where the event fires. Choose *Any Screen* (anywhere in the app) or *Specific Screen* (constrained by conditions like `screen_name equals "Cart"`). **Event properties:** the element's fingerprint. These identify the specific element and determine whether an interaction matches this event. The available properties differ between iOS and Android, but the strongest identifiers are available on both: 1. **Hierarchy** - the element's structural position on screen; reliable on its own 2. **Target class** - the element's native UI class or type 3. **Element ID** - Accessibility identifier (iOS) or Full resource ID (Android); the most precise match when present 4. **Accessibility label** - the element's accessibility text Each platform also exposes additional properties - for example, *Owner target class* and *Target view name* on iOS; *View tag* and *Target view class* on Android - plus action-specific properties like *Placeholder* (text changes), *Tab name* (selections), and *Dialog title* (presented views). You don't need to enable all properties. Hierarchy, Target class, and the platform's ID, when available, are usually enough to identify the element. Additional properties are available under **Advanced filters** and should only be added when you need to disambiguate further, such as for list rows or two controls that differ only by label. Enabling too many properties makes the event too strict and can cause valid interactions to be missed. At least one property is required. Screenshot 2026 06 03 At 22 57 48 **Text Contains (optional):** matches the element's visible text using *Contains* or *Equals* - useful when identical elements differ only by label, for example, *"Add to Cart"* vs *"Remove"*. Screenshot 2026 06 03 At 22 58 47 ### Importing from raw events You can label the event for Android, iOS, or both by enabling each OS toggle. To make this easier, Userpilot offers an option to view captured events from the other OS that match the selected attribute from the original event. You can then select the matching event and import its values to track the same interaction across Android and iOS as one labeled event. Screenshot 2026 06 07 At 15 40 29 Screenshot 2026 06 07 At 15 41 56 ## Supported interaction types The following interaction types are captured automatically when auto-capture is enabled: | Interaction category | Interaction type | Meaning | | :------------------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------ | | Tapped | Tap | The user tapped/clicked on an element, such as a button, card, icon, link, or menu item | | Changed text | text field changed | The user entered, edited, or deleted text inside an input field, such as search, email, name, comment, or password fields | | Changed selection | radio button selected | The user selected one option from a set of radio buttons. Usually only one option can be selected at a time | | Changed selection | chip selected | The user selected a chip/tag/pill-style option, such as a filter, category, or quick choice | | Changed selection | list item selected | The user selected an item from a list, such as choosing a country, user, product, or setting | | Changed selection | spinner selected | The user selected an option from a dropdown/spinner menu. Common in Android forms | | Changed selection | tab host selected | The user selected a tab inside a tab container or tab host. Usually used when switching between sections | | Changed selection | tab selected | The user tapped a specific tab, such as Overview, Settings, Analytics, etc | | Changed selection | menu item selected | The user selected an item from a menu, overflow menu, or contextual menu | | Changed value | switch changed | The user turned a switch on or off. Example: enabling notifications | | Changed value | checkbox selected | The user checked or unchecked a checkbox. Often used for multi-select options or consent | | Changed value | toggle button selected | The user selected or toggled a button that has an active/inactive state. Similar to a switch but often styled as a button | | Changed value | slider changed | The user changed a slider value, such as volume, price range, percentage, or brightness | | Changed value | date picker changed | The user selected or changed a date from a date picker | | Changed value | time picker changed | The user selected or changed a time from a time picker | | Presented view | view presented | A screen, modal, bottom sheet, dialog, or view became visible to the user | Screenshot 2026 06 03 At 22 47 41 ## Viewing and using auto-captured events 1. Once events are labeled, they are available across Userpilot for analysis and targeting. You can use labeled mobile events in: 2. **Reports** - build funnels, trends, or engagement reports based on specific mobile interactions 3. **Segments** - group users by whether they have or haven't completed a particular interaction 4. **Mobile experiences** - trigger in-app experiences when a user performs a specific action, such as tapping a button or reaching a particular screen To review your labeled mobile events, navigate to [Events → Overview](https://run.userpilot.io/events/overview), then filter the data by selecting **Mobile** from the platform filter. Screenshot 2026 06 03 At 23 07 55 The availability of auto-captured events in reports, segments, and experiences may depend on the mobile SDK version and platform support. Check with your engineering team to confirm your current setup. Use the technical setup guides below to enable Mobile Event Auto-Capture in your app: * [iOS auto-capture setup](/developer/installation/mobile/ios/auto-capture) * [Android auto-capture setup](/developer/installation/mobile/android/auto-capture) # Raw Events Source: https://docs.userpilot.com/data-events/autocapture/raw-events Userpilot can automatically capture events using the raw events auto-capturing feature, which captures events like Clicks, Text Inputs, and Form Submissions. ### Overview Userpilot's raw events auto-capture automatically captures Clicks, Text Inputs, and Form Submissions, so you don't need to visually label events with the Chrome extension; you can label them directly from the auto-capture events page. It starts collecting data the moment auto-capture is enabled, reflected in Userpilot in real time. Auto-capture powers advanced segmentation, content triggering, and analytical reporting, letting nontechnical teams (product and UI/UX) and even stakeholders make data-driven decisions. ### Use Cases * Surface your most interacted-with features by occurrence count, then easily flag and label the important ones * Get an intuitive view of feature usage and where users spend their time on your product * Once labeled, use the events to trigger content and track user activity for segmentation ### Raw Events Auto-Capture Enabling/Excluding Under [Configure - Settings](https://run.userpilot.io/settings/data-capture-privacy), raw events auto-capturing can be enabled/disabled. This has to be enabled for Userpilot to collect users' interactions (clicks, text input, form submissions). Excluding certain elements, domains, and locations can also be added under the exclude fields not to be auto-captured by Userpilot. ### Types of interactions captured * **Click**: Any clicks on a button, link, or element (meaningful clicks/actions). In other words, clicking buttons with underlying mutations, links, or elements, each with a descriptive title. * **Text Input**: Typing a character or more into a text field, with each interaction tied to the field’s placeholder or input name. The description may include the placeholder text or the input name, depending on the field. * **Form Submission**: The user submits a form, typically via a button or submit input which triggers the underlying action or mutation to process the data entered in the form. ### Labeling Raw Events This is only available for Growth & Enterprise plans Turn a Raw Event into a [**Labeled Event**](../autocapture/visual-labeler) by clicking "Label Event" or "Visually label" next to the captured Raw Event. Some settings are pre-filled based on how the event was captured (Name, Domain, URL path, and CSS selectors), and you can customize them as needed. After the event has been labeled, it will appear under [Overview](https://run.userpilot.io/events/overview) with the rest of the events (tracked events, custom events). It can be used for segmentation, content triggering, and creating analytical reports. Once you label a Raw Event, its **historical data** (collected before labeling) becomes available in **Event Overview** and **Analytics** (report creation). **Segments** and **Content Triggering**, however, only consider data collected after the event was labeled.