Offers API
Reference for GET /api/v1/offers and /api/v1/categories: authentication, query parameters, the offer object, errors and rate limits.
Authentication
Send your API key with every request. Any of these works; the header is preferred:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_API_KEY
?api_key=YOUR_API_KEYOnly approved publisher accounts can use the API. Call it from your server, never from an app or a browser.
GET /api/v1/offers
Live offers you can show, filtered for one user. An offer is live when it is active and inside its start and end dates. Offers that are private to other publishers, or hidden from you, are never returned.
| Parameter | Description |
|---|---|
country | Two-letter ISO country of your user, e.g. US. Returns only offers that run there, priced for that country. |
platform | ios, android or website. Returns only offers for that platform, plus offers that run everywhere. |
category | A category slug from /api/v1/categories. |
user_id | Your ID for the user, up to 200 characters. Filled into each click_url. |
featured | 1 returns featured offers only. |
limit | 1 to 500. Default 100. |
offset | Skip this many offers, for paging. Default 0. |
Offers are sorted with featured offers first, then by your payout, highest first.
Response
{
"data": [
{
"id": "846c942f-3292-4689-9b0a-1a047cfcfa04",
"offer_id": "NET-1001",
"name": "Reach level 10 in Coin Quest",
"description": "Install Coin Quest and reach level 10 within 14 days.",
"logo_url": "https://cashadmedia.com/uploads/offer-logos/….png",
"category": { "slug": "games", "label": "Games" },
"featured": false,
"countries": ["US", "GB"],
"platforms": ["ios", "android"],
"steps": [
{ "event": "install", "title": "Install and open", "payout": 0.4, "reward": 400, "country_price": true },
{ "event": "level_10", "title": "Reach level 10", "payout": 1.35, "reward": 1350, "country_price": false }
],
"total_payout": 1.75,
"total_reward": 1750,
"terms": "New users only.",
"ends_at": null,
"click_url": "https://cashadmedia.com/click/846c942f-…?publisher_id=…&user_id=u_123"
}
],
"meta": { "total": 1, "count": 1, "limit": 100, "offset": 0, "country": "US", "platform": "android", "currency": "USD" }
}The offer object
| Field | Description |
|---|---|
id | Our ID for the offer. Stable; use it as your key. Also sent in postbacks as offer_id. |
offer_id | The advertiser's or network's own ID for the offer. Informational. |
name, description, terms | Text to show your users. terms may be empty. |
logo_url | Square logo, or null. |
category | slug and label. |
featured | true for offers we want highlighted. |
countries | Countries the offer runs in. Empty means everywhere. |
platforms | Platforms the offer runs on. Empty means all. |
steps | One entry per event the user is paid for. Single-step offers have one. See below. |
total_payout, total_reward | Sums over all steps. |
ends_at | ISO time the offer stops, or null. |
click_url | The link to open when the user takes the offer. See click links. |
Each step has:
| Field | Description |
|---|---|
event | Event name. The same value arrives as event in your postback when the step is completed. |
title | What the user has to do, ready to show. |
payout | What you earn for the step, USD. |
reward | Suggested reward for the user, in points. Scale or replace it with your own currency. |
country_price | With country in the request: true when the amounts are a price set for that country, false when they are the step's default. |
geo_prices | Without country in the request: the countries that pay differently, each with country, payout and reward. |
GET /api/v1/categories
{ "data": [{ "slug": "games", "label": "Games" }, { "slug": "finance", "label": "Finance" }] }Errors
Errors come back as JSON with an HTTP status and a code:
{ "error": { "code": "invalid_country", "message": "`country` must be a two-letter ISO code, e.g. US." } }| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_country | country is not a two-letter ISO code. |
| 400 | invalid_platform | platform is not ios, android or website. |
| 400 | invalid_user_id | user_id is longer than 200 characters. |
| 401 | missing_api_key | No key was sent. |
| 401 | invalid_api_key | The key is wrong or was replaced. |
| 403 | account_not_approved | Your account is not approved, or is suspended. |
| 429 | rate_limited | Over the rate limit. Wait for the Retry-After seconds. |
Rate limits and caching
Each key can make 120 requests a minute. Responses can be cached for 60 seconds. In practice, cache the list per country and platform for a few minutes: offers don't change by the second, and the click link checks each offer again when it is opened.