Web Server-to-server events API for PBA (Web-S2S)

At a glance: Use the Web Server-to-Server (Web-S2S) events API to report events and conversions to PBA that aren't reported by the Web SDK.


Web Server-to-server events API for PBA

The Web-S2S API for People-Based Attribution complements the Web SDK allowing marketers to report events occurring on their websites but outside the scope of the Web SDK. For example, a visitor to the website (a web user), triggers an online payment event, processed by backend systems. After processing, the backend, using the S2S API, reports the event to AppsFlyer.

Events sent by the S2S API:

  • are recorded similarly to events reported by the Web SDK
  • are included in PBA dashboards if set as conversion events
  • populate PBA raw data with event_source field set to web S2S

API use instructions

Create your API call using the sections that follow. 

Help us to help you

Dear Developer, 

We know (we too are developers) that it's easy to skip or miss important details in API guides. So here are some tips to avoid common mistakes. We'd like your feedback about this article, good and bad. To send feedback, at the footer of the article, click "was this article helpful."

Checklist of common mistakes

No. Item Remarks
1 Unique user ID
  • Strive to give us the best unique user ID available. This has a significant impact on data analysis.
  • Best practice is to send the customerUserId. If it's not available send the afUserId being the website cookie ID set by the WebSdk.
  • At any time you associate your customer user ID (CUID) with the afUserId send a setCuID() message with both IDs.
2 Timestamp
  • We suppress your timestamp if the event arrives late. Meaning events having a Monday timestamp must arrive prior to Tuesday midnight UTC.
  • Timestamps are UTC-based. If necessary convert from local time to UTC time before populating the parameter
3 Revenue and currency You must populate eventRevenueCurrency and eventRevenue even if they are contained in the eventValue. Do so because we use them in our dashboards.

API basics

API implementation requires the following credentials available in the dashboard:

  • Bundle ID (aka brand bundle ID)
  • Web Dev key

To get the credentials: 

  1. In AppsFlyer, from the top menu, select My Apps > View brand bundles.
    The list of bundles display.
  2. Copy and record the appropriate:
    • Brand bundle ID
    • Web dev key

Web S2S API basics



  • bundleId: Is the app bundle ID available in the dashboard. 
  • method being one of the following:
    • event: send for reportable backend events
    • setCuId: send when associating afUserId with your CUID
HTTP method POST
Accepted content type application/json 
JSON payload limitation 

JSON payload size: maximum 1KB

Rate limitation

POST limitation volume: 60,000 POSTs per minute. To increase the limit, contact your CSM.


setCuId method

Method name


Use case 

On associating a CUID with a visitor to your website. For example, any time you match the web afUserId with your customer user ID. Doing so enables PBA to match data from various sources. This is similar to setCustomerUserId on the website.

Method path



The JSON payload consists of the parameters listed here. All parameters are mandatory.

 Curl example setCuId

curl --location --request POST 'https://webs2s.appsflyer.com/v1/bundleId/setcuid' \ --header 'Accept-Encoding: application/json' \ --header 'Content-Type: application/json' \ --data-raw '{ "customerUserId": "1234567890abcdef", "afUserId":"9999999-f848-4963-a091-568f0bf9a361", "webDevKey" : "99999999-9999-9999-9999-999999999999"}

Event method

Method name


Use case Send
Method Path


 Detailed information Event method details section of this article contains payload details, Curl example, Python example and testing suggestions.

Event method details

Payload parameters

Payload parameters are divided into user identifiers and event parameters. 

  • User ID: You must send at least one user ID parameter.
  • Event: Send the mandatory parameters and optional parameters as needed.

User identifier parameters (send at least one parameter)

User ID Parameter  Description


Customer user ID (CUID) is a unique identifier set by you.

  • Use the identical identifier for events reported by any means to AppsFlyer. Meaning the same identifier is used in the Web SDK, mobile SDK, and S2S APIs.
  • Web SDK customer user ID
  • Format: String
  • Example: "customerUserId" : "663274"
  • Populates raw data field: customer_user_id


The unique user ID assigned by the Web SDK to every user that visits your website. You will need to pass the cookie value to your backend servers.

  •  Cookie details:
    • Name: afUserId
    • Value: set afUserId to this value
    • Domain: website-domain
  • Example: "afUserId" : "unique_cookie_uuid"
  • Populates raw data field: af_web_id

Event parameters

Parameter Name Mandatory Description



Populate using the web dev key available on the Dashboard.

  • Example:"webDevKey" : "ffffffff-ffff-ffff-ffff-ffffffffffff"
eventType Yes

Event attribute identifier for internal use by AppsFlyer. Always set to EVENT.

  • Example: "eventType" : "EVENT"
eventName Yes
  • We use this parameter to differentiate conversion and non-conversion events using the event conversion list set by the marketer in PBA settings. 
  • Ensure that you populate it with values consistent to the marketer's conversion logic.
  • Format: String
  • Example: "eventName" : "web_purchase"
  • Populates raw data field: event_name
timestamp No

Time the event occurred in milliseconds. Send as a Unix timestamp having 13 digits.

  • If no timestamp is sent, the time is set using the server time. 
  • Events arriving late are timestamped using the current server time. Late means arrival after midnight UTC on the day following the event. For example, an event occurring on Monday must be processed before midnight UTC Tuesday. 
  • Events having a timestamp in the future (relative to the current server time) are timestamped with the server time.
  • Format: Int
  • Example: "timestamp" : 1584835200123
  • Populates raw data field: event_time
eventValue No
Map of event parameters describing the event. Use this parameter to send rich in-app events like product SKU, line item price.
  • Note about revenue! You can populate this parameter with revenue details. In addition, you must populate eventRevenue, and eventRevenueCurrency.
  • Format: JSON
  • Example: To send SKU ABC123, having a blue color and a unit price of $3.99 set eventValue to:
    {"Purchase": {"sku" : "ABC123", "color": "blue", "unit_price":3.99,"currency": "USD"}}
  • Limitation: 1000 characters. Do not exceed this; it will be truncated. 
  • Populates raw data field: event_value
eventRevenueCurrency No

Currency code of a revenue event, being a three-character ISO 4217 currency code.

  • Default: USD
  • Format: String
  • Example: "eventRevenueCurrency" : "EUR"
  • Populates raw data field: event_revenue_currency
eventRevenue No 

Revenue (monetary value) assigned to an event.

Note! If revenue is reported in eventValue, report it also in eventRevenue and populate eventRevenueCurrency. 

  • Negative values permitted. For example, a refund.
  • Format: Float 
  • Example values: 1 1.2 1234.20 -1234.20
  • Populates raw data field: event_revenue
eventCategory No  This parameter is deprecated and will be removed from the system at a future date. Use eventValue instead.
eventLabel No 

This parameter is deprecated and will be removed from the system at a future date. Use eventValue instead.

referrer No

HTTP referrer

  • Format: String
  • Example:"referrer" : "https://www.google.com/"
  • Populates raw data field: http_referrer
userAgent No 

User-agent request sent by the browser to the server.

  • Where possible send this value as it assists in determining the device type. 
  • Format: String
  • Example: "userAgent" : "Chrome/80.0.3987"
  • Populates raw data field: user_agent
ip No

User IP address

  • Where possible send the value of this field. It assists in determining the geo-location of the user.
  • Format: String
  • Example: "ip": ""
  • Populates raw data field: ip

Curl example

curl --location --request POST 'https://webs2s.appsflyer.com/v1/bundleId/event' \
--header 'Accept-Encoding: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
	"customerUserId": "1234567890abcdef",
    "webDevKey" : "99999999-9999-9999-9999-999999999999",
    "ip" : "",
	"timestamp" : 1234567890123,
	"eventRevenueCurrency" : "EUR",
	"eventRevenue" : 1234.56,
		"eventValue": {
		 "shoes": "color",
		 "quantity" : "3",
		 "Revenue" : "1234.56",
		 "Currency" : "ZAR"


Python example

''' using the requests python package, install using pip install requests  '''
import requests
url = "https://webs2s.appsflyer.com/v1/bundleId/event"
payload = {
    "customerUserId": "1234567890abcdef",
    "afUserId": "9999999-f848-4963-a091-568f0bf9a361",
    "webDevKey": "99999999-9999-9999-9999-999999999999",
    "ip": "",
    "eventType": "EVENT",
    "timestamp": 1234567890123,
    "eventName": "my_web_event",
    "eventRevenenuCurrency": "EUR",
    "eventRevenue": 1234.56,
                "shoes": "color",
                "quantity": "3",
                "Revenue": "1234.56",
                "Currency": "ZAR"
headers = {
    'Accept-Encoding': 'application/json',
    'Content-Type': 'application/json'
response = requests.request("POST", url, headers=headers, json=payload)


For testing purposes, send several events as follows:

  1. Send an event.
  2. Ensure that you get a 200 OK return code. If not, take corrective action using the return codes and error messages.
  3. Wait for several hours after midnight UTC to see the reported event in PBA raw data. You must wait because PBA data is processed once a day. 

Additional information

Getting the Web Dev Key

 To get the Web Dev Key:

  1. In AppsFlyer, go to the My Apps tab.
  2. Click View brand bundles.


  3. Copy the required Web Dev Key. 

Extracting the Web SDK afUserID

  • The afUserId, is a unique identifier, set by the Web SDK when a user first visits your site.
  • If you need afUserIduse one of the methods that follow.

Get afUserId from the HTTP cookie header

  • The afUserId is sent by the visitors browser on calls to your site.
  •  Extract it from the HTTP cookie header if needed.

Viewing afUserId in the visitor's browser

  •  View the afUserId in the visitor's browser, for troubleshooting and debugging purposes.
  • For it to be available, the visitor needs to have first visited a page having the Web SDK at least once. 
  • The cookie containing afUserId is a first-party cookie in relation to your domain.
  • The procedure that follows was prepared using Chrome 81. There may be some differences between various browsers and operating systems.

To get the afUserId from the visitor's browser:

  1. In your browser, go to your website.
  2. Right-click, select Inspect
    The browser's inspect element window opens.


  3. Go to the (A) Application tab.
  4. In the side menu, (B) expand Cookies.
  5. Select your website. If it does not display, refresh the browser.
  6. In the (C) filter field, enter afUserId
    The value of afUserID displays. 

Response codes

Response code Message How to Handle
200 OK  
404 Not found
  • Check the endpoint 
  • Check that the Bundle ID is correct
400 Bad request
  • There is an error in the JSON. See the error message for details. 


  • Symptom: HTTP return codes do not return
    Solution: Allowlist AppsFlyer servers.

Release notes

Web SDK release notes
Date  Endpoint Version* Notes
2020-05-12 1  Initial release
2020-05-24 1  
* Version number relates to the endpoint version number. https://webs2s.appsflyer.com/v1/method