API Reference

Webhook Documentation

Overview

Web2Wave can send real-time notifications about events in your project via webhooks. This allows you to integrate with external systems and react to user actions as they happen.

Webhook Delivery Options

You can choose one of the following options for receiving webhooks:

Option 1: Single Webhook URL

Send all webhooks to a single URL endpoint. This is the simplest option if you have one system that needs to receive all webhook events.

  • Pros: Simple setup, direct integration
  • Cons: All events go to one endpoint, no built-in filtering or logging

Option 2: Webhook Gateway (Powered by Convoy)

Use our integrated Webhook Gateway for advanced webhook management capabilities.

  • Multiple Endpoints: Send different webhook types to different URLs
  • Event Logging: View a complete log of all sent webhooks
  • Custom Filters: Filter webhooks based on event data using Convoy subscription filters
  • Retry Management: Automatic retry handling for failed deliveries
  • Portal Access: Visual interface to manage your webhooks

To use Webhook Gateway, click "Add Webhook Gateway Portal" and the system will generate a portal token for you.

Note: You can only use one option at a time - either a single webhook URL or the Webhook Gateway.

Available Webhook Types

  1. user_property - Sent when user properties are created or updated
  2. event - Sent for analytics events tracked in your application
  3. subscription - Sent when subscription status changes
  4. CompleteRegistration - Sent when a user completes the quiz and reaches the paywall

General Requirements

  • URL Requirements:

    • Must be specified in project settings
    • Must begin with http:// or https://
    • If no URL is specified, no events will be sent
  • Timeout: Server response time must not exceed 3 seconds or the connection will be terminated

  • Format: All data is sent as JSON with UTF-8 encoding

  • Authentication: Each webhook request includes a Webhooks-Token header containing your project's webhook secret for verification

Webhook Structure

All webhooks follow this basic structure:

{
  "type": "webhook_type",
  "data": {
    // Type-specific data
  }
}

Fields:

  • type (string): The webhook event type
  • data (object): Event-specific data

Webhook Types

type: "user_property"

Sent every time a user property is added or modified. This includes quiz answers, UTM parameters, user location data (country_code, language), and any custom properties.

When triggered:

  • New user property is set
  • Existing user property is updated

Data fields:

FieldTypeDescription
project_domainstringDomain of the project
user_idstringUnique user identifier (GUID)
propertystringProperty name (e.g., "email", "utm_source", "answer_1")
valuestringProperty value (multiple values separated by "||")

Example:

{
  "type": "user_property",
  "data": {
    "project_domain": "app.web2wave.com",
    "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
    "property": "2_question",
    "value": "Of course, yes"
  }
}

type: "event"

Sent for every analytics event tracked in your application.

When triggered: Any custom event is logged (e.g., button clicks, page views, form submissions)

Data fields:

FieldTypeDescription
created_atstringEvent timestamp (ISO 8601)
user_idstringUnique user identifier (GUID)
project_domainstringDomain of the project
quiz_idstringQuiz identifier
quiz_namestringName of the quiz
event_namestringName of the event
event_valuestringEvent value
event_propertiesstring|nullJSON-encoded event properties
urlstringPage where event occurred
initial_urlstringInitial page URL with UTM parameters
user_agentstringUser's browser information
user_timestringUser's local time
user_localestringUser's language/locale
app_versionstringApplication version
quiz_versionstring|nullQuiz version
experimentstring|nullA/B test experiment name
experiment_groupstring|nullA/B test variant
additional_datastring|nullJSON-encoded additional data
ipstringUser's IP address
paywall_namestring|nullPaywall name if applicable
paywall_versionstringPaywall version
user_visitstringVisit identifier

Example:

{
  "type": "event",
  "data": {
    "created_at": "2024-06-12T19:19:18.000000Z",
    "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
    "project_domain": "app.web2wave.com",
    "quiz_id": "5",
    "quiz_name": "Product Quiz",
    "event_name": "Answer radio 2_question",
    "event_value": "Of course, yes",
    "event_properties": "{\"value\":\"Of course, yes\"}",
    "url": "https://app.web2wave.com/#2_question",
    "initial_url": "https://app.web2wave.com/?utm_source=google&utm_campaign=my_campaign",
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "user_time": "9:19:18 PM",
    "user_locale": "en",
    "app_version": "1.0",
    "quiz_version": null,
    "experiment": null,
    "experiment_group": null,
    "additional_data": null,
    "ip": "192.168.1.1",
    "paywall_name": null,
    "paywall_version": "1.0",
    "user_visit": "visit_123"
  }
}

type: "CompleteRegistration"

Sent when a user completes the quiz and reaches the paywall, including all user properties. This is useful for tracking quiz completions and passing all collected user data to your systems.

When triggered:

  • User finishes the quiz and is shown the paywall
  • Only sent if "CompleteRegistration event with User Properties" is enabled in webhook settings

Data fields:

FieldTypeDescription
created_atstringEvent timestamp
user_idstringUnique user identifier (GUID)
project_domainstringDomain of the project
event_namestringAlways "CompleteRegistration"
propertiesarrayAll user properties (same format as user_property webhook)

Example:

{
  "type": "CompleteRegistration",
  "data": {
    "created_at": "2024-06-12T19:20:00.000000Z",
    "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
    "project_domain": "app.web2wave.com",
    "event_name": "CompleteRegistration",
    "properties": [
      {
        "project_domain": "app.web2wave.com",
        "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
        "property": "email",
        "value": "[email protected]"
      },
      {
        "project_domain": "app.web2wave.com",
        "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
        "property": "utm_source",
        "value": "google"
      },
      {
        "project_domain": "app.web2wave.com",
        "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
        "property": "answer_1",
        "value": "Option A"
      },
      {
        "project_domain": "app.web2wave.com",
        "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
        "property": "user_country_code",
        "value": "US"
      },
      {
        "project_domain": "app.web2wave.com",
        "user_id": "f555ab28-a2b8-447d-9fe9-3c17e6ac70f4",
        "property": "user_language",
        "value": "en"
      }
    ]
  }
}

type: "subscription"

Sent when subscription status changes (created, renewed, cancelled, etc.).

When triggered:

  • New subscription created
  • Subscription renewed
  • Subscription cancelled
  • Payment succeeded/failed
  • Subscription status changed

Data fields:

FieldTypeDescription
created_atstringSubscription creation timestamp (ISO 8601)
updated_atstringLast update timestamp (ISO 8601)
payment_systemintPayment system identifier
payment_system_labelstringPayment system name (e.g., "Stripe")
real_paymentintProduction mode (1) or test mode (0)
pay_system_idstringPayment system's subscription ID
project_domainstringProject domain
quiz_namestringAssociated quiz name
quiz_idstringQuiz identifier
paywall_namestringPaywall name
paywall_idstringPaywall identifier
price_idstringPrice/plan identifier
amountfloatAmount in cents
amount_realfloatAmount in real currency
currencystringCurrency code (e.g., "usd", "gbp")
canceled_atstring|nullCancellation timestamp or null
customerstringCustomer ID in payment system
statusstringSubscription status (see Status Options below)
next_charge_datestring|nullNext payment date (ISO 8601)
last_charge_datestring|nullLast payment date (ISO 8601)
charges_countintTotal number of charges
total_revenueintTotal revenue in cents
total_revenue_usdintTotal revenue in USD cents
user_idstringUser identifier
user_emailstringUser's email address
manage_linkstring|nullSubscription management URL
event_typestringPayment system event (e.g., "charge.succeeded")
priceobjectDetailed price information
invoices_newarrayList of invoice objects
propertiesarray|nullUser properties (if enabled)
user_visitobjectVisit tracking information

Status Options:

  • active - Active subscription
  • incomplete - Incomplete setup
  • incomplete_expired - Setup expired
  • trialing - In trial period
  • past_due - Payment overdue
  • canceled - Subscription canceled
  • unpaid - Payment failed
  • paused - Subscription paused

Example: [Full subscription webhook example available in the original documentation above]

Configuration Options

In your project webhook settings, you can configure:

Event Type Filtering

  • User Property: Every user answer, UTM tags, location data, etc.
  • Analytics Events: All tracked events in your application
  • Subscription updated: When subscription status changes
  • CompleteRegistration event with User Properties: When quiz is completed

Additional Options

  • Filter specific events: Specify exact event names to receive (one per line)
  • Filter user properties: Specify which user properties to include (one per line)
  • Include User Properties with Subscriptions: Add all user properties to subscription webhooks

Testing Webhooks

Use webhook.site for testing and debugging your webhook integration.

Best Practices

  1. Verify webhook authenticity using the Webhooks-Token header
  2. Respond quickly (within 3 seconds) to avoid timeouts
  3. Return 2xx status codes to acknowledge receipt
  4. Handle duplicates - webhooks may be sent multiple times
  5. Process asynchronously - acknowledge receipt immediately, then process in background
  6. Log webhook data for debugging and audit purposes

Error Handling

  • Webhooks that timeout or receive non-2xx responses may be retried
  • Failed webhooks are logged for troubleshooting
  • Ensure your endpoint can handle concurrent requests

Using Webhook Gateway Filters

When using the Webhook Gateway option, you can create advanced filters using Convoy's JSON-based filter syntax. This allows you to:

  • Route different event types to different URLs
  • Filter based on specific field values
  • Create complex conditions using logical operators
  • Use regex patterns for flexible matching

Filter Examples for Web2Wave

Simple Filters

Send only active subscriptions:

{
  "data": {
    "status": "active"
  }
}

Send only events from a specific quiz:

{
  "data": {
    "quiz_id": "123"
  }
}

Send only CompleteRegistration events:

{
  "type": "CompleteRegistration"
}

Complex Filters

Send only high-value subscriptions ($50+):

{
  "data": {
    "amount_real": {
      "$gte": 50
    }
  }
}

Send subscriptions from specific payment systems:

{
  "data": {
    "payment_system_label": {
      "$in": ["Stripe", "PayPal"]
    }
  }
}

Send only failed or cancelled subscriptions:

{
  "$or": [
    {
      "data": {
        "status": "canceled"
      }
    },
    {
      "data": {
        "status": "unpaid"
      }
    }
  ]
}

Send events matching specific patterns:

{
  "data": {
    "event_name": {
      "$regex": "^CompleteRegistration|Purchase|Subscribe$"
    }
  }
}

Complex subscription filter (high-value active subscriptions):

{
  "$and": [
    {
      "data": {
        "status": "active"
      }
    },
    {
      "data": {
        "amount_real": {
          "$gte": 29.99
        }
      }
    },
    {
      "data": {
        "currency": {
          "$in": ["usd", "eur", "gbp"]
        }
      }
    }
  ]
}

Filter user properties by specific answers:

{
  "$and": [
    {
      "type": "user_property"
    },
    {
      "data": {
        "property": "email"
      }
    }
  ]
}

Send only events with specific UTM sources:

{
  "$and": [
    {
      "type": "user_property"
    },
    {
      "data": {
        "property": "utm_source"
      }
    },
    {
      "data": {
        "value": {
          "$in": ["google", "facebook", "instagram"]
        }
      }
    }
  ]
}

Filter subscriptions with nested price data:

{
  "data": {
    "price": {
      "currency": "usd"
    }
  }
}

Filter by user visit data:

{
  "data": {
    "user_visit": {
      "utm_source": "facebook"
    }
  }
}

Supported Filter Operators

OperatorTypeDescriptionExample
(none)allDirect match{"data": {"status": "active"}}
$eqallEqual to{"data": {"amount": {"$eq": 100}}}
$neqallNot equal to{"data": {"status": {"$neq": "canceled"}}}
$gtnumberGreater than{"data": {"amount_real": {"$gt": 50}}}
$gtenumberGreater than or equal{"data": {"amount_real": {"$gte": 50}}}
$ltnumberLess than{"data": {"charges_count": {"$lt": 3}}}
$ltenumberLess than or equal{"data": {"charges_count": {"$lte": 3}}}
$inarrayValue in array{"data": {"currency": {"$in": ["usd", "eur"]}}}
$ninarrayValue not in array{"data": {"status": {"$nin": ["trialing", "incomplete"]}}}
$orarrayAny condition matches{"$or": [{"type": "event"}, {"type": "subscription"}]}
$andarrayAll conditions match{"$and": [{"type": "subscription"}, {"data": {"status": "active"}}]}
$regexstringRegex pattern match{"data": {"event_name": {"$regex": "^Complete"}}}
$existboolField exists{"data": {"user_email": {"$exist": true}}}

For complete filter documentation and more examples, see the Convoy Filters Documentation.