Overview
The Branch Attribution API offers developers a way track INSTALL
, REINSTALL
, and OPEN
events while also supplying a payload of attribution properties. This is something the Branch mobile SDKs do by default, but this API provides the option of sending this information server-side.
The response to a request sent to this API will be deep link data.
If you choose to use this API instead of tracking these events with a Branch SDK, please be aware that session management becomes the responsibility of the developer. You will need to account for handling poor or no connectivity, persisting data locally, retrieving values like IP address, tracking downstream conversions, creating shareable deep links, and other possible challenges. To achieve feature parity with a Branch SDK, one would need to duplicate the code in the SDK.
For this reason, it is highly recommended that all apps use a Branch SDK when possible.
Limitations
By default, Branch will rate limit non-referred OPEN
events (that is, app sessions not sourced by a link) to once every 4 hours per IP address.
Contact your Branch Account Manager to confirm the exact limit for your account.
Sessions exceeding your rate limit will still return deep link data in the network request, but the data will not appear in your Branch Dashboard reports or exports.
Branch will also return 429
responses if your app starts sending requests for the same user in rapid succession. While this scenario does not mirror normal user behavior, you may run into it during your own testing. If this happens, please wait a few minutes before resuming testing. You can also try changing the device metadata in your request.
Try It!
Try out the Attribution API in your browser, using your Branch data:
Getting Started
Prerequisites
In order to use the Attribution API, you first need to:
Create a Branch Dashboard.
Make sure that your account has access to the
v1/open
API enabled.Configure your Branch Dashboard with default link redirects, your
app.link
domains, a URI scheme, and Universal Links.Complete the "In-App Setup" section of this guide for your relevant app(s).
Authentication
Calls to the Attribution API require your Branch Key and Branch Secret. Both can be found in your Branch Dashboard Account Settings.
In-App Setup
iOS
Configuration
To configure your iOS app to use the Attribution API, you first need to:
Add your URI scheme to your
info.plist
file.Add your Branch
app.link
andalternate.app.link
domains to your project's Associated Domains.
Collect Launch Data for Request
To gather the launch data you need to make a request to the Attribution API, you can:
Retrieve the device's public IP address.
Retrieve the device's User Agent string.
Examine your AppDelegate's
openURL()
function for a URI.If a URI containing the query parameter
link_click_id
is present, then store that query parameter's value for use in the session's API network request.An example: If the URI
example://open?link_click_id=1234
opens the app, you will need to retrieve the1234
value.
Examine the AppDelegate's
continueUserActivity()
function for awebpageURL
value.The
webpageURL
value will live inside theNSUserActivity
parameter.If you find a URL, store the entire URL value for use in the session's API network request. This is true regardless of whether it is a Branch Deep Link.
Optional: Support Apple Search Ads
For server-to-server integrations, you will need to retrieve the new attribution token and send it to Branch on install as apple_attribution_token
.
To retrieve the attribution token:
Import the
AdService.framework
into your project.Request the attribution token, which should be available from Apple within 50ms:
func appleAttributionToken() -> String? { if #available(iOS 14.3, *) { return try? AAAttribution.attributionToken() } return nil }
+ (NSString *)appleAttributionToken { #if !TARGET_OS_TV if (@available(iOS 14.3, *)) { NSError *error; NSString *appleAttributionToken = [AAAttribution attributionTokenWithError:&error]; if (!error) { return appleAttributionToken; } } #endif return nil; }
Send the token to Branch for attribution within 24 hours, as that is the TTL for the token.
For more about retrieving the attribution token, visit Apple's documentation.
To learn more about Apple Search Ads, visit our guide.
Android
Configuration
Add your URI scheme to your
AndroidManifest.xml
file.Also add your Branch
app.link
andalternate.app.link
domains to yourAndroidManifest.xml
file.
Collect Launch Data for Request
To gather the launch data you need to make a request to the Attribution API, you can:
Retrieve the device ID (GAID or Android_ID) if available.
Retrieve the device's public IP address.
Retrieve the device's User Agent string.
Examine the intent that opened your
MainActivity
for a URI.If a URI containing the query parameter
link_click_id
is present, then store that query parameter's value for use in the session's API network request.An example: If the URI
example://open?link_click_id=1234
opens the app, you will need to retrieve the1234
value.
Examine the intent that opened your
MainActivity
for a web URL.If you find a URL, store the entire URL value for use in the session's API network request. This is true regardless of whether it is a Branch Deep Link.
Optional: Support Google Play Install Referrer
Complete the steps below only during the INSTALL
session:
Upon app launch, query the Google Play Install Referrer library for the referrer URL, click timestamp, and install timestamp.
Examine the referrer URL for a
link_click_id
query parameter.If present, retrieve its value for use in the request's
link_identifier
parameter.This value might appear in the referrer URL as
&link_click_id=<>
or&link_click_id-<>
. In either scenario, extract only the<>
part.
Examine the referrer URL for a
google_search_install_referrer
query parameter.If present, retrieve its value for use in the requests's
google_search_install_referrer
parameter.This value might appear in the referrer URL as
&google_search_install_referrer=<>
or&google_search_install_referrer-<>
. In either scenario, extract only the<>
part.
Usage
The network request to the v1/open
endpoint should occur once you've been notified that the user has successfully brought your app to the foreground.
Branch marks the beginning of an app lifecycle as when your app is launched and brought to the foreground of the device. The launch can either be from a cold start, or a transition from running in the background (present in the iOS or Android task manager) to the foreground.
On web, an open event is measured every time a webpage with the web SDK opens in a new tab, or when a user clicks on a Branch link and is redirected to a page with the web SDK. This is called a web_session_start
.
Request Open
Request Info
Export Request
POST /v1/open
Host: api2.branch.io
Content-Type: application/json
Request Headers
Header | Description | Required? |
---|---|---|
| The device's public IP address from your app user's device, not your server's IP address. | Yes |
| application/json | Yes |
| application/json | Recommended |
Request Body Parameters
Parameter | Type | Description | Required? |
---|---|---|---|
| String | The Branch Key of the relevant app, found in the Settings tab of your Branch Dashboard. | Required on iOS & Android |
| String | The Branch Secret of the relevant app, found in the Settings tab of your Branch Dashboard. | Required on iOS & Android |
| Bool | Always set this value to | Required on iOS & Android |
| String | The version of your app, such as | Required on iOS & Android |
| String | Choose either | Required on iOS & Android |
| String | The device's OS version, such as | Required on iOS & Android |
| String | The user agent of the device. | Required on iOS & Android |
| String | For iOS, populate with the IDFA if available. Otherwise, fallback to IDFV. | Required on iOS |
| String | This value confirms whether the iOS ID in the | Required on iOS |
| String | The IDFV, if available. | Required on iOS |
| String | The Google Advertising ID, if available. | Required on Android |
| Object | The set of advertising IDs, if available. | Required on Android |
| Boolean | Set this value to | Required on iOS & Android |
| Boolean | This value is used to determine whether the IDFA or GAID can be used for advertising purposes. | Required on iOS & Android |
| String | This is the device's local IP address, if one is available. Optional but highly recommended for improving attribution accuracy. | Recommended |
| Int | Height of the device’s screen. | Recommended |
| Int | Width of the device’s screen. | Recommended |
| String | When a URI opens the app, check for a | Optional |
| String | Populate this value with the Branch or non-Branch web URL that opened the app, if available. | Optional, iOS only |
| String | Populate this value with the Branch or non-Branch web URL that opened the app, if available. | Optional, Android only |
| Boolean | Set to | Optional |
| String | Populate with the value of the full Android PlayStore Install Referrer URL, if available. | Optional, Android only |
| String | Populate with the value of the | Optional, Android only |
| Long | The referrer click timestamp collected from the Play Install Referrer library, if available. | Optional, Android only |
| Long | The install begin timestamp collected from the Play Install Referrer library, if available. | Optional, Android only |
| String | The attribution token used for Apple Search Ads. Used to call the Apple Search Ads Attribution API. | Optional, iOS only |
| String | The Base64 encoded string of the entire response from the Apple Search Ads API. | Deprecated |
| Boolean | If this param is set to | Optional |
| Boolean | Setting to | Optional |
| Boolean | If | Optional |
| String | If | Optional |
| Boolean | If set to | Optional |
| Boolean | If set to | Optional |
| String | Populate with a Branch web URL that is present on the Clipboard on first open, if available. | Optional, iOS only (NativeLink) |
| String | Populate with the value of | Optional, Android only |
| String | Populate with the value of | Optional, iOS only |
| String | A custom parameter slot you can attach to your | No |
| String | A custom parameter slot you can attach to your | No |
| String | A custom parameter slot you can attach to your | No |
| Bool | Whether European regulations, including the DMA, apply to this user and conversion. | Required if EU regulations apply to this user |
| Bool | Whether end user has granted or denied ads personalization consent. | Required if |
| Bool | Whether end user has granted or denied consent for 3P transmission of user level data for ads. | Required if |
Response Info
When a request is made to the Attribution API, the app session can be attributed to a deep link click.
Regardless of whether the session is attributed, the API will always return a 200
response with some contextual data included in the JSON payload.
If the session was attributed to a deep link click, this payload will include the link's deep link data. You can use this data in your in-app logic and to execute your deep linking user experience.
Response Body Parameters
Below is a partial list of the possible values you may receive in a response:
Parameter | Description |
---|---|
| If you set |
| This will tell you if the current app session was sourced via a Branch Deep Link. |
| If a non-Branch deep link opened your app (i.e., a Universal Link), you can retrieve that link from this key. |
| This will be |
| This will be |
| This will contain a web url that you can use for deep link routing. If your app was already setup to route off Universal Links or Android App Links, you can pass this value into that pre-existing routing logic. |
| This will contain a URI relative path that you can use for deep link routing. If your app was already setup to route off URI schemes, you can pass this value into that pre-existing routing logic. |
Examples
Example Requests
curl -v -d '{
"branch_key": "key_live_xxx",
"branch_secret": "secret_live_xxx",
"server_to_server": true,
"app_version": "1.12.4",
"os": "iOS",
"os_version": "10.0",
"model": "iPhone",
"screen_height": 2208,
"screen_width": 1242,
"facebook_app_link_checked": false,
"user_agent": "{FULL_USER_AGENT_HERE}",
"hardware_id": "000AAAA-0A0A-000AAA-AAAA000",
"hardware_id_type": "idfa",
"ios_vendor_id": "000AAAA-0A0A-000AAA-AAAA000",
"is_hardware_id_real": true,
"ad_tracking_enabled": true,
"custom_param_1": "Parameter 1",
"custom_param_2": "Parameter 2",
"custom_param_3": "Parameter 3",
"dma_eea": true,
"dma_ad_personalization": true,
"dma_ad_user_data": true
}' "https://api2.branch.io/v1/open" -H "X-IP-Override: 1.2.3.4"
curl -v -d '{
"branch_key": "key_live_xxx",
"branch_secret": "secret_live_xxx",
"server_to_server": true,
"app_version": "1.12.4",
"os": "Android",
"os_version": 26,
"model": "SM-G960U1",
"screen_height": 2076,
"screen_width": 1080,
"facebook_app_link_checked": false,
"user_agent": "{FULL_USER_AGENT_HERE}",
"hardware_id": "00aa0a000a0a0",
"google_advertising_id": "000AAAA-0A0A-000AAA-AAAA000",
"advertising_ids": {
"oaid": "000AAAA-0A0A-000AAA-AAAA000"
},
"google_search_install_referrer": "referrer_value_here",
"clicked_referrer_ts": 1574699946,
"install_begin_ts": 1574699955,
"is_hardware_id_real": true,
"ad_tracking_enabled": true,
"custom_param_1": "Parameter 1",
"custom_param_2": "Parameter 2",
"custom_param_3": "Parameter 3",
"dma_eea": true,
"dma_ad_personalization": true,
"dma_ad_user_data": true
}' "https://api2.branch.io/v1/open" -H "X-IP-Override: 1.2.3.4"
Example Responses
Organic response:
{
"session_id": "xxxx",
"randomized_device_token": "xxxx",
"link": "https://bnc.lt/j/adsf",
"data": "{\"+clicked_branch_link\":false,\"+is_first_session\":false}"
}
Organic response with sever_to_server_identity
set to true
in the request:
{
"session_id": "xxxx",
"randomized_bundle_token": "xxxx",
"identity": "xxxx",
"randomized_device_token": "xxxx",
"link": "https://bnc.lt/j/adsf",
"data": "{\"+clicked_branch_link\":false,\"+is_first_session\":false}"
}
Response when session was started by a non-Branch deep link:
{
"session_id": "823602214081710808",
"data": "{\"+non_branch_link\":\"https://branch.io/\",\"+clicked_branch_link\":false,\"+is_first_session\":false}",
"randomized_device_token": "823601870295755491"
}
Response when session was started by a Branch Deep Link:
{
"randomized_device_token": "823600311503935224",
"link": "https://example.app.link/X7OsnWv9TF",
"session_id": "429691081177874743",
"data": "{
"$canonical_url": "https://example.com/home?utm_campaign=test",
"$desktop_url": "http://example.com/home",
"$og_description": "My Content Description",
"$og_image_url": "http://lorempixel.com/200/200/",
"$og_title": "46D6D28E-0390-40E4-A856-BD74F34D24C8",
"+click_timestamp": 1503684563,
"+clicked_branch_link": true,
"+is_first_session": false,
"+match_guaranteed": true,
"custom_param_1": "blue",
"dma_eea": true,
"dma_ad_personalization": true,
"dma_ad_user_data": true,
"~campaign": "new launch",
"~channel": "facebook",
"~creation_source": 3,
"~feature": "sharing",
"~id": 429691043152332059,
"~referring_link": "https://example.app.link/X7OsnWv9TF",
"~stage": "new person",
"~tags": ["one","two"]
}"
}
Track Downstream Events
Every time the v1/open
Attribution API endpoint is called, the API will track an INSTALL
, REINSTALL
, or OPEN
event.
To track other events, you will need to use the relevant API instructions for the type of event you want to track:
Commerce Events (such as
PURCHASE
andADD_TO_CART
)Content Events (such as
SEARCH
andVIEW_ITEM
)Lifecycle Events (such as
SUBSCRIBE
orLOGIN
)Custom Events (all other events you want to track)
When tracking these downstream conversion events, please address the following items:
If a request is made from the device, Branch will automatically retrieve the IP address from the request. If the request is made from a server, the user's IP address must be set via the
X-IP-Override
header.Set the device's user agent in the
user_data.user_agent
request body parameter.For events that occur in your iOS app, populate the device ID with the IDFA (or fallback to the IDFV). For Android apps, populate the device ID with the GAID (or fallback to android_id).
For events that occur in your web app, retrieve a browser fingerprint via the Branch Web SDK. Include this in the event call.
Populate the
developer_identity
property whenever a persistent user ID is available. Please view our guide on best practices for user IDs.