Every row from GET /publisher/offers carries the fields below. Amounts are in USD and already priced at your payout; nothing on the row is a list price.
{
"id": "aff_7c2e91b04d3a",
"numericId": 241889305712604,
"name": "Harbor Blocks",
"image": "https://...",
"largeImage": null,
"squareImage": null,
"description": "Build harbors block by block.",
"shortDescription": "Install and reach level 40",
"requirements": [
{ "text": "Install the app", "order": 1 },
{ "text": "Reach level 40", "order": 2 }
],
"bundleId": null,
"storeId": "6449812207",
"effectivePayoutUsd": 4.2,
"installPayoutUsd": 4.2,
"networkEpc": 0.31,
"epcSource": "afos",
"trackingType": "CPI",
"trackingTypeNormalized": "cpi",
"offerTypeDerived": null,
"categories": ["Puzzle"],
"contentType": "game",
"offerKind": "game",
"verticals": [],
"classificationConfidence": "high",
"platforms": ["ios"],
"geoTargeting": { "mode": "include", "countryCodes": ["US"] },
"status": "active",
"isPaidOnInstall": true,
"keywordCampaign": false,
"trackingUrl": "https://click.affiliateos.ai/click?...&sub_id={SUB_ID}",
"goals": [
{
"id": "1",
"numericId": 51772690341208,
"name": "Install",
"label": "Install and open",
"goalType": "install",
"effectivePayoutUsd": 4.2,
"userRewardUsd": 1.5,
"userRewardIsAdvertiserSet": true,
"maximumCompletionTimeDays": null,
"daysLeft": null
},
{
"id": "6",
"numericId": 51772690341213,
"name": "Reach level 10",
"label": "Reach level 10",
"goalType": "level",
"effectivePayoutUsd": 0,
"userRewardUsd": 1.5,
"userRewardIsAdvertiserSet": true,
"maximumCompletionTimeDays": 14,
"daysLeft": null
}
]
}
Example for Pebble Rewards. IDs, payouts and copy are made up.
| Field | Type | Meaning |
|---|
id | string | The offer’s ID. Store everything by it, and send it back in links and filters. |
numericId | number or null | An integer twin of id, for systems that can only store numbers. Always the same number for the same offer. Accepted wherever the id filter, the offer detail, the conversions filter or a link’s off_id takes an ID. |
name | string | The offer’s title. |
bundleId | string or null | The app’s bundle or package ID, such as com.tidewater.harborblocks, when the offer has one. |
storeId | string or null | The app’s store ID: an Android package name, or an App Store number, sometimes with an id prefix. Many offers carry the app’s identity only here. |
| Field | Type | Meaning |
|---|
effectivePayoutUsd | number | What the whole offer pays you, all steps together. The portal calls it Total payout. |
installPayoutUsd | number or null | What the install step pays you. null when the install doesn’t pay you. |
isPaidOnInstall | boolean | true when a plain install (or install and open) is a step that pays you. See Install offers. |
networkEpc | number or null | Earnings per click at your payout. An estimate, never a guarantee. |
epcSource | string or null | afos when networkEpc was measured on AffiliateOS traffic over 30 days, network when it’s the figure the offer came with (scaled down when it runs above the payout), null when there is none. |
| Field | Type | Meaning |
|---|
trackingType | string or null | The pricing label the offer was listed with, as sent, such as CPI or CPA. |
trackingTypeNormalized | string or null | The same, lowercased to one of cpa, cpc, cpe, cpi, cpie or mrcpe. |
offerTypeDerived | string or null | CPI or CPE, worked out from the steps. Only filled when both labels above are blank; use it as a fallback. |
contentType | string or null | game or non_game. Our own classification, the same on every offer. |
offerKind | string or null | game, signup, finance, deposit, subscription, purchase, sweepstakes, survey, rewards_app or other. |
verticals | array | sports_betting, real_money_gaming, both or neither. |
classificationConfidence | string or null | high or low. Treat low as unclassified. |
categories | array | Free-text labels the offer came with. They differ from offer to offer; filter on contentType or offerKind instead. |
keywordCampaign | boolean | true when the user must find the app by searching the store, not by following a link. Show the description’s instructions prominently. |
| Field | Type | Meaning |
|---|
platforms | array | Where it runs: ios, android, web, sometimes desktop. See Web, desktop and mobile offers. |
geoTargeting | object or null | mode is all, include (only countryCodes) or exclude (everywhere but countryCodes). Codes are two letters, such as US. |
status | string | active on every row in the list: offers that can’t run are left out instead. |
| Field | Type | Meaning |
|---|
description, shortDescription | string or null | What to tell the user. |
requirements | array or null | The steps in plain words, each with text and order. |
image | string or null | The offer’s icon or main image. |
largeImage, squareImage | string or null | Extra creatives. Often null. An image can be null until our copy of it is ready. |
| Field | Type | Meaning |
|---|
trackingUrl | string | The link to send the user through, in full: https://click.affiliateos.ai/click?off_id=aff_7c2e91b04d3a&pub_id=...&partner_id=...&sub_id={SUB_ID}&device_id={DEVICE_ID}. Replace {SUB_ID} with the user’s own ID and {DEVICE_ID} with the advertising ID when you have it. Leave partner_id as it is. |
Each entry in goals is one step.
| Field | Type | Meaning |
|---|
id | string | The step’s ID. Unique within its offer only. Postbacks send it as goal_id. |
numericId | number or null | An integer twin, unique across every offer. Use it as your own event ID. Postbacks send it as goal_id_numeric. |
name | string | The step’s exact name. Postbacks send it as conversion_name, and a postback rule for one event matches on it. |
label | string | Display text for the step. |
goalType | string | Such as install, registration, tutorial, level, purchase, deposit, subscription, trial or event. |
effectivePayoutUsd | number | What this step pays you. 0 is common: see Multi-step offers. |
userRewardUsd | number | The player’s reward for this step, in USD. Never null on this API. |
userRewardIsAdvertiserSet | boolean | true: the reward is fixed for this step; show and credit it as is, even when it is 0. false: it’s our suggestion, a share of your payout you can change under My Profile, API user reward. Install steps stay at $0 in that suggestion. |
maximumCompletionTimeDays | number or null | Days the user has to finish the step, counted from the click or the install. null when there is no limit. |
daysLeft | number or null | The same limit, from the few offers that send it under this name. Read maximumCompletionTimeDays first. |
streakDays | number | Only on steps that need consecutive days of play: how many. Absent on every other step, so test whether the key exists. |
Fields that appear only sometimes
#
| Field | When | Meaning |
|---|
cap | When we report caps on the API; null on offers without a known limit | New users the offer can still take from you today. 0 means no new starts where we enforce the limit; on some offers it’s an estimate, so check available before hiding a card. null means no known limit, not unlimited. See Daily caps. |
capEventName | With cap | The step that uses up the cap, usually the first one. |
capTimezone, capResetsAt | With cap | The cap’s time zone and its next reset, as a UTC timestamp. null when the time zone isn’t known. |
userStatus | When native placements are on for your account and you send sub_id | new, in_progress or completed for that user. |
GET /publisher/offers/:offerId returns one offer with the same fields, priced the same way, plus more copy and targeting: advertiserName, cta, tip, disclaimer, attributionWindowDays, deviceTargeting, osTargeting, startDatetime and endDatetime. Its cpi is your install payout as a number, or null. It also answers for an offer that’s out of the list only because its cap or budget ran out.
In the portal, an offer’s page shows the same data under Offer details (Payout, Tracking Type, Platforms, Countries, Categories, Attribution window, App bundle), Payout steps (each step’s payout, with User reward where it differs) and Requirements.
Network API rows (/network-api/offers) share the core fields above, with these differences:
syncStatus instead of status, plus budgetStatus and syncedAt.
- Rows don’t carry
numericId, installPayoutUsd, offerTypeDerived, userStatus or the cap fields, and each step carries description instead of label, with no numericId or userRewardIsAdvertiserSet.
advertiserName, attributionWindowDays, deviceTargeting, osTargeting, startDatetime and endDatetime are on the list rows too.
accessPolicy (auto_approved, approval_required or private) appears under four spellings; read whichever you like.
- Direct offers your network added also carry
campaignId and campaignName.
- A step’s
userRewardUsd is null when no player reward was published. 0 is a real value, so never read null as zero.