Amplitude & Mixpanel
Where the analytics integrations stand today.
#Amplitude — Event Streaming (push)
Amplitude pushes events to Pushlane in real time using its Webhook Event Streaming destination. Pushlane exposes a dedicated endpoint that accepts the raw Amplitude batch payload and maps it into the same ingest pipeline as the SDK — including deduplication, catalogue auto-discovery, and flow triggers.
#Amplitude — Setup
In your Amplitude workspace, go to Data → Destinations → Event Streaming, add a new Webhook destination, and configure it as shown below. The Authorization header is the custom header Amplitude lets you attach; set its value to Bearer lpk_live_… — your publishable write-key, found under Settings → API.
# In Amplitude: Data → Destinations → Event Streaming → Webhook
# 1. Endpoint URL:
POST https://ingest.pushlane.io/v1/integrations/amplitude
# 2. Custom header (Authentication):
Authorization: Bearer lpk_live_…tenantId query parameter is needed. A missing or unknown key is rejected with 401 before any event is processed.#Amplitude — Field mapping
Pushlane maps each Amplitude event object to its normalized form. The mapping is tolerant: the worker also accepts a bare array, a single event object, or an envelope with an events or data key.
| Amplitude field | Pushlane field | Notes |
|---|---|---|
event_type | name | Required — events without a name are skipped |
user_id | externalId | [object Object] fallback when user_id is absent |
time | ts | Epoch ms (number) or ISO-8601 string; falls back to now |
event_properties | properties | Forwarded as-is |
insert_id | dedup key | Stable hash of name|user|time when absent |
user_id nor device_id cannot be attributed to a user and are skipped — they are counted in the skipped field of the response, never a batch failure.#Amplitude — Response and limits
The endpoint always returns 200 for a valid authenticated request, even when some events are skipped. It returns 413 when a single request carries more than 500 events.
// Success — all or part of the batch accepted
{
"received": 42, // events extracted from the payload
"accepted": 41, // forwarded into the pipeline (after dedup)
"skipped": 1 // no user_id / device_id — counted, not failed
}
// Too many events in one request (> 500)
HTTP 413
{ "error": "too_many_events", "max": 500, "received": 512 }#Mixpanel — Raw Export polling (pull)
Unlike Amplitude, Mixpanel has no real-time per-event outbound webhook. Pushlane pulls your event stream by polling the Mixpanel Raw Export API every 10 minutes using a service account. The Raw Export API is available on all Mixpanel plans.
#Mixpanel — Setup
Go to Settings → Integrations → Mixpanel and click Connect Mixpanel. Fill in the three fields and select your data residency region.
| Field | Where to find it |
|---|---|
| Service account username | Mixpanel Organization Settings → Service Accounts → create or copy the username |
| Service account secret | Generated alongside the username — write-only, never displayed after saving |
| Project ID | Mixpanel Project Settings → Project ID (numeric) |
| Region | US (data.mixpanel.com) or EU (data-eu.mixpanel.com) — must match your project's data residency |
#Mixpanel — How polling works
Every 10 minutes Pushlane fetches events for each connected Mixpanel project:
- The fetch window runs from the last cursor position to now minus 10 minutes (a lag margin for in-transit events), and is clamped to the last 24 hours.
- A maximum of 5 000 events per tick are ingested per tenant. When more exist in the window, the oldest are ingested first and the cursor advances to the last ingested event so the next tick resumes from there.
- Pushlane deduplicates on Mixpanel's
$insert_idproperty (mapped to a deterministic UUID). Window overlaps between ticks are absorbed by the dedup layer — no event is ingested twice regardless of how much the windows overlap.
// Mixpanel Raw Export row → Pushlane event
{
"event": "Sign Up", // → name
"properties": {
"distinct_id": "user_abc", // → externalId
"time": 1719878400, // → ts (epoch SECONDS, converted to ms)
"$insert_id": "evt_xyz", // → dedup key (else name|distinct_id|ts)
"plan": "pro" // → forwarded as-is in properties
// "time", "distinct_id", "$insert_id" are lifted out and NOT forwarded
}
}#Mixpanel — Status
The integration card in Settings shows the current sync status:
| Status | Meaning |
|---|---|
| Pending first sync | Credentials saved; the first poll has not run yet (runs within 10 minutes) |
| Syncing | Last poll succeeded; events are flowing |
| Auth failed | Mixpanel returned 401 or 403 — the service account secret may have expired; reconnect with updated credentials |
#Events in Pushlane
Events imported from both Amplitude and Mixpanel enter the same ingest pipeline as events sent via the SDK or HTTP API. This means:
- Deduplication (R2) prevents double-counting across batches and retries.
- Each new event name is auto-discovered in the event catalogue and appears immediately in the flow builder trigger picker.
- Flows can trigger on any imported event name — for example a segment trigger on
Sign Upfrom Mixpanel works identically to one on an SDK-sentSign Up.
#Prefer real-time? Mirror analytics into Pushlane.track
The connectors above stream your events into Pushlane server-to-server (push for Amplitude, a 10-minute poll for Mixpanel). If you also want events straight from the app — with no lag, and to instrument new events — mirror your existing analytics.track / logEvent calls into Pushlane.track additively: keep your analytics, and add a Pushlane.track alongside.
// keep your existing analytics call, add Pushlane.track alongside it
analytics.track('paywall_viewed', { placement: 'home' });
Pushlane.track('paywall_viewed', { placement: 'home' });message_sent → chat_message_sent — Pushlane writes message_sent itself), and skip auto-emitted app_open / session_started (the SDK already emits them). The Pushlane MCP's plan_instrumentation tool does this reconciliation automatically — see Events & catalogue for the full rules.Next: RevenueCat — connect subscription events to flow triggers.