Catalog API

Table of Contents


Overview


Digital Turbine's Catalog API provides a feed of all the information currently available on the Via Manual Campaigns page

This will allow publishers to automate:

  • Getting Digital Turbine's campaigns setup in their systems
  • Checking status of campaigns, campaign changes, and budgets

This is a restful API that must be called programmatically, returning JSON.

Authentication


The Catalog API uses "Basic Authentication" over SSL to authenticate and authorize users, using your Via login credentials in the Authorization header.

<?php
$url = "https://via.appia.com/ext/api/campaigns/manual?siteId=####";
$creds = "example@appia.com:appia123";
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_HTTPHEADER,array('Authorization: Basic ' . base64_encode($creds)));
$result = curl_exec($c);
curl_close($c);
?>

Frequency


If you are requesting all campaigns, please request them no more than hourly, ideally at an arbitrary time (not exactly at the top of every hour)

If you are requesting information for specific campaign id's, please request them no more than once every 10 minutes.

Request


URL

https://via.appia.com/ext/api/campaigns/manual?siteId=####

Headers

ParameterRequiredDescription
Accept HeaderYes

Defaults to JSON and the most recent API version. Allowed values:

  • application/vnd.appia+json

  • application/vnd.appia-v1+json

AuthorizationYesSee Authentication section above

Request Parameters

ParameterRequiredDescription
siteIdYes

Defaults to all site IDs. Allowed value - any valid Site ID

ex. https://via.appia.com/ext/api/campaigns/manual/?siteId=#### 

campaignIdNo

Defaults to all campaigns. Allowed value - any valid Campaign ID

ex. https://via.appia.com/ext/api/campaigns/manual/99999?siteId=####

expand=creativesNoReturns the creative images for each campaign

Pagination

Listings are paginated. Request the next page by appending the "Next" url parameters that are returned in the response

Example

 

If the initial request url is: https://via.appia.com/ext/api/campaigns/manual?siteId=####  And the following is retuned at the end of the response "next": "campaigns/manual?siteId=####&offset=25&limit=25" The url for the next page of results should be https://via.appia.com/ext/api/campaigns/manual?siteId=####&offset=25&limit=25

 

Response


Data Returned

FieldDescription
campaignIdThe unique numeric id for the campaign
urlThe a unique url for this campaign, to access this API for only this campaign
nameDigital Turbine's name for the campaign
descriptionDigital Turbine's description for the campaign
status

Current state of the campaign:

  • ACTIVE - currently running and available, although daily caps may have been spent.
  • PAUSED - campaign has temporarily paused and is inactive
  • PENDING - campaign has temporarily paused and is inactive
  • EXPIRED - campaign has ended and is inactive
startDate

Date values will use ISO-8601 compliant short notation, either YYYY-MM-DD for dates or YYYY-MM-DD“T”HH:MM:SS for date time.

Example

  • Short Notation: 2014-02-20
  • Long Notation: 2014-02-20T16:02:05
endDate

Date values will use ISO-8601 compliant short notation, either YYYY-MM-DD for dates or YYYY-MM-DD“T”HH:MM:SS for date time.

Example

  • Short Notation: 2014-02-20
  • Long Notation: 2014-02-20T16:02:05
noteImportant notes about the campaign, usually regarding restrictions about where the campaign can run
impressionUrl

The url to use to report impressions for this campaign

http://ads.appia.com/v2/impressionAd.jsp?campaignId=9998&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&aaid=[USER_ADVERTISING_ID]&idfa=[USER_IDFA]

[YOUR_SITE_ID] - substitute your site_id that is running the campaign ex. siteId=9999

Optional, but recommended:

[USER_ANDROID_ID] - substitute the Android ID of the user viewing the campaign, if it is known ex. androidId=B77H823942an1234

[USER_ADVERTISING_ID] - substitute the Google Advertising Id of the user viewing the campaign, if it is known ex. aaid=38400000-8cf0-11bd-b23e-10b96e40000d

[USER_IDFA] - substitute the IDFA of the user viewing the campaign, if it is known ex. idfa=236A005B-700F-4889-B9CE-999EAB2B605D

clickUrl

The url to use when a user clicks on an ad for this campaign

http://ads.appia.com/v2/clickAd.jsp?campaignId=9998&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&aaid=[USER_ADVERTISING_ID]&idfa=[USER_IDFA]&ts=[TIME_STAMP]

[YOUR_SITE_ID] - substitute your site_id that is running the campaign. ex. siteId=9999

[TIME_STAMP] - a unique timestamp for this click, used to break any caching. ex.ts=1395353746407

Optional, but recommended:

[USER_ANDROID_ID] - substitute the Android ID of the user viewing the campaign, if it is known ex. androidId=B77H823942an1234

[USER_ADVERTISING_ID] - substitute the Google Advertising Id of the user viewing the campaign, if it is known ex. aaid=38400000-8cf0-11bd-b23e-10b96e40000d

[USER_IDFA] - substitute the IDFA of the user viewing the campaign, if it is known ex. idfa=236A005B-700F-4889-B9CE-999EAB2B605D

unlimitedTotalBudget

If = false, then the campaign has a max budget set

remainingTotalBudget

If unlimitedTotalBudget = false, this is the amount of the budget currently remaining
remainingDailyCapThe amount of the dailyCap that remaining for today. Can be null if there is no daily limit.
dailyCapThe maximum daily budget allowed for this campaign. Can be null if there is no daily limit.  Campaigns are removed from API results when daily caps are met.
dailyCapTypeThe value returned will be either 'Network' for a daily cap that is shared across Digital Turbine's network, or 'Site' for a daily cap that is allocated to the siteId passed in the request.
bilingTypeValue returned will be either CPI or CPC. 
targetedLocationsArray of targeted countries, cities, or demographic market areas (DMAs)
excludedLocationsArray of excluded countries, cities, or demographic market areas (DMAs)
defaultPayout

The payout for the campaign, unless otherwise set with a sitePayout below.

This is the net payout. However, if "hasCustomRevShareAgreement" = true, the defaultPayout value is Gross for those publishers.

maxPayout (deprecated)Deprecated as of 6/10/2015 and will be removed from the API at a later date.  Use defaultPayout
sitePayouts (deprecated)

Deprecated as of 6/10/2015 and will be removed from the API at a later date.  Use defaultPayout

countries (deprecated)

Deprecated as of 2/29/2016 and will be removed from the API at a later date.  Replaced by targetedLocations & excludedLocations.

application

"identifier" - the unique identifier for the application being advertised in this campaign.

Either the packagename in GooglePlay or the bundleId for the Apple AppStore. ex. com.appia.sampleapp

categoryThe app store category for the app being advertised in this campaign
platformAndroid or iOS
maxOsPlatformThe most recent OS version allowed to see this ad
minOsPlatformThe oldest recent OS version allowed to see this ad
appStoreUrlThe url to the appstore page for the app being advertised
excludedDevicesSpecific device models that are not allowed to see ads for this campaign
excludedSitesA list of subsites that are not allowed to run the campaign (under the name field)
blockedSubSitesArray of excluded publisher sub sites.
creatives

An array of creative images for a campaign. Populated only when request parameter "expand=creatives" is used (this field will be null if the request parameter is not present).

For each creative image, the following information is returned:

  • width - the width of the image
  • height - the height of the image
  • url - the image URL
  • languageCode - the two-character language code
  • thumbnail - boolean value: true if this is a thumbnail image

 

Sample Response

 {
    "items": [
        {
            "campaignId": 9998,
            "url": "https://via.appia.com/ext/api/campaigns/manual/9998",
            "name": "Sample Campaign 1",
            "description": "This is a campaign sample for the API documentation",
            "status": "Active",
            "startDate": "2012-06-20T14:00",
            "endDate": null,
            "note": "No Individual Homescreen Ad Units",
            "impressionUrl": "http://ads.appia.com/v2/impressionAd.jsp?campaignId=9998&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&macAddress=[USER_MAC_ADD]&udid=[USER_UDID]",
            "clickUrl": "http://ads.appia.com/v2/clickAd.jsp?campaignId=9998&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&macAddress=[USER_MAC_ADD]&udid=[USER_UDID]&ts=[TIME_STAMP]",
            "unlimitedTotalBudget": false,
            "remainingTotalBudget": 5000.1,
            "remainingDailyCap": 700.8,
            "dailyCap": 800,
			"dailyCapType" : "Network",
            "billingType" : "CPI",
            "targetedLocations"[
                {
                            "id": 6252001
                            "countryIsoCode": "US"
                            "countryName": "United States"
                            "subdivision1Name": null
                            "subdivision2Name": null
                            "cityName": null
                            "dmaCode": null
                            "dmaName": null
                            "type": "country"
                }
			],
            "excludedLocations"[
                {
                            "id": null
                            "countryIsoCode": null
                            "countryName": null
                            "subdivision1Name": null
                            "subdivision2Name": null
                            "cityName": null
                            "dmaCode": 505
                            "dmaName": "Detroit, MI"
                            "type": "dma"
                }
			],
			"defaultPayout": 2,
            "maxPayout": 2,
            "sitePayouts": [],
            "countries": [
            {
                "name": "United States",
                "code": "US"
            }
        ],
            "application": {
                "url": null,
                "identifier": "com.appia.sample1"
            },
            "category": {
                "name": "Lifestyle",
                "description": "Lifestyle"
            },
            "platform": "Android",
            "maxOsPlatform": null,
            "minOsPlatform": "Android 2.3",
            "appStoreUrl": "http://play.google.com/store/apps/details?id=com.appia.sample1",
            "excludedDevices": [
                "Samsung Captivate SGH-i897",
                "Alcatel Venture",
                "HTC Knight PG06100",
                "ZTE N860",
                "Samsung Precedent SCH-M828C",
                "Samsung Galaxy Suit SGH-T499",
                "Pantech P8000",
                "Samsung Replenish M580",
                "T-Mobile myTouch 4G Slide",
                "LG P509",
                "LG P999",
                "Huawei M865C",
                "Huawei Ascend M860",
                "Samsung Galaxy Tab SCH-I800",
                "SE Xperia PLAY R800x",
                "LG Thrill 4G P925",
                "Samsung Repp SCH-R680",
                "LG Thrill 4G P920H",
                "Motorola Electrify"
            ],
            "excludedSites": [],
			"blockedSubSites": [
            {
                "id": 1,
                "siteId": 2710,
                "name": "subsitetestName"
            },
            {
                "id": 2,
                "siteId": 2710,
                "name": "subsitetestName2"
            }
           ],
		    "hasCustomRevShareAgreement": true
        },
        {
            "campaignId": 9999,
            "url": "https://via.appia.com/ext/api/campaigns/manual/9999",
            "name": "Sample Campaign 2",
            "description": "This is a campaign sample for the API documentation",
            "status": "Active",
            "startDate": "2012-07-03T13:00",
            "endDate": null,
            "note": "No Individual Homescreen Ad Units",
            "impressionUrl": "http://ads.appia.com/v2/impressionAd.jsp?campaignId=9999&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&macAddress=[USER_MAC_ADD]&udid=[USER_UDID]",
            "clickUrl": "http://ads.appia.com/v2/clickAd.jsp?campaignId=9999&siteId=[YOUR_SITE_ID]&androidId=[USER_ANDROID_ID]&macAddress=[USER_MAC_ADD]&udid=[USER_UDID]&ts=[TIME_STAMP]",
            "unlimitedTotalBudget": false,
            "remainingTotalBudget": 3605.6,
            "remainingDailyCap": null,
            "dailyCap": null,
            "defaultPayout": 0.8,
            "maxPayout": 0.8,
            "sitePayouts": [
            {
                "id": 2222,
                "url": null,
                "name": "Sample Site 2222",
                "payout": 0.95,
                "isNetPayout": null
            },
            {
                "id": 1111,
                "url": null,
                "name": "Sample Site 1111",
                "payout": 2.5,
                "isNetPayout": null
            }
        ],
            "countries": [
			{
                "name": "United States",
                "code": "US"
			}
		],
            "application": {
                "url": null,
                "identifier": "com.appia.sample2"
            },
            "category": {
                "name": "Health & Fitness",
                "description": "Health & Fitness"
            },
            "platform": "Android",
            "maxOsPlatform": null,
            "minOsPlatform": "Android 2.0",
            "appStoreUrl": "http://play.google.com/store/apps/details?id=com.appia.sample2",
            "excludedDevices": [],
            "excludedSites": [
            {
                "id": 1234,
                "url": null,
                "name": "Sample Site 1",
                "payout": null,
                "isNetPayout": null
            },
            {
                "id": 1235,
                "url": null,
                "name": "Sample Site 2",
                "payout": null,
                "isNetPayout": null
            }
        ],
            "hasCustomRevShareAgreement": true
        }
    ],
    "offset": 0,
    "limit": 2,
    "next": "campaigns/manual?offset=25&limit=25",
    "previous": "",
    "first": "campaigns/manual?offset=0&limit=25",
    "last": "campaigns/manual?offset=500&limit=25",
    "totalRecords": 504,
    "totalPages": 21
}


Error Handling

The API uses a hybrid approach to error handling, relying on custom 5xx HTTP Status Codes for a first error category, then providing additional detail in the response body using the following fields:

  • Related entity property: Additional detail on the property of the entity which caused the error. (Example: If the error was caused by an invalid email address, this field would be “emailAddress”)
  • User Level Message
  • Developer Level Message
  • More Info URL: Points to a website where the developer can find out more information to fix the issue.

 

Sample Error Response

 {
    "errorDetails": {
        "errorCode": 400,
        "sourceErrorEntity": "X is not a valid value for status",
        "userMessage": "There was an error with the parameters passed. Please verify and try again.",
        "developerMessage": "Cannot parse query; your argument X is not a valid value for status is invalid. ",
        "moreInfoUrl": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1"
    }
}

Example Request

 

<?php
$url = "https://via.appia.com/ext/api/campaigns/manual?siteId=1111";
$creds = "email:password";
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_HTTPHEADER,array('Authorization: Basic ' . base64_encode($creds)));
$result = curl_exec($c);
curl_close($c);
?>