AppsFlyer - Receive Callback
Enterprise
This endpoint is part of Countly Enterprise. To get access, contact sales or compare versions. Existing customers can reach the support portal with questions.
Endpoint
/i/appsflyer
Overview
Receives AppsFlyer Push API payloads and attempts to attribute them to users by appsflyer_id.
If a user with a matching custom.appsflyer_id exists, attribution is applied immediately.
If no matching user exists, the payload is stored for deferred attribution.
Authentication
Authentication Methods:
- App key parameter:
app_key
Permissions
- No admin/API-key permission is required.
- Request is accepted only when the app is valid and not paused.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
app_key | String | Yes | Application key used to resolve the target app. Matches the app's main key or any of its additional keys. |
appsflyer_id | String | Yes | AppsFlyer device identifier used for user matching. Must not be empty. |
event_name | String | Yes (one of three) | AppsFlyer event name. event_type or event are accepted instead. |
event_type | String | Yes (one of three) | Used when event_name is not provided. |
event | String | Yes (one of three) | Used when neither event_name nor event_type is provided. |
media_source | String | No | Media source from the payload. |
campaign | String | No | Campaign name from the payload. |
| Other AppsFlyer fields | String | No | Any other field in the request (for example af_ad, af_adset, af_c_id, install_time, is_retargeting) is stored and attributed as sent. |
Examples
Example 1: Install callback
curl "https://your-server.com/i/appsflyer?app_key=YOUR_APP_KEY&appsflyer_id=1700000000000-1234567&event_name=install&media_source=Meta&campaign=Spring_Campaign"
Response
Success Response
Immediate attribution example:
{
"result": "Success",
"status": "attributed"
}
Deferred attribution storage example:
{
"result": "Success",
"Records inserted": 1,
"document": {
"appsflyer_id": "1700000000000-1234567",
"event_name": "install",
"media_source": "Meta",
"campaign": "Spring_Campaign",
"app_id": "6991c75b024cb89cdc04efd2",
"cd": "2026-10-01T12:00:00.000Z",
"_id": "6a1f0c2e9b1d4a0012ab3456"
},
"user": null
}
Response Fields
| Field | Type | Description |
|---|---|---|
result | String | Result message (Success on successful processing). |
status | String | Attribution status (present on the immediate attribution path). |
Records inserted | Number | Number of inserted records in the deferred path. |
document | Object | Stored callback payload in the deferred path: all request parameters except app_key, plus app_id and the receive time cd. |
user | Object or null | Deferred path only. null when no user has this appsflyer_id, or the matched user object when that user has no device ID (did). |
Error Responses
- HTTP 400 - Missing app key:
{
"result": "Missing parameter \"app_key\""
}
- HTTP 400 - App not found:
{
"result": "App does not exist"
}
- HTTP 400 - App paused:
{
"result": "App is currently not accepting data"
}
- HTTP 400 - Missing AppsFlyer ID:
{
"result": "Missing required parameter \"appsflyer_id\""
}
- HTTP 400 - Missing event name:
{
"result": "Missing required parameter: one of \"event_name\", \"event_type\", or \"event\""
}
- HTTP 400 - User lookup failure:
{
"result": "Error finding user: <error>"
}
- HTTP 400 - Deferred save failure:
{
"result": "Error saving data: <error> <payload>"
}
Behavior
- Validates
app_keyand resolves the app. - Rejects paused apps.
- Validates that
appsflyer_idand an event name are present. - Tries to find a user by
custom.appsflyer_id. - If a matching user with a device ID is found, attributes immediately and returns
status: attributed. - Otherwise (no user, or a user without a device ID), stores the payload in
countly.appsflyerand returns insert details.
When attribution succeeds, the event is recorded as appsflyer_<event name> and the fields are written to the user's custom properties (with first_<field> copies where missing).
Limitations
app_keyis mandatory.appsflyer_idand one ofevent_name,event_typeoreventare mandatory.- Paused apps reject ingestion.
Related Endpoints
Implementation details
Database Collections
| Collection | Used for | Data touched by this endpoint |
|---|---|---|
countly.apps | App configuration and metadata | Resolves the app by app_key and checks whether it is paused. |
countly.app_users{appId} | Per-app user profiles | Looks up users by custom.appsflyer_id. |
countly.appsflyer | Deferred attribution payloads | Stores unmatched payloads. |