This guide specifies how nGrow is expecting your custom built webfunnels to send user events to our webhook.
π§ General Requirements
Our server will respond with a 2xx HTTP status within 1 second after receiving a webhook request.
β
βIf no such response is received, the event is considered undelivered.
β
βUndelivered events should be retried automatically using an exponential backoff strategy:
β
β
delay(n) = nβ΄ + 15 + rand(0, 29) Γ (n + 1)
Where:
delay β delay in seconds before the next retry
β
βn β retry attempt number (starting from 1)
β
βrand(0, 29) β a random integer between 0 and 29
β
β
π Webhook Endpoint
URL:
Please use webhook url provided to you during nGrow app onboarding on 'Select Funnel Builder' page
βhttps://email-webhooks.ngrow.ai/api/v1/web2wave-webhook/<ngrow_app_id>.
Each webhook request contains a JSON payload depending on the event type.
π₯ Supported Event Types
Event Type | Description |
profile.updated | Fired when a user updates their profile. Email is required to be present. |
onboarding.completed | Fired when the user completes onboarding. |
purchase.completed | Fired on initial purchase, upsell, or recurring transaction. |
subscription.renewed | Fired when an existing subscription is renewed. |
π Common Required Fields (all events)
{
"type": "string", // Event name
"funnel_id": "string", // The current funnel or paywall id
"project_id": "string", // Any consistent project_id, associated with app
"created_at": 1734392768, // UNIX time in UTC timezone
"profile": {
"id": "string",
"country": "string", // 2-digit ISO code
"city": "string",
"locale": "string", // ISO (e.g. en-us)
"time_zone": "string" // e.g. America/New_York
}
}
π Event-Specific Payloads
1. profile.updated
Triggered when user properties change. Must be fired when the user submits their email.
Required additional field:
"data": {
"email": "[email protected]"
}
Example:
{
"type": "profile.updated",
"created_at": 1734392768,
"funnel_id": "fun_01...",
"project_id": "01HP...",
"profile": {
"id": "pro_01...",
"country": "US",
"city": "New York",
"locale": "en-US",
"time_zone": "America/New_York"
},
"data": {
"email": "[email protected]"
}
}
2. onboarding.completed
Triggered when the user finishes the onboarding funnel.
After the funnel is completed, we expect the onboarding.completed event. In addition to the common fields, it must contain the data.replies attribute β an array of objects describing the userβs answers.
Each object in data.replies includes:
screen.custom_id β optional (screen name or text)
β
βscreen.id β screen ID
β
βscreen.index β screen position in the funnel
β
βelement.custom_id β optional (question name or label)
β
βelement.id β question ID
β
βelement.type β Options (single/multi choice) or Input (free text)
β
βstate.value β answer ID or text. If multiple options selected, values are comma-separated
β
β
Example:
{
"type": "onboarding.completed",
"created_at": 1734388235,
"data": {
"replies": [
{
"screen": {
"custom_id": "q_triggers",
"id": "W5mtQrrW",
"index": 22
},
"element": {
"custom_id": "q_triggers",
"id": "W5mtQrrW",
"type": "Options"
},
"state": {
"value": "nrWU6, 2ndrm, gefCv, family-issues, not-enough-me-time-or-self-care"
}
}
]
}
}
3. purchase.completed
Triggered on any type of user purchase.
Required fields in data:
id, created_at, price, currency
β
βvendor_product_id, vendor_profile_id, vendor_transaction_id
β
β
Example:
{
"type": "purchase.completed",
"created_at": 1734349469,
"data": {
"id": "tra_...",
"currency": "USD",
"price": 3000,
"vendor_product_id": "prod_...",
"vendor_transaction_id": "in_..."
}
}
4. subscription.renewed
Fired when the subscription is renewed by the payment provider.
Required fields in data:
starts_at, vendor, vendor_subscription_id, vendor_transaction_id
β
β
Example:
{
"type": "subscription.renewed",
"created_at": 1734349469,
"data": {
"starts_at": "2024-09-14T13:44:02Z",
"vendor": "stripe",
"vendor_subscription_id": "sub_...",
"vendor_transaction_id": "in_..."
}
}