Server-to-server events API

The Server-to-Server events API enables sending events that are not sent using the AppsFlyer SDK. For example, if you have both a web and mobile interface, you can record events from both mediums in AppsFlyer using the Server-to-Server events API. 

Server-to-Server events need to be prepared as follows:

  • Content-Type: Set as application/json.
  • URL endpoint:
    https://api2.appsflyer.com/inappevent/{app_id}
    • Android example:
      https://api2.appsflyer.com/inappevent/com.appsflyer.myapp
    • iOS example:
      https://api2.appsflyer.com/inappevent/id123456789
      Note: Ensure that the App ID in iOS contains a leading id before the ID. Failure to do so results in a valid 200 OK return code but the event is not registered.
  • Maximum size of the JSON payload: 1K 
  • The JSON payload must be passed as a string and the event value must be stringified.
  • The JSON payload must include the parameter: "af_events_api" :"true"
    This parameter ensures that the event is structured as a rich event to enable automatic mapping of the event values to various partners.

See the examples below.

Method: POST

Header - "authentication"= {dev-key}

The dev key is found in Dashboard > App Settings > Dev Key

iOSAndroid
{
  "appsflyer_id": {AppsFlyer Device ID }, // e.g. 1415211453000-6513894
  "idfa":{idfa},
  "customer_user_id": {customer_user_id}, // Customer User ID optional parameter
  "eventName": {The event name}, // e.g. "af_purchase"
  "eventValue": {A JSON containing a rich in-app event value - must be stringfied},
  "{

    \"af_revenue\":\"6\",
    \"af_content_type\":\"wallets\",
    \"af_content_id\":\"15854\"

  }",
  "eventCurrency": {Event currency}, // e.g "USD"
  "ip": {device IP},
  "eventTime": {Event timestamp in UTC +0}, // e.g "2014-05-15 12:17:00.000"
  "af_events_api" :"true"
}

 Note

All Reserved Character (https://tools.ietf.org/html/rfc3986#section-2.1) must be percent-encoded before the URI is formed.

Parameters

  • Mandatory parameters: appsflyer_id (AppsFlyer Device id), eventName, eventValue and af_events_api
  • Recommended parameters: idfa for iOS and advertising_id for Android.
    To send event postbacks of your users to external partners, these parameters are mandatory.
  • (Optional) EventValue can be with an empty value, i.e., "eventValue":"", (no space is needed)
  • (Optional)  IP address (ip) should be the IP of the mobile device (during the event occurrence)
  • (Optional) The customer user ID field (customer_user_id) is a user identifier parameter, mapped to the Customer User ID field in the Raw Reports. The Customer User ID SDK API attaches this value automatically to all SDK originated in-app events. Make sure to include this field will ALL your S2S events to enjoy the same functionality.

Preparing data for parameters

Backend logic is required in order to obtain certain values for the parameters mentioned above. Below you can find the recommended flow for obtaining these values:

Mapping AppsFlyer ID with customer user ID

AppsFlyer ID is a mandatory parameter when sending server to server in-app events. To make it easier for you to know which user performed which event, implement the flow below:

  1. Set customer user ID when the user installs the app
  2. Download raw data report for installs through export data or pull API
  3. Get AppsFlyer ID by matching the customer user ID in your internal systems with the customer user ID in the raw data report.
    Note: you can get the AppsFlyer ID of your users from the AppsFlyer SDK integrated in your apps (Android / iOS)
  4. Map AppsFlyer ID to customer user ID in your internal (important for future use)

Once you map AppsFlyer ID with your internal customer user ID, you can easily know which user performed which event. You can then obtain the AppsFlyer ID and other values (event value, event currency, event time etc.) and send the server to server in-app event.

Timing the events

Server-to-server events can be sent in real time or with an event time stamp.

You can use the optional eventTime parameter to specify the time of the event occurrence (in UTC +0 timezone). If the parameter is not included in the message, AppsFlyer uses the timestamp from the HTTPS message received.

eventTime format is: "yyyy-MM-dd HH:mm:ss.SSS" (e.g. "2014-05-15 12:17:00.000")

When sending events with timestamps, for these events to be recorded with their real-time stamps (when they actually took place), they must all be sent to AppsFlyer by 02:00 AM UTC +0 of the following day.

Events with past timestamps, which are not sent by 2:00 AM, are recorded under the time that they are sent.

Event with timestamp sent before 2am  utc +0

Event Triggered: 2 May @ 22:00

Event Sent to AppsFlyer servers: 3 May @ 01:00

Event is recorded in the platform under the real time that the event occurred (2 May @ 22:00).

Event with timestamp sent after 2 am utc +0

Event Triggered: 2 May @ 22:00

Event Sent to AppsFlyer servers: 4 May @ 09:00

Event is recorded in the platform at the time it is sent to the AppsFlyer server and not the time that the event occurred (4 May @ 09:00).

Event with future timestamps

Events sent with future timestamps are always recorded in AppsFlyer under the time they are sent to AppsFlyer, and not the event timestamp in the payload.

Timing events: visual timeline

Server-to-Server-Events.PNG

 Note

The maximum number of S2S requests is 60K per minute or 1K per second. Contact your Customer Success Manager if your requirements are different.

Service return codes

200
OK when the request has been processed by the AppsFlyer system.
401
unauthorized when the key provided in the authentication header is not the dev-key for this app.
400
Bad request when the request failed at least one of the validation criteria
500
Internal server error this indicates a server error

If your servers are protected by a firewall you will need to white list the incoming responses from AWS IP address Ranges to receive the return messages.

Request body example

{
  "appsflyer_id": "1415211453000-6513894",
	"advertising_id": "38412345-8cf0-aa78-b23e-10b96e40000d",
	"eventName": "af_purchase",
	"eventValue": 
	"{
		\"af_revenue\": \"6\",
		\"af_content_type\": \"wallets\",
		\"af_content_id\": \"15854\",
		\"af_quantity\" :\"1\"
   }",
	"eventCurrency": "USD",
	"ip": "1.2.3.4",
	"eventTime": "2014-05-15 12:17:00.000",
	"af_events_api" :"true"
}


In this case, AppsFlyer receives an S2S in-app event which represents a purchase event with revenue, as well as additional properties such as content type etc.

Special cases

Sending negative revenue

If you want to send an event with negative revenue (for events such as cancelled purchase or refund), you can specify negative value in the revenue parameter. For example:

{
  "appsflyer_id": "1415211453000-6513894",
	"advertising_id": "38412345-8cf0-aa78-b23e-10b96e40000d",
	"eventName": "cancel_purchase",
	"eventValue": 
	"{
		\"af_revenue\": \"-6\",
		\"af_content_type\": \"wallets\",
		\"af_content_id\": \"15854\",
		\"af_quantity\" :\"1\"
   }",
	"eventCurrency": "USD",
	"ip": "1.2.3.4",
	"eventTime": "2014-05-15 12:17:00.000",
	"af_events_api" :"true"
}

Sending events without event value

If you want to send events without event value, simply pass an empty string to event value: "event_value":""

AppsFlyer is then able, according to the advertiser's configuration, to send such rich in-app events to media sources for advanced targeting, optimization and audience creation purposes.

Fetching the AppsFlyer device ID

appsflyer_id is a mandatory parameter in server-to-server event messages. AppsFlyer uses this parameter to attribute the event to the original device and to the attributed media source. The ID can be obtained as follows:

 Tip

When testing S2S messages, if you're using raw data or push or pull APIs, look for the record with media source "s2s_test". This is your test device and its AppsFlyer Device ID is the ID you need.

Difference between organic and non-organic

When you send S2S in-app events, AppsFlyer automatically associates additional data with the events. The additional data comes from the install event that precedes the in-app events.

What this means is that some data that AppsFlyer associates with non-organic S2S in-app events, is not associated with organic S2S in-app events.

 Example

For example, if you compare raw data reports of non-organic and organic S2S in-app events, non-organic events contain data that organic in-app events do not.

Non-organic in-app events contain data about the media source, campaign, attributed touch type and attributed touch time.

Organic in-app events, on the other hand, follow an organic install. Organic install do not have data related to campaign, media sources or attributed touch type and time.

Was this article helpful?
4 out of 12 found this helpful