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:

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", "*" ][ "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", "*"]["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.

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