Userpilot
Datafly Signal delivers events to Userpilot server-to-server using the real-time HTTP Track API. Userpilot uses these events to segment users and trigger in-app experiences (onboarding flows, tooltips, surveys, checklists) — without a client-side Userpilot tag on your site.
Prerequisites
Before configuring Userpilot in Signal you need a Userpilot account, your application write token, and your account’s analytics endpoint host.
Step 1: Find your Write Token
- Log in to Userpilot and open the Environment page (Settings).
- Copy the application write token. This is the token Signal uses to authenticate Track requests.
Use the write token, not the read/export token. The read token cannot send events and will be rejected with a 401/403.
Step 2: Find your Analytics Endpoint
On the same Environment page, note your analytics endpoint host:
- Standard accounts use
analytex.userpilot.io. - EU data-residency accounts use
analytex-eu.userpilot.io. - Some Enterprise accounts have a dedicated host — use whatever the Environment page shows.
You will enter this host (without https:// and without a path) into Signal.
Configure in Signal
Configuration Fields
| Field | Required | Description |
|---|---|---|
api_key | Yes | Your Userpilot write token. Sent as the Authorization: Token ... header. |
analytics_endpoint | Yes | Your analytics host, e.g. analytex.userpilot.io (or analytex-eu.userpilot.io for EU). Host only, no scheme or path. |
Management UI Setup
Add the integration
Go to Integrations > Add Integration > Userpilot.
Choose a preset
Select the Default preset (page views plus core product-engagement events).
Enter credentials
Enter your api_key (write token) and analytics_endpoint host.
Select consent categories
Userpilot has no server-side consent parameter, so consent is enforced upstream in Signal. Select the consent categories that should gate delivery (typically analytics / functional). Events without the required consent are not delivered.
Save
Click Save.
API Endpoint
POST https://{analytics_endpoint}/v1/trackRequired headers:
Content-Type: application/json
Authorization: Token {api_key}
X-API-Version: 2020-09-22A successful request returns HTTP 202 Accepted. Events can take up to 15 minutes to appear in the Userpilot dashboard.
Identity Signals
Userpilot is a known-user product-experience tool: every event must carry a stable user_id so Userpilot can attribute it to a user profile.
| Signal | Field | Description |
|---|---|---|
user_id | user_id | Required. Your application’s user identifier, set via datafly.identify(). Userpilot rejects events without a user_id, so anonymous (pre-login) events are not delivered to Userpilot. |
Userpilot does not require PII hashing — it stores user traits (name, email, plan) as raw profile attributes. Set those traits with datafly.identify(); Signal forwards behavioural events keyed to the same user_id. No data is hashed for Userpilot.
Sending the user ID
Call datafly.identify() when a user logs in or signs up:
datafly.identify("user_001", {
name: "Jane Doe",
email: "jane@example.com",
plan: "pro"
});Event Mapping
Signal maps GA4-style event names to Userpilot custom events. Properties become Userpilot event metadata.
Userpilot metadata accepts primitive values only (string, number, boolean, null). Nested objects and arrays are rejected, so the blueprint flattens product/line-item data to scalar summary fields (product_id, product_name, price, currency) rather than sending an items array.
Default preset
| Signal event | Userpilot event |
|---|---|
page | page_viewed |
Signed Up | signed_up |
Logged In | logged_in |
Feature Used | feature_used |
Products Searched | searched |
Plan Viewed | plan_viewed |
Product Viewed | product_viewed |
Trial Started | trial_started |
Subscription Started | subscription_started |
Subscription Cancelled | subscription_cancelled |
Lead Generated | lead_generated |
Unmapped events are dropped. To customise, edit the integration’s Field Mappings in the Management UI.
Example: Feature Used event
Datafly.js call:
datafly.track("Feature Used", {
feature: "export_csv",
feature_id: "feat_017",
context: "reports_dashboard"
});Userpilot Track payload sent by Signal:
{
"user_id": "user_001",
"event_name": "feature_used",
"metadata": {
"feature": "export_csv",
"feature_id": "feat_017",
"context": "reports_dashboard"
}
}Testing Your Integration
Trigger an event
While logged in to your app as an identified user, perform a tracked action (e.g. use a feature mapped in the preset).
Check Signal’s event debugger
In the Management UI, open the Event Debugger for the Userpilot integration and confirm the outbound payload has user_id, event_name, and a flat metadata object, and that Userpilot returned 202.
Verify in Userpilot
In Userpilot, open the user’s profile or the event list and confirm the event appears.
Allow up to 15 minutes for events to surface in the Userpilot dashboard. A 202 response confirms acceptance even if the event is not yet visible.
Troubleshooting
| Problem | Solution |
|---|---|
401 / 403 Unauthorized | You are using the read/export token. Use the write token from the Environment page. Confirm the Authorization: Token ... format. |
404 Not Found | Wrong analytics endpoint host. Re-check the Environment page (e.g. analytex.userpilot.io vs analytex-eu.userpilot.io) and enter the host only, with no scheme or path. |
400 Bad Request | The payload contains a non-primitive metadata value (nested object or array). Ensure mappings target scalar fields only. |
| Events accepted (202) but not visible | Wait up to 15 minutes. Confirm the user_id matches a user that exists in Userpilot (identify the user first). |
429 Too Many Requests | You exceeded 600 requests/minute per token. Signal rate-limits and retries automatically; reduce volume or contact Userpilot if sustained. |
| No events at all for anonymous visitors | Userpilot requires a user_id. Pre-login (anonymous) events are not delivered — identify the user first. |
Rate Limits
| Limit | Value |
|---|---|
| Track / Identify API | 600 requests per minute per token |
Signal applies a per-integration rate limit and retries on 429, so transient bursts are smoothed automatically.