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 available to your account, filtered for one user.
| 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, and each step then says whether this user has completed it. |
featured | 1 returns featured offers only. |
q | Search text, matched against the offer name and description, or an exact offer id. |
offerwall_id | One of your offerwalls (Dashboard → Offerwalls). Each reward is then in that wall's currency at its rate, and click links are tagged with it, so postbacks carry the same reward. |
sort | payout (default): featured offers first, then by your payout, highest first. newest: the latest offers first. |
limit | 1 to 500. Default 100. |
offset | Skip this many offers, for paging. Default 0. |
Without sort, 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"],
"step_count": 2,
"steps": [
{ "event": "install", "title": "Install and open", "payout": 0.4, "reward": 400, "completed": true, "country_price": true },
{ "event": "level_10", "title": "Reach level 10", "payout": 1.35, "reward": 1350, "completed": false, "country_price": false }
],
"total_payout": 1.75,
"total_reward": 1750,
"terms": "New users only.",
"ends_at": null,
"click_url": "https://redirect.cashadmedia.com/846c942f-…?publisher_id=…&user_id=u_123"
}
],
"meta": { "total": 1, "count": 1, "limit": 100, "offset": 0, "country": "US", "platform": "android", "sort": "payout", "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 | A short reference code for the offer, handy when you contact us about it. |
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. |
step_count | How many steps the offer has. More than 1 means a multi-step offer, each step paid on its own. |
steps | One entry per event the user is paid for, in the order the user does them. 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. |
completed | With user_id in the request: true when this user has already completed the step (pending or credited), so you can tick it off and show what's left. |
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. |
| 400 | invalid_sort | sort is not payout or newest. |
| 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.