Guides
Guides

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:

KeyTypeDescription
categoriesString[]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" ]
countriesString[]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..
devicesString[]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", "*" ]
offerIDsString[]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.

KeyTypeDescription
typeString"singlestep" or "multistep"
nameStringName of the offer
descriptionStringDescription of the offer
imageStringURL of the offer's square image
countriesString[]Array of ISO-3166 country codes, or '*' for all.
offerIDStringThe unique ID for this offer
categoriesString[]An array containing any of the following:

[ "app", "game", "desktopgame", "mobilegame", "oneclick", "survey", "signup", "video", "quiz", "chromeextension", "creditcard", "deposit", "freetrial", "shopping" ]
devicesString[]An array containing any of the following:

["macos", "windows", "android", "iphone", "ipad", "*"]
linkStringTracking 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.
conversionRateNumberThe conversion rate (in %) this offer has across the Lootably network
extraCreativesObjectExtra creatives you can display in your UI. See below for more information.
previewURLString | undefinedURL to preview this offer
bundlePackageIDString | undefinedThe app store bundle or package ID
appStoreCategoriesString[] | undefinedCategories from Google Play or Apple App Store
appStoreDescriptionString | undefinedDescription from Google Play or Apple App Store
paymentModelStringThe payment model of this offer, it can be any of the following.

[ "CPA", "CPE", "CPC", "CPI", "CPS", "CPM", "CPL", "CPV", "SOI", "DOI", "survey" ]
restrictionsObject | undefinedAny additional targeting restrictions or requirements
multipleConversionsAllowedBooleanReturns 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.

TypeScript type definition

KeyTypeDescription
revenuenumber | 'variable'The USD amount you'll receive for a completion
currencyRewardnumber | '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.

TypeScript type definition

KeyTypeDescription
goalIDstringThe ID of this goal
descriptionstringThe description of this goal
revenuenumberThe amount of revenue generated when a user completes this goal
currencyRewardnumberThe reward your user will receive for completing this goal in your placements currency. Calculated based on the settings from your placement's Currency tab.
isOptionalbooleanIf 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.

TypeScript type definition

KeyTypeDescription
typeStringThe type of creative, either "image" or "video"
urlStringThe URL of the image or video asset.

What’s Next

Learn how to setup a postback URL to track conversions and reward your users