Trigger Customer.io Campaigns Instantly from PostHog User Events
Automatically enroll users into Customer.io campaigns the moment they fire a key event in PostHog. Stop missing conversion windows by connecting your product analytics directly to your marketing automation.
- 1
Receive PostHog Event via Webhook
Add a
Webhooknode as the trigger. In PostHog, go to Project Settings > Webhooks and paste the n8n webhook URL. Set the PostHog webhook to fire on the specific action you care about (e.g.signed_uportrial_started). In n8n the node listens at the path/posthog-event. SetHTTP Methodto POST and note the production URL. - 2
Extract and Validate Event Data
Add a
Setnode namedExtract Event Data. Map these fields from the incoming webhook body: setemailto{{ $json.body.person.properties.email }},userIdto{{ $json.body.person.distinct_id }}, andeventNameto{{ $json.body.event }}. This normalises the PostHog payload into clean variables for the next steps. - 3
Filter for the Target Event
Add an
IFnode namedIs Target Event. Set the condition:{{ $json.eventName }}equals the exact PostHog event name you want to act on, for exampletrial_started. The TRUE branch continues to Customer.io. The FALSE branch can be left unconnected to silently drop unmatched events. - 4
Identify or Update the Person in Customer.io
Add an
HTTP Requestnode namedUpsert Person in Customer.io. SetMethodto PUT andURLtohttps://track.customer.io/api/v1/customers/{{ $json.userId }}. UnderAuthenticationchooseHeader Authand add headerAuthorizationwith valueBasic YOUR_SITE_ID:YOUR_API_KEY(base64-encoded). SetBody Content Typeto JSON and pass{ "email": "{{ $json.email }}", "posthog_event": "{{ $json.eventName }}" }. This creates or updates the person so Customer.io can match them to a campaign. Store your credentials in n8n Credentials, not plain text. - 5
Fire the Customer.io Campaign Trigger Event
Add a second
HTTP Requestnode namedSend Campaign Event. SetMethodto POST andURLtohttps://track.customer.io/api/v1/customers/{{ $json.userId }}/events. Use the same Basic auth header as the previous node. Set the JSON body to{ "name": "{{ $json.eventName }}", "data": { "source": "posthog" } }. In Customer.io, create a campaign with the trigger set to this exact event name. The campaign will now fire automatically every time PostHog sends the matching event.
Frequently asked questions
How do I find my Customer.io Site ID and API Key?
Log in to Customer.io, go to Settings > Account > API Credentials. Your Site ID and Tracking API Key are listed there. Base64-encode the string `siteId:apiKey` and use it as the Basic auth header value.
Can I trigger this for multiple PostHog events?
Yes. Either add more conditions to the IF node using OR logic, or duplicate the entire workflow for each event and change the event name in the filter. Using separate workflows keeps things easier to debug.
What if PostHog does not send the user's email in the webhook?
Make sure you call `posthog.identify()` in your product with the user's email as a property before the event fires. PostHog webhooks include person properties only when the person has been identified. You can also enrich the payload by calling the PostHog Persons API inside n8n using an extra HTTP Request node.