Untargeted Offer API
Offer API Overview
The Offer API allows publishers to pull offers and display them natively on their website or app. This integration type can be used in a variety of UIs and works especially well for featured placement sections. The Offer API returns all offers (both single and multi-reward) by default, along with goal-related data and a unique ID for each offer.
The Offer API returns all available offers and allows publishers to control sorting and targeting of offers for their players.
The Offer API is not designed to be called in real-time client scenarios.
We recommend you call our API every 15 minutes to ensure your players have access to the most up-to-date offers. If your app is polling the API more than 60/min this will result in an error. NOTE: Offers may return to the feed after they have been removed due to day capping/temporary pausing.
Integration
Integrate the Offer API Using the Following Steps
Requirements
Before beginning, you:
- Must have an active AdGem account
- Must have added at least one property to your account
- In order for your app to have access to AdGem's offers, you will need to ensure your app is approved in the AdGem system. App setup and approval instructions can be found HERE. By default, your app will not be enabled on offers until you have completed the intital integration steps. Please reach out to your dedicated Publisher Support Advocate with any questions.
Related Readings
For a complete picture of the Offer API integration with your property, please read these articles:
- Essentials Overview
- Offerwall Promotions
- [ API Integration] (this page)
Step 1 - Security Token Request
To get started with the Offer API, you will first need to add your property using the AdGem Publisher Dashboard.
Once you have added your property, reach out to an AdGem team member to request a security token and to gain access to AdGem offers.
Step 2 - Customize Offer Experience
Because the Offer API integration has not been fully configured in the Publisher Dashboard yet, wait for the go-ahead from an AdGem team member before proceeding.
Although this is not the offerwall web integration, you are required to configure your app's offerwall settings.
-
Locate the property:
- Click on Properties & Apps in the left nav.
- Find the property that is using the Offer API integration.
-
View offerwall information:
- Click Options > Edit.
- Click on the Offerwall tab.
-
Update the following fields in the form:
- Currency Name - Singular (required)
- Currency Name - Plural (required)
- Currency Multiplier (required; update, if applicable)
- Offer Filters (update, if applicable)
Step 3 - Configure the Offer API Link
Configure your Offer API request:
GET /v1/offers
Host: https://offer-api.adgem.com
Accept: application/json
Authorization: Bearer {ADGEM_APP_SECURITY_TOKEN}
{ADGEM_APP_SECURITY_TOKEN} with the security token value that you received in Step 1 - Security Token Request.
Endpoint Structure
All calls to the Offer API require, at minimum, the ADGEM_APP_SECURITY_TOKEN.
Parameter |
Type |
Required |
Description |
|---|---|---|---|
country_codes |
string | Optional | Optionally, you can filter offers by country code(s). Multiple country codes can be included when delimited by a comma. All codes must be in CAPS. For example, country_codes=US,GB,FR,DE. |
platform |
string | Optional | Optionally, you can filter offers by a platform. The following values are accepted: ios, android, web, or all. Only one of these options can be set as this parameter's value. Multiple values are not allowed. For example, platform=ios. |
categories |
string | Optional | Optionally, you can filter offers by categories. The following values are accepted: app, trial, survey, paid, free, and user_info_request. Multiple categories can be included when delimited by a comma. For example, categories=app,survey.NOTE: Using the categories parameter in the request will override the app’s Offer Filters configured in the Publisher Dashboard. |
tracking_types |
string | Optional | Optionally, you can filter offers by tracking types. The following values are accepted: CPI, CPE, CPA, Survey, and CPC. Please note that all values are case sensitive. These values can be combined in the call to select multiple tracking types. For example, tracking_types=CPI,Survey. |
sort |
string | Optional | Optionally, you can sort offers by stats values in either ascending (asc) or descending (desc) order. Available values: epc. Please note that all values are case-sensitive. For example, sort=epc.asc or sort=epc.desc. |
per_page |
integer | Optional | Paginate the response by limiting the number of offers per page. Accepts values from 1 to 100. For example, per_page=50. When provided, the response includes a pagination object with page metadata.NOTE: If per_page is not included in the request, all offers will be returned in a single response with no pagination metadata. |
page |
integer | Optional | The page number to retrieve when using pagination. Defaults to 1 if not provided. Requires per_page to be set. For example, per_page=50&page=2. |
Best Practices
Polling the API
We highly recommend that you actively poll the Offer API every 5 to 10 minutes to get the latest campaign-level information such as caps and price adjustments.
Leveraging the Schema - Tips
-
Utilizing the
- The
network_epcfield can be extremely valuable to use as a publisher. This value is the network-wide earnings per click (EPC) at which a campaign is actively performing on AdGem. If, for example, you are presenting offers in a list to your users, you could leverage thenetwork_epcfield by ordering your offers from highest to lowest EPC values on the list.
Including the - We highly recommend that you include
payoutin your postback response so that you can track the accurate decimal amount of revenue earned from the user completing the offer. Thepayoutfield should be used to validate any release of a user's rewards as this is the official and truest amount AdGem will pay for each transaction.
Using the - We highly recommend that publishers ensure that all information included in the
disclaimerfield is made visible to users interacting with offers. AdGem Player Support will enforce offer attribution windows as set by our advertisers, making it important that your users are aware of this completion window prior to offer engagement.
Utilizing the - The
attribution_window_daysfield can be dynamically used in your native UI to display how many days the user has to complete the offer, as well as the remaining days from the offer start.
What is the Offer ID?
- An offer is the intersection between an app and a campaign in AdGem. The offer ID serves as a unique offer version identifier as it appears in the call schema. This means that if campaign
123is available in apps456and789, the offer ID for campaign123and app456will be different from the offer ID for campaign123and app789. Also, this ID will change across all apps when a specific type of change to the campaign is made (see below). This will also allow you to determine which version of the offer your users had initially interacted with. - An offer has a set of contract terms. If there is a change to the contract terms, AdGem will generate a new offer ID value. If a user clicks on an "old" offer ID, it then locks the user into the original contract terms. The offer contract changes if any of the following events occurs:
- The
total_payout_usdfield value changes. - The
total_amountfield is updated. - Changes to any of the
goalsobjects. - The
is_multi_rewardfield changes. - The targeting rules for the campaign change; in other words, changes to the
geo_targeting,device_targeting, oros_targetingfields.
- The
- You may find that some offers in your API call do not have a
geo_targeting.countriesobject. In these instances, you should note that these offers will have more precise targeting, often at the region or state level and should not be shown globally, nor nationwide. This will be shown via thegeo_targeting.statesobject.
network_epc Field
payout field in your Postbacks
disclaimer field for Native Offers
attribution_window_days Field
Step 4 - Service Response
Handling the Response
The response from the Offer API will include an array of offers available for your property. If per_page is not provided, all offers are returned in a single response. If per_page is provided, a single page of offers is returned along with a pagination object containing page metadata. Each offer will include details and information necessary for you to display the right offers to the appropriate users. In addition, the call response will also include a links object for access to our AdGem Support Portal.
Service Response
###IMPORTANT: Replacing playerid
The offerwall url must be modified to replace the dummy parameter {playerid} with your parameter that represents the unique player as used internally in your application. This identifies the player so that virtual currency can later be attributed to their account via the callback request. The player ID has to remain constant (for the unique player in your application) so that players are prevented from completing an offer more than once, and are able to receive their rewards.
NOTE: Missing playerid
Please note that tracking url clicks that do not contain a playerid value will be redirected to a 404 error page.
REQUIRED: Player ID Structure
All playerid values that you return should only use lowercase alpha numeric values. A good playerid value may look like: abc-123-efg-456, but should NOT look like: aBc-123-Efg-456.
Your playerid should be alphanumeric and should not include emojis or any special characters. The max character limit for the playerid value is 256.
Offer API Response Endpoint Structure
Field |
Type |
Example |
Description |
|---|---|---|---|
id |
string | 123456789012345678 |
A unique value for the specific offer version |
campaign_id |
integer | 107 |
A unique identifier for this specific offer |
name |
string | Lords Mobile |
The offer name |
store_id |
string | 1384664077 |
The Google Play or App Store unique namespace or package name |
tracking_type |
string | CPI |
The pricing model of this type of offer (CPI, CPE, CPA, CPC) |
total_payout_usd |
number | 0.25 |
The amount of USD earned for completing a single offer or completing all goals for multi-reward. For Multi-Reward Offers, the total_payout_usd is the sum each goal's potential payout. |
total_amount |
integer | 25 |
The amount of virtual currency awarded to the user for fully completing an offer. This is calculated according to the campaign payout and the exchange rate you have set in the AdGem Publisher Dashboard for your offerwall. - Single Rewarded Offers display the potential earnings a user can make for completing the offer. - Multi-Reward Offers display the sum of potential earnings the user can earn by completing all the goals. |
start_datetime |
timestamp | 2018-05-24 16:34:45 |
The datetime this offer was set to active status |
is_multi_reward |
boolean | true / false |
Indicates that the offer is Multi-Reward or Single Reward. - true means this offer contains multiple goals for the player to complete.- false means this offer only has one goal/event for the player to complete. |
completion_difficulty |
integer | 1 |
Indicates the level of difficulty in completing an offer. Please reference the Completion Difficulty Scale for more information. |
is_featured_campaign |
boolean | true / false |
Indicates if this offer is featured |
campaign_vertical |
string | Games General |
The offer vertical |
creatives |
object | The details used to create AdGem offers in your native UI | |
creatives.name |
string | Lords Mobile |
The offer name |
creatives.icon_url |
url | https://adgem-dashboard-production.s3.us-east-2.amazonaws.com/campaigns/107/campaign-offerwall-creatives/icons/201805242053.png |
The url for the offer icon |
creatives.description |
string | Battle in a world of chaos in Lords Mobile, the latest real-time strategy game from IGG |
The brief description of the offer |
creatives.short_description |
string | Play to earn! |
The offer tagline |
creatives.instructions |
array | ["Discover Idle Jackpot", "Open and play", "Redeem your points! *New Users Only!"], |
The instructions that a player must follow in order to complete the offer and be rewarded. Instruction steps can be parsed by comma. For example: 1. Download and Open the App 2. Redeem your points! |
creatives.disclaimer |
string | New users only |
A disclaimer for offer completion requirements. AdGem Player Support will enforce offer attribution windows as set by our advertisers, making it important that your users are aware of this completion window prior to offer engagement. |
creatives.currency_name |
string | Coin |
The name of your offerwall virtual currency as set in the AdGem Dashboard |
creatives.currency_name_plural |
string | Coins |
The name of your offerwall virtual currency plural form as set in the AdGem Dashboard |
creatives.categories |
string | app |
The offer category type. Possible values include: "app", "survey", "trial", "free", "paid", and "user_info_request". |
creatives.sort_order_setting |
integer | 3 |
Indicates where an offer is sorted on the full AdGem Offerwall |
creatives.stickers |
array | The AdGem-assigned stickers associated with the offer | |
creatives.stickers.*.text |
array | New |
The sticker text |
creatives.stickers.*.color |
array | The sticker hex color | |
creatives.hero_image_url |
url | https://adgem-dashboard-production.s3.us-east-2.amazonaws.com/campaigns/107/campaign-offerwall-creatives/hero_images/4wwM9DRLnUvtVix |
The url for the hero image |
creatives.offer_cta |
string | The suggested user Call to Action button for engagement and offer completion | |
creatives.offer_tip |
string | A suggested user tip to promote user engagement | |
creatives.basic_requirements |
array | Additional user requirements to confirm a user's eligibilty for offer rewards. NOTE: {attribution_window} can be populated via the attribution_window_days field for the offer. |
|
goals |
array | The payable offer goal events | |
goals.*.id |
string | 123456789012345678 |
The unique id for the offer goal |
goals.*.name |
string | Reach level 5 |
The name of the offer goal |
goals.*.description |
string | Reach level 5 |
The description of the offer goal |
goals.*.amount |
integer | 25 |
The amount of virtual currency awarded to the user for completing the goal |
goals.*.payout_usd |
number | 0.25 |
The potential payout for a goal's completion by a player |
goals.*.order |
integer | 1 |
The linear order of the goal to be completed |
goals.*.non_linear |
boolean | false |
Determines if a goal must be completed in order or not |
goals.*.is_purchase_goal |
boolean | false |
Determines if a goal requires a purchase or not |
goals.maximum_completion_time_days |
integer | 30 |
The specific number of days a user has to complete the goal. Can be a null value if number of days eligible for goal completion does not differ from campaign rules |
links |
object | The associated links to be used for offer completion | |
links.click_url |
url | https://api.adgem.com/v1/click?all=1&appid=12345&cid=107&playerid={playerid}&offer_id=178542717096300546 |
The url that the player will click on to engage with the offer. NOTE: The {playerid} must be replaced with the unique id for your player on your system. |
links.support_url |
url | https://api.adgem.com/support/12345/107/{playerid} |
The url that directs players to a support page for a specific campaign available for player support. NOTE: The {playerid} must be replaced with the unique id for your player on your system. |
links.interstitial_url |
url | https://api.adgem.com/offer-interstitial?all=1&appid=12345&cid=107&playerid={playerid}&offer_id=178542717096300546 |
The url that directs users to an AdGem hosted offer interstitial page. Should only be used if not developing a unique offer UI |
stats |
object | The offer-specific metrics | |
stats.network_epc |
string | 7.000 |
The earnings per click (EPC) for this offer across the network. If the offer is new and the network EPC has not been calculated, the value will be null. |
stats.network_epi |
string | 1.200 |
The earnings per install (EPI) for this offer across the network. If the offer is new and the network EPI has not yet been calculated, the value will be null. |
geo_targeting |
object | Acceptable locations (i.e., countries, states, and/or cities) for the offer | |
geo_targeting.countries.*.namegeo_targeting.states.*.namegeo_targeting.cities.*.name |
string | Germany |
The full name of the location |
geo_targeting.countries.*.iso_numericgeo_targeting.states.*.iso_numericgeo_targeting.cities.*.iso_numeric |
integer | 164 |
The location ID on the AdGem network |
geo_targeting.countries.*.iso_alpha2geo_targeting.states.*.iso_alpha2geo_targeting.cities.*.iso_alpha2 |
string | DE |
The ISO 2 letter country code |
geo_targeting.countries.*.iso_alpha3geo_targeting.states.*.iso_alpha3geo_targeting.cities.*.iso_alpha3 |
string | DEU |
The ISO 3 letter country code |
geo_targeting.countries.*.geoname_idgeo_targeting.states.*.geoname_idgeo_targeting.cities.*.geoname_id |
integer | 2921044 |
The name of geographical point in plain ascii characters |
device_targeting |
array | ["android_phone", "android_tablet"] |
The device type(s) allowed by the offer. |
os_targeting |
array | The operating systems for which the offer is available | |
os_targeting.*.name |
string | android |
The operating system type (potential types include: "web", "android", and "ios") |
os_targeting.*.min |
string | 4.0.2 |
The minimum operating system version for which the offer is available |
os_targeting.*.max |
string | 17.2.1 |
The maximum operating system version for which the offer is available |
attribution_window_days |
integer | 30 | The total number of days the user has to complete the offer from offer start |
Pagination Response
When per_page is included in the request, the response will include a pagination object alongside the offers array:
Field |
Type |
Example |
Description |
|---|---|---|---|
pagination.current_page |
integer | 1 |
The current page number |
pagination.per_page |
integer | 50 |
The number of offers per page |
pagination.has_more_pages |
boolean | true |
Whether there are more offers on subsequent pages |
pagination.next_page |
integer or null | 2 |
The next page number, or null if on the last page |
When per_page is not included in the request, the pagination object will not be present in the response.
Example of a Successful API Response
{
"status": "success",
"data": {
"offers": [
{
"id": "3863247715439418",
"campaign_id": 107,
"name": "Idle Jackpot",
"store_id": "1439500962",
"tracking_type": "CPE”,
"total_payout_usd": 78.45717,
"total_amount": 8341,
"start_datetime": "2024-04-03 22:57:11",
"is_multi_reward": true,
"completion_difficulty": 3,
"is_featured_campaign": false,
"campaign_vertical": “Games General“,
"creatives": {
"name": “Idle Jackpot”,
"icon_url": "https://adgem-dashboard-production.s3.us-east-2.amazonaws.com/campaigns/107/campaign-offerwall-creatives/icons/9vBzpAGqNG50g4cyrdIdvcW2WY23DfC6Hej8bxln.jpeg",
"description": "Grow your jackpot! Earn money while you sleep! Wake up and collect! Compete against your friends",
"short_description": "Level up to earn!",
"instructions": [
"Discover Idle Jackpot",
"Open and play",
"Redeem your points! *New Users Only!"
],
"disclaimer": “New Users only”,
"currency_name": "Coin",
"currency_name_plural": "Coins",
"categories": [app,free],
"sort_order_setting": null,
"stickers": [
{
"text": "sapiente",
"color": "#a51948"
},
{
"text": "beatae",
"color": "#81e34d"
}
]
},
"hero_image_url": "https://adgem-dashboard-production.s3.us-east-2.amazonaws.com/campaigns/107/campaign-offerwall-creatives/hero_images/4wwM9DRLnUvtVix"
},
"offer_cta": "Click to get offer!",
"offer_tip": "Pro Tip: Unlock higher earnings by making in-app purchases!",
"basic_requirements": [
{
"description": "Must be a new user. Install required for eligibility.",
"order": 1
},
{
"description": "Must complete within {attribution_window} days.",
"order": 2
},
{
"description": "Internet Connection Required. VPN Use Prohibited.",
"order": 3
},
{
"description": "Rewards may be subject to 24 hour delay.",
"order": 4
},
{
"description": "You must “Allow” the app/game to track your activity to earn rewards.",
"order": 5
}
]
],
"goals": [
{
"id": "3863247736412910",
"name": “Install”,
"description": “Install the app”,
"amount": 15,
"payout_usd": 8.35,
"order": 1,
"non_linear": false,
"is_purchase_goal": false,
"maximum_completion_time_days": null
},
{
"id": "3863247736412911",
"name": "Reach Level 2",
"description": "Reach Level 2",
"amount": 226,
"payout_usd": 3.37,
"order": 2,
"non_linear": false,
"is_purchase_goal": false,
"maximum_completion_time_days": 30
},
{
"id": "3863247736412912",
"name": “Purchase Upgrade”,
"description": “Purchase Upgrade”,
"amount": 427,
"payout_usd": 4.37,
"non_linear": true,
"is_purchase_goal": true,
"order": 3,
"non_linear": false,
"is_purchase_goal": false,
"maximum_completion_time_days": 30
},
{
"id": "3863247736412913",
"name": "Reach Level 10”,
"description": "Reach Level 10”,
"amount": 550,
"payout_usd": 9.6,
"order": 4,
"non_linear": false,
"is_purchase_goal": false,
"maximum_completion_time_days": 30
}
],
"links": {
"click_url": "https://api.adgem.com/v1/click?all=1&appid=12345&cid=107&playerid={playerid}&offer_id=3863247715439418",
"support_url": "https://api.adgem.com/support/12345/107/{playerid}"
"interstitial_url": "https://api.adgem.com/offer-interstitial?all=1&appid=12345&cid=107&playerid={playerid}&offer_id=3863247715439418"
},
"stats": {
"network_epc": "1.5",
"network_epi": "0.75"
},
"geo_targeting": {
"countries": [
{
"name": "Spain",
"iso_numeric": "109",
"iso_alpha2": "TM",
"iso_alpha3": "CHN",
"geoname_id": "67985739"
},
{
"name": "Madagascar",
"iso_numeric": "431",
"iso_alpha2": "US",
"iso_alpha3": "GGY",
"geoname_id": "55529403"
},
{
"name": "Honduras",
"iso_numeric": "287",
"iso_alpha2": "WO",
"iso_alpha3": "NPL",
"geoname_id": "91389411"
}
],
"states": [
{
"name": "Alabama",
"slug": "united-states-alabama",
"iso_numeric": null,
"iso_alpha2": null,
"iso_alpha3": null,
"geoname_id": null
},
{
"name": "Alaska",
"slug": "united-states-alaska",
"iso_numeric": null,
"iso_alpha2": null,
"iso_alpha3": null,
"geoname_id": null
},
{
"name": "California",
"slug": "united-states-california",
"iso_numeric": null,
"iso_alpha2": null,
"iso_alpha3": null,
"geoname_id": null
}
],
"cities": [
{
"name": "Montserrat",
"iso_numeric": "560",
"iso_alpha2": "CA",
"iso_alpha3": "BGR",
"geoname_id": "73626582"
},
{
"name": "Hong Kong",
"iso_numeric": "914",
"iso_alpha2": "US",
"iso_alpha3": "AUT",
"geoname_id": "65045826"
},
{
"name": "Denmark",
"iso_numeric": "440",
"iso_alpha2": "CA",
"iso_alpha3": "CXR",
"geoname_id": "53091371"
}
]
},
"device_targeting": [
"iphone",
"ipad"
],
"os_targeting": [
{
"name": "ios",
"min": "3.2.3"
},
{
"name": "web"
}
]
"attribution_window_days": 30
}
],
"links": {
"support_portal": "https://adunits.adgem.com/support/player?appid=12345&playerid={playerid}",
}
}
Example of a Paginated API Response (per_page=50&page=1)
Available click_url Parameters
The following list contains parameters that you can append to the click_url. These parameters can be returned to you in the player event completion postbacks:
Note: All parameter names and their values are case-sensitive.
Parameter |
Description |
|---|---|
c1 |
A custom parameter value as set by the publisher |
c2 |
A custom parameter value as set by the publisher |
c3 |
A custom parameter value as set by the publisher |
c4 |
A custom parameter value as set by the publisher |
c5 |
A custom parameter value as set by the publisher |
country |
The ISO country code for the user, where the offer was completed |
gaid |
Google Advertising ID, available when the developer is using Google Play Services |
idfa |
Apple Advertising ID, available when the user has not limited ad tracking |
ip |
The IP Address for the user who completed the offer |
state |
The user’s state or region where they are located |
useragent |
The User Agent from the user’s default browser app |
Call Examples
<?php
// Initialize cURL and make the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://offer-api.adgem.com/v1/offers');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Authorization: Bearer {ADGEM_APP_SECURITY_TOKEN}',
]);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
curl_close($ch);
// Decode the response into a PHP associative array
$response = json_decode($response, true);
// Make sure that there was not a problem decoding the response
if(json_last_error()!==JSON_ERROR_NONE){
throw new RuntimeException(
'API response not well-formed (json error code: '.json_last_error().')'
);
}
// Print out the response details or any error messages
if(isset($response['status']) && $response['status']==="success"){
echo 'API call successful';
echo PHP_EOL;
echo 'Response Data: <pre>'.print_r($response['data'], true).'';
echo PHP_EOL;
}else{
echo 'API call failed';
echo PHP_EOL;
echo 'Errors: <pre>'.print_r($response['data'], true).'';
echo PHP_EOL;
}
?>
# importing the requests library
import requests
# defining the api-endpoint
API_ENDPOINT = "https://offer-api.adgem.com/v1/offers"
# your Adgem App ID and API Token
ADGEM_APP_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# headers to be included in request
headers = {
"Accept": "application/json",
"Authorization": "Bearer {ADGEM_APP_SECURITY_TOKEN}"
}
# sending get request and saving response as response object
response = requests.get(url = API_ENDPOINT, headers = headers)
# extracting response data
response_data = response.data
print(response_data)
require 'net/http'
require 'json'
url = 'https://offer-api.adgem.com/v1/offers'
uri = URI(url)
req = Net::HTTP::Get.new(uri)
req['Accept'] = 'application/json'
req['Authorization'] = 'Bearer {ADGEM_APP_SECURITY_TOKEN}'
res = Net::HTTP.start(uri.hostname, uri.port) { |http|
http.request(req)
}
JSON.parse(res)