Webhooks

Prev Next

Overview

Branch’s webhook system allows you to export install and down-funnel event data as it occurs. You can import this data into your internal systems for analysis. You simply need to specify a URL for the POST or GET requests.

If you are looking for postback integrations for ad networks, please visit our Ads documentation. For pre-configured integrations into popular analytics tools, please visit our Data Integrations documentation.

The webhook system is highly customizable. You can register to only receive notifications for specific events, as well as specific subsections of events, filtered by link data, user data or event properties.

Our webhook infrastructure supports all Branch events. The data is formatted according to standard event naming and metadata format which will get you through implementation and on to analysis in no time.

Set up a webhook

Step 1: Add webhook

  1. In the Branch Dashboard, select Data Feeds > Webhooks.

  2. Select Add New Webhook.

Step 2: Select event for webhook

After you select Add New Webhook, complete the the following steps:

  1. Select the drop-down menu under Select an event.

  2. Select an event from the list. When the selected event occurs, a webhook will fire.

    Tip

    Events will only appear in the Select an event dropdown if at least one of those events has been recorded in the past 30 days.

    Expand to view available events

    Event

    Description

    install

    Triggered the first time a user ever launches your app on their device.

    reinstall

    Triggered if a user deletes and reinstalls your app on their device.

    open

    Triggered whenever the app is opened (and the open is neither an install or reinstall)

    web session start

    Triggered when the user views a webpage using the Branch Web SDK

    click

    Triggered whenever a Branch link is clicked on any platform

    -- additional events --

    A complete list of events you track through the Branch Web or App SDKs.

  3. Select Save. The Add Webhook pop-up will open.

For an exhaustive list of events and more detailed definitions of each event, please see the Event Ontology Data Schema.

Warning

Event frequency is not yet supported. At this time webhooks can only be sent every time an event occurs.

Step 3: Configure webhook

  1. In the Free Form Edit field, enter the URL where you would like the events to be sent. This URL can be written with Freemarker syntax to dynamically populate parameters and execute simple, logical expressions. There is more information on Freemarker support below.

  2. Select the Filters tab.

  3. Under Webhook details, select the POST drop-down menu. Events can be sent either via POST or GET. POST events will be created with a default POST body. There is more information on POST bodies below.

  4. Select POST or GET from the drop-down menu.

  5. Select the event drop-down menu to the right of the previous drop-down. Choose which event should cause the webhook to fire. For an exhaustive list of events and more detailed definitions of each event, please see the Event Ontology Data Schema.

Warning

Apple requires users to opt into sharing their device data through Apple's AppTrackingTransparency framework. When an install is attributed to paid ads, a 2nd install event will fire post user-opt-in.

Opt-ins will affect your final install count. Our recommendation is to use a different identifier (ex. IDFV) to de-dupe install events on your internal systems.

For additional information on changes post iOS 14.5, visit our FAQ Pages

Basic filtering

In the Filters tab of the Edit/Add Webhook pop-up you can create a filter. Only events that pass the filter criteria will be sent.

Your title goes here

While Branch preserves the original case of all captured data field values and case is retained through export, when webhook/postback filters are evaluated, case-sensitivity is removed. For example, if you created a filter on user_data.os, iOS, ios, and IOS are equivalent.

A default filter that checks to see whether the event is not triggered by a known crawler/robot. To do this, we check if the operating system (OS) does not equal "robots." With that filter applied, only events without OS equal to robots (for example, iOS and Android) will trigger a webhook.

The most popular filter options are available in a drop-down menu. This should help you get up and running quickly, while also providing an example structure for more advanced filtering if you need it.

Complete the following steps to create a filter:

  1. Click the Add New Filter button.

  2. Select the metadata you'd like to filter with with the Field Name drop-down menu. For example, if you only want iOS installs, select Operating System from the dropdown. You'll see the text field to the right populate with the correct key.

  3. Select equals or does not equal from next dropdown.

  4. Enter the value of the key that you'd like to filter in or out. For example, if you want iOS installs, you'll have set up "equals" and "iOS" in the dropdowns.

See the Advanced Filtering section to read more about customizing when events are sent.

Filtering example 1

For example, let’s say you’re interested in receiving a webhook for every install event that is referred from a Branch link where you set the Campaign field to App Install Campaign. You would configure a filter to fire a webhook only when Campaign is equal to App Install Campaign. You would select Campaign from the drop-down, the key would be be autofilled and would equal last_attributed_touch_data.~campaign. Then, you'd set the value equal to App Install Campaign.

Filtering example 2

For example, let’s say you’re interested in receiving a webhook for every click event that is referred from a Branch link where you set the Channel field to AppLovin. You would configure a filter to fire a webhook only when Channel is equal to AppLovin. You would select Channel from the drop-down, the key would be be autofilled and would equal last_attributed_touch_data.~channel. Finally, you'd set the value equal to AppLovin.

Testing

To test whether your webhook is configured correctly, you can use RequestBin. RequestBin gives you a URL that accepts events for 24 hours and allows you to see exactly what Branch is sending.

  1. Go to RequestBin and select + Create Request Bin.

  2. Copy the Endpoint URL.

  3. Create a new webhook and use the Endpoint URL as your webhook URL.

  4. Whenever your webhook is triggered, you will see a full report on RequestBin:

Warning

Please archive your Requestbin webhook when you have finished testing. Requestbins only last for 24 hours and return errors once they expire.

Data format

Setting up Advanced Filters or Freemarker macros requires an understanding of the Event Ontology data format. Before diving into the schema, you should understand some high level concepts about event metadata structure:

  • Each event has top level fields, such as "name" and "id" that are not nested

  • Link data is generally nested in "Last Attributed Touch Data"

  • User data (including device and OS data) is nested in "User Data"

  • Product or content level data is nested in "Content Items"

  • Transaction and generic content data is nested in "Event Data"

  • Journeys or Deepviews view data (e.g. Journey banners loads, not clicks) is "Last CTA View Data"

  • Client-specified custom data (e.g. internal fields your company requires on specific events) is nested in "Custom Data"

Note

To find a complete list of Branch supported postback macros, please see Postback Macros & Functions.

Warning

Geographic data, such as country and city, may not be available for a very small percentage of events where the IP cannot be resolved to a location.

Sample webhook POST body syntax

The POST body for all webhooks follows the same structure:

POST
User-agent: Branch Metrics API
Content-Type: application/json
{
    "name": "<event name e.g. open>",
    "user_data": {},
    "last_cta_view_data": {},
    "last_attributed_touch_data": {},
    "custom_data": {},
    "event_data": {},
    "content_items": {},
    "timestamp": 'example timestamp (int)'
}

If any of these objects are empty, they will not appear in the POST body.

Here's a POST body with example data for an attributed open:

// Attributed open
POST
User-agent: Branch Metrics API
Content-Type: application/json

{
  "name": "open",
  "user_data": {
    "os": "IOS",
    "os_version": "11.1.2",
    "environment": "FULL_APP",
    "platform": "IOS_APP",
    "idfa": "F520B35A-4165-4426-98F6-64F12F47E9BZ",
    "idfv": "C6B869E7-7B0A-4A93-1C3D-960E8859DP5D",
    "limit_ad_tracking": false,
    "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202",
    "ip": "50.200.105.218",
    "developer_identity": "DB8C86A6-8B7C-4192-BD29-8107A5B788A1",
    "country": "US",
    "language": "EN",
    "brand": "Apple"
  },
  "last_cta_view_data": {
    "~id": 457624031399716729,
    "~campaign": "_test",
    "~feature": "journeys",
    "+domain": "branchster.app.link",
    "+url": "https://branchster.app.link/jeMczRn5XH",
    "$deeplink_path": "open/item/1234",
    "~creation_source": 5,
    "+referrer": "https://store.com/products/green-table",
    "foo": "bar",
    "$canonical_url": "https://store.com/products/green-table",
    "mydata": "set_branch_view_data_value",
    "~tags": [
      "tag1",
      "tag2",
      "bottom_banner_style"
    ]
  },
  "last_attributed_touch_data": {
    "~id": 467391383381228204,
    "~feature": "marketing",
    "~campaign": "december_test",
    "~channel": "Facebook Organic",
    "product_id": "XBA8198j",
    "product_name": "Green Table AB10",
    "+url": "https://branchster.app.link/test_linking",
    "$marketing_title": "Deep Link Testing",
    "$ios_deepview": "branch_default",
    "+via_features": [
      "QUICK_LINKS"
    ]
  },
  "custom_data": {
    "reinstall": "false",
    "ip": "50.200.105.218",
    "referred": "false"
  },
  "timestamp": 1512681005807
}

Advanced filtering

In Basic filtering we covered what filters do, and how to set basic filters. Branch supports more advanced filtering which allows you to set filters based on almost any event metadata.

Make sure you've taken a look at the data format before you attempt to set advanced filters.

Complete the following steps to create an advanced filter:

  1. Select the Add New Filter button.

  2. Select the metadata you'd like to filter on. For advanced filtering, choose "Custom."

  3. Type in the key that you'd like to filter on. To find the key you'd like to filter on, reference our quick introduction to the Br data format to figure out where your key is likely nested. Another foolproof way to find your key is looking at your data in full before setting up your filter. You can do this by doing a CSV export, API export, or send a single webhook with a POST body. You can locate your key in that POST body.

  4. Unless your key is part of the top level data (e.g. timestamp or id), it will likely be nested one level deep. Most keys will be of the format object_name.key. For example, if you want to filter for a custom key in deep link data called "product_deeplink_id", that would take the form last_attributed_touch_data.product_deeplink_id.

Advanced filtering example

Let’s say you’re interested in receiving a webhook for every Purchase event using a specific coupon. When you set up the Purchase event in your app or on your website, you added a specific piece of metadata for coupon. In the Event Ontology Schema you saw that coupon is inside event_data.

To configure your filter to fire a webhook only when coupon is equal to SUMMERDEALS10 you will:

  1. Select Custom from the Field Name dropdown.

  2. Set the key as event_data.coupon.

  3. Select equals on the Comparator drop-down.

  4. Enter a value of SUMMERDEALS10.

Array filtering not yet available

Currently, webhooks do not support filtering on values inside arrays. Example arrays that cannot be filtered by value are tags, +via_features, and content_items.

Templating your postback URL

If you'd like to template your postback URL, you’ll likely need to create one of our templated postback URLs along side the aforementioned filters. These work very similarly to filters but use Freemarker syntax.

Getting started with templates

To start, we can add a simple template. Let's say we want to add campaign as a query parameter. The correct syntax is

`https://webhook.com?campaign=${(last_attributed_touch_data.~campaign)!}`

Let's walk through the syntax:

  1. First, find the key for the value you want to template in. As with filtering, to find the key, reference our quick introduction to the Branch data format to figure out where your key is likely nested. Another foolproof way to find your key is looking at your data in full before setting up your filter. You can do this by doing a CSV export, API export or send a single webhook with a POST body, and locate your key in that POST body.

  2. This exercise tells us that Campaign is nested inside last_attributed_touch_data and is represented by last_attributed_touch_data.~campaign.

  3. The additional syntax around last_attributed_touch_data.~campaign is because Branch's templating engine uses Freemarker. In Freemarker, you can print variables by surrounding them with ${}. Finally, we add ()! to the variable because we want to prevent errors in the case that there is no value.

  4. This leaves us with ${(last_attributed_touch_data.~campaign)!}.

Here is some more example Freemarker for common templates:

Parent object

Common name

Freemarker

Bundle

Android Package Name

${(bundle.android.package_name)!}

Bundle

iOS Bundle ID

${(bundle.ios.bundle_id)!}

Last Attributed Touch Data

Feature

${(last_attributed_touch_data.~feature)!}

Last Attributed Touch Data

Channel

${(last_attributed_touch_data.~channel)!}

Last Attributed Touch Data

Campaign

${(last_attributed_touch_data.~campaign)!}

Last Attributed Touch Data

Ad Partner Name

${(last_attributed_touch_data.~advertising_partner_name)!}

User Data

OS

${(user_data.os)!}

User Data

Platform

${(user_data.platform)!}

User Data

IDFA

${(user_data.idfa)!}

User Data

IDFV

${(user_data.idfv)!}

User Data

Android Advertising ID

${(user_data.aaid)!}

Note

To find a complete list of Branch supported postback macros, please see Postback Macros & Functions.

Freemarker expressions

Due to security restrictions, Branch does not support the full list of Freemarker expressions.

Here is a list of blocked expressions:

"<#import>", "<#visit>", "<#include>", "?eval", "<#recurse>", "<#setting>", "<#macro>", "<#function>", "<#nested>", "<#return>", "<#list>"

Allowlist webhook IP addresses

If needed, allowlist the following webhook server IP addresses for security purposes:

  • 52.9.159.121/32

  • 52.9.176.205/32

  • 52.9.188.221/32

  • 52.9.188.236/32

  • 52.52.143.205/32

  • 52.53.45.79/32

  • 52.8.3.171/32

  • 52.8.85.213/32

  • 52.43.119.253/32

  • 54.176.26.254/32

  • 54.153.26.149/32

  • 54.153.41.111/32

  • 54.176.133.14/32

  • 54.193.10.161/32

  • 100.21.145.61/32

  • 35.160.5.60/32

  • 35.163.128.27/32

  • 35.167.148.222/32

  • 44.231.103.124/32

  • 44.237.121.167/32

  • 44.238.95.201/32

  • 44.247.175.42/32

  • 44.247.58.38/32

  • 52.33.75.0/32

  • 52.34.127.49/32

  • 54.241.169.87/32

  • 52.52.236.153/32

  • 54.177.16.103/32

  • 184.169.196.16/32

  • 35.161.135.86/32

  • 44.230.175.24/32

  • 52.27.172.117/32

  • 54.213.17.93/32

  • 44.229.177.148/32

  • 35.160.133.187/32

Optional: Configure AWS security group

If you have an AWS account you use for webhooks, you will need to create a security group, as well as a series of inbound rules associated with that security group.

Note that this example does not include the entire list of IP addresses you need to make rules for. Find those above.

AWS security group details showing inbound rules and IP allowlist configurations for postbacks.

Optional: Configure GCP firewall policy

If you have an GCP account you use for webhooks, you will need to create a firewall policy, as well as a series of firewall rules associated with that policy.

Note

This example does not include the entire list of IP addresses you need to make rules for. Find those in our Postback Configuration documentation.

Note that

GCP firewall policy details showing various rules and their configurations for postbacks.

Authenticating webhook events

Use the Filters tab to configure your own headers and authenticate your webhook events.