At a glance: InCost API, part of AppsFlyer ROI360, lets ad network partners programmatically send advertising cost data to AppsFlyer. Doing so provides advertisers with aggregate cost data from all their ad networks in one place.
InCost API
Ad network partners send detailed advertising cost using InCost API. AppsFlyer ingests the data making it available to advertisers and partners via reports, analytics, and an AWS S3 bucket.
Related reading: Cost-sharing options for ad networks
Implementation requirements for ad networks
Complete the steps in the sequence listed.
# | Action |
---|---|
1 | Fill out the InCost onboarding form. |
2 | Reach out to your AppsFlyer PDM and let them know you want to integrate InCost. |
3 | Make sure campaign hierarchies (campaign ID, adset ID, and ad ID) are included on your attribution links for more than 90% of your traffic. |
4 |
The ad network admin gets the AppsFlyer V2.0 API token in the AppsFlyer dashboard. |
5 |
Complete InCost integration and testing as described in this article. |
6 |
|
7 |
Request advertisers to enable get cost data in the cost tab of your AppsFlyer integrated partner page. |
Process for sending and verifying data
- Prepare cost data for submission in a JSON as detailed in this article.
- Take into consideration the app time zone to align cost data dates with that of the app.
- Use InCost uploader to send the cost.
- Collect and store the job ID that InCost returns.
- After 2 minutes, use the job status method to verify the job has completed successfully.
- Jobs that complete successfully have an applied status. It can take up to 5 hours for data to appear in the AppsFlyer dashboard.
InCost API methods
Method | Description | Method |
---|---|---|
Get app permission list |
|
GET |
InCost upload |
|
POST |
Get job status |
|
GET |
InCost API basics
Path |
|
Path parameters (mandatory) |
|
Headers |
|
Authorization |
|
Date limitations |
|
Rate limitation |
API call-rate limited per ad network account (token):
|
InCost upload method
Use the InCost upload method to report cost.
API requests must comply with the following:
- One app per API call.
- Data format is JSON as depicted in the Curl example.
- Each JSON contains the campaign cost details for a specified date.
- Mandatory fields must be populated. Meaning, don't send empty fields.
- Media source is restricted to media sources associated (registered under) your ad network account. Get the list from your partner development manager.
- If there are fields that are not part of your campaign cost reporting hierarchy, don’t include them in your request. For example, adset ID, asset name, ad ID, ad name.
Path |
POST |
Path parameters (mandatory) |
|
Response | Provided |
Cost fields in the JSON
Field |
Mandatory |
Remarks |
---|---|---|
date |
Yes |
|
app_id |
Yes |
|
media_source |
Yes |
|
af_prt |
No* |
|
campaign_id |
Yes |
|
campaign_name |
Yes |
|
adset_id |
No* |
|
adset_name |
No |
|
ad_id |
No* |
|
site_id |
No |
|
ad_name |
No |
|
geo |
No |
|
currency |
Yes |
|
spend | Yes |
|
channel | No |
|
keywords | No |
|
* See the remarks column, as in some cases you must send this field. |
InCost upload Curl example
curl --location --request POST 'https://hq1.appsflyer.com/api/incost-uploader/v1/data/app/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ' \
--data-raw
'[{
"date": "2020-02-28",
"app_id": "com.cost.app",
"media_source": "example_int",
"campaign_id": "1236678",
"campaign_name": "example_campaign",
"geo": "ZA",
"currency": "ZAR",
"spend": 123.12
},
{
"date": "2020-02-29",
"app_id": "com.cost.app",
"media_source": "exmaple_int",
"campaign_id": "123",
"campaign_name": "Campaign123",
"geo": "IL",
"currency": "USD",
//make sure the value for "spend" does NOT have quotation marks, as indicated below.
"spend": 2400
}]'
Get job status method
The method returns the status/error message of a previously submitted send cost data call in a JSON.
Path |
Make sure to set the method to GET . |
Path parameters (mandatory) |
|
Job-status
Status | Description |
---|---|
Applied |
|
Job in progress | Job is not yet complete. |
Validation error |
|
Error processing data | AppsFlyer system problem. Wait 15 minutes and try again. If the error persists, contact AppsFlyer technical support. |
curl --location --request GET 'https://hq1.appsflyer.com/api/incost-jobstatus/v1/data/app/<app_id_placeholder>/job/<job_id placeholder>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer '<api_token_placeholder. Note the token has more than 700 characters.>'
get job status responses examples
Status | Description |
---|---|
Applied |
|
Invalid date |
|
Testing InCost integration
The following apps are available in your dashboard for testing:
- Android: com.cost.app
- iOS: id888123456
To test cost integration:
- [Optional] End-to-end-attribution test:
- Prepare attribution links for the test applications using the attribution-link template configured for your integration.
- Generate attribution traffic for clicks, including campaign, adset, ad ID so that the cost data can match with the click data.
- Generate a click for the test applications, using the attribution-link template configured in your integration. Make sure to populate macros, as if this was real traffic.
- [Mandatory] Basic cost integration:
- Prepare test data.
- Submit the data, use InCost uploader.
- Record the job ID that returns.
- Wait 2 minutes.
- Verify that no errors were found. Use get job status.
Note: Because there is no attribution traffic (clicks), the matched row score will be less than 100. - If errors are found, make corrections, and submit again.
- Cost data will display in the dashboard within 5 hours, verify that the data is correct.
Error messages
The following error codes and message return.
Category | InCost error code | Error message |
---|---|---|
Rate Limit | ic111 | Exceeded API-rate limit. Wait one minute and try again. |
Data Validation | ic211 | Incorrect date format. Use the format yyyy-mm-dd. |
Data Validation | ic212 | XXX is in the future. Future dates are not allowed. |
Data Validation | ic213 | media_source XXX was not found. Verify and resubmit. |
Data Validation | ic215 | app_id was not found. Verify and resubmit. |
Data Validation | ic217 | Insufficient cost amount. Spend amount must be greater than 0. |
Data Validation | ic218 | Reserved |
Data Validation | ic219 | Geo (country) code was not found. Use an ISO 3166 2-letter code. |
Data Validation | ic220 | Currency code was not found. Use an ISO 4217 2-letter code. |
Data Validation | ic221 | Request had 2 or more currencies. Send 1 currency per app per request. |
Data Validation | ic222 | Request had 1 or more duplicate records. Remove file duplication/s. |
Data Validation | ic224 | Job ID was not found. Verify and resubmit. |
Data Validation | ic225 | Status was not found. Verify and resubmit. |
Data Validation | ic226 | Incorrect count value. Use a number between 1-1000. |
Data Validation | ic227 | Incorrect cursor. Use the cursor from the last response. |
File Size | ic311 | File exceeds 25MB. Split the file into multiple requests. |
Authentication | ic414 | Partner account lacks permissions. Partner account must be enabled to upload cost for this app. |
Formatting | ic416 | Incorrect JSON format. Verify and resubmit. |
General error | ic300 | There is a server issue. Try again in 10 minutes. |
Authorization | ic415 | App and job IDs don't match. Verify and try again. |
Data Validation | ic228 | Request had 2 or more app IDs; the maximum is 1 per request. Split the request and resubmit. |
Data Validation | ic229 | Request and URL app IDs don't match. Verify the app IDs match and resubmit. |
Data Validation | ic230 | |
Data Validation | ic231 | Request included data of varying granularity; the data must be uniform. If varying granularity is required, split the request and resubmit. |
Data Validation | ic232 | Some request data was outside the allowed time range; the data must be from the last 90 days. Verify the data and resubmit. |
Data Validation | ic241 | Incorrect click values. Use positive numbers only. Verify and resubmit. |
Data Validation | ic242 | Incorrect impression values. Use positive numbers only. Verify and resubmit. |
Data Validation | ic243 | Incorrect time zone code. Use a valid AppsFlyer code per http://www.thefulllist.com/. |
Authorization | ic301 | Incorrect agency name. Use a valid agency name in the URL, then make an upload request. |
Authorization | ic302 | App ID is not enabled for ROI360. The agency can only share cost data with an advertiser who has the ROI360 feature. |
Authorization | ic302 | App ID is not enabled for cost integration. The agency must enable the cost toggle, then resend the data. |
Data Validation | ic244 | Incorrect partner name. Enter a valid name in the partner field and resubmit. |
Data Validation | ic245 | Campaign ID can't be sent in the request. Remove the campaign ID and resubmit. |
Data Validation | ic246 | Campaign name was not found. Verify and resubmit. |
Data Validation | ic248 | Request contain invalid field names, or missing mandatory fields. |
Enabling get cost data by the advertiser
- Advertisers enable Get Cost Data in the AppsFlyer dashboard using the procedure that follows.
- The advertiser must enable get cost data for each app individually. Verify that you are enabled by using get InCost enabled app list API.
To enable get cost data from the ad network:
- In AppsFlyer, go to Integration > Active Integrations.
- Select the integrated partner (ad network name in AppsFlyer).
- Go to Cost tab.
- Enable Get Cost Data.
AppsFlyer is permitted to record cost data from the partner.
For the avoidance of doubt, don't give your API token to the ad network. They don't need it.