Offers API
Instructions for integrating the Offers API into your system.
To get started using the Lootably Offers API you will need to grab your placementID
and apiKey
from the "API" tab inside your placement's settings on the Lootably Publisher Dashboard. All Offers API requests are sent to https://api.lootably.com/api/v2/offers/get
.
Which API should I use?
Choose the User API when:
- You need real-time, user-specific results when a user loads your website/app.
- You want us to handle country, device, and OS restriction targeting.
Choose the Catalogue API when:
- You need a list of every offer in our system.
- You need information about a specific offerID or set of offerIDs.
- You are comfortable writing an algorithm to handle country, device, and OS restrictions in your own system.
Regardless of which API you choose to use, the API route is the same and the response data is of the same structure.
If you do not know which API to use, please reach out at [email protected] with your use case and we can point you in the right direction.
TypeScript Integration
To make integration easier for developers using TypeScript, we provide an NPM package with type definitions for our Offers API. This package helps ensure type safety, reduces development time, and prevents errors. We highly recommend using this package if your backend is built with TypeScript.
Installation
To get started, install the package:
npm install lootably-offers-api-types
Usage Example
Here is a basic example of how to use the provided types to call the Offers API and ensure type safety in your TypeScript project:
import type { SuccessfulAPIResponse, FailedAPIResponse } from 'lootably-offers-api-types';
const API_URL = 'https://api.lootably.com/api/v2/offers/get';
async function fetchOffers(): Promise<void> {
const requestBody = {
placementID: process.env.PLACEMENT_ID,
apiKey: process.env.API_KEY,
userData: {
userID: 'exampleUserID',
userAgentHeader: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
ipAddress: '192.0.2.1',
},
categories: ['app', 'game'],
devices: ['windows', 'android'],
countries: ['US', 'CA'],
};
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
});
const data: SuccessfulAPIResponse | FailedAPIResponse = await response.json();
if (data.success) {
console.log('Request ID:', data.data.requestID);
console.log('Offers:', data.data.offers);
} else {
console.error(`Error: ${data.message}`);
console.error('Request ID:', data.data.requestID);
}
}
fetchOffers().catch((error) => {
console.error('An error occurred while fetching offers:', error);
});
For a complete list of available types, please refer to the Lootably Offers API Types repository.
User API
Our User API allows you to fetch offers for a specific user in real-time. This API is meant to be called on live traffic each time a user loads your page.
{
"body": {
"apiKey": "...",
"placementID": "...",
"userData": {
"userID": 'exampleUserID',
"userAgentHeader": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
"ipAddress": '192.0.2.1',
}
}
}
Catalogue API
The Catalogue API allows you to fetch our offers and store them internally to later serve to your users. By default, the Catalogue API will return all active offers in our system. We recommend calling this API every 10-20 minutes to ensure that your cached offer list is always up to date.
If you only need a subset of our offers, you can use any of these parameters to narrow down the returned list:
Key | Type | Description |
---|---|---|
categories | String[] | The list of categories you'd like to receive. Here are the possible values [ "app", "game", "desktopgame", "mobilegame", "oneclick", "survey", "signup", "video", "quiz", "chromeextension", "creditcard", "deposit", "freetrial", "shopping" ] |
countries | String[] | The list of country codes you'd like to receive. We use the ISO 3166 standard for our country codes, ISO 3166 alpha-2 country codes.. |
devices | String[] | The list of devices you'd like to receive. Please note that offers with a device value of "*" will always be returned. Here are the possible values [ "macos", "windows", "android", "iphone", "ipad", "*" ] |
offerIDs | String[] | An array of offer IDs you want to retrieve. All other filtering properties still apply. |
{
"body": {
"apiKey": "...",
"placementID": "..."
}
}
Offer Object
All successful API responses will return a list of offer objects containing the following properties, but singlestep and multistep offers will each have a slightly different set of properties, outlined below.
Key | Type | Description |
---|---|---|
type | String | "singlestep" or "multistep" |
name | String | Name of the offer |
description | String | Description of the offer |
image | String | URL of the offer's square image |
countries | String[] | Array of ISO-3166 country codes, or '*' for all. |
offerID | String | The unique ID for this offer |
categories | String[] | An array containing any of the following: [ "app", "game", "desktopgame", "mobilegame", "oneclick", "survey", "signup", "video", "quiz", "chromeextension", "creditcard", "deposit", "freetrial", "shopping" ] |
devices | String[] | An array containing any of the following: ["macos", "windows", "android", "iphone", "ipad", "*"] |
link | String | Tracking link that you redirect your users to. If you do not provide userData in the query then you will need to manually replace {userID} with the user's ID before redirecting. |
conversionRate | Number | The conversion rate (in %) this offer has across the Lootably network |
extraCreatives | Object | Extra creatives you can display in your UI. See below for more information. |
previewURL | String | undefined | URL to preview this offer |
bundlePackageID | String | undefined | The app store bundle or package ID |
appStoreCategories | String[] | undefined | Categories from Google Play or Apple App Store |
appStoreDescription | String | undefined | Description from Google Play or Apple App Store |
paymentModel | String | The payment model of this offer, it can be any of the following. [ "CPA", "CPE", "CPC", "CPI", "CPS", "CPM", "CPL", "CPV", "SOI", "DOI", "survey" ] |
restrictions | Object | undefined | Any additional targeting restrictions or requirements |
multipleConversionsAllowed | Boolean | Returns true if the offer can be completed for more than one time by a user. |
Singlestep
Singlestep offers will include the base properties listed above, as well as the following additional properties.
Key | Type | Description |
---|---|---|
revenue | number | 'variable' | The USD amount you'll receive for a completion |
currencyReward | number | 'variable' | The amount your user will receive in this placements currency for a completion |
Multistep
Multistep offers will include the base properties listed above, as well as an array of goals
. Each goal item will contain the following properties.
Key | Type | Description |
---|---|---|
goalID | string | The ID of this goal |
description | string | The description of this goal |
revenue | number | The amount of revenue generated when a user completes this goal |
currencyReward | number | The reward your user will receive for completing this goal in your placements currency. Calculated based on the settings from your placement's Currency tab. |
isOptional | boolean | If true, this goal is not required to advance in the offer. For example, some offers provide a bonus to users when they complete an in-app purchase, but the in-app purchase is not required to finish the offer. For these goals, isOptional would be true. |
Extra Creative(s)
Some offers may provide additional creatives for you to use to display to your users.
Key | Type | Description |
---|---|---|
type | String | The type of creative, either "image" or "video" |
url | String | The URL of the image or video asset. |
Updated 5 days ago