> AffiliateOS Help Center. Index of every article for AI tools: https://www.affiliateos.ai/help/llms.txt

# Every offer field, explained

Offers and the feed · For publishers, networks · Updated 30 October 2026
Web version: https://www.affiliateos.ai/help/offers/every-offer-field

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.

## Example row

```json
{
  "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.

## Identity

| 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. |

## Money

| 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](https://www.affiliateos.ai/help/offers/install-offers-paid-once). |
| `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. |

## What the offer is

| 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. |

## Who can run it

| Field | Type | Meaning |
|---|---|---|
| `platforms` | array | Where it runs: `ios`, `android`, `web`, sometimes `desktop`. See [Web, desktop and mobile offers](https://www.affiliateos.ai/help/offers/web-desktop-and-mobile). |
| `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. |

## Copy and images

| 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. |

## The link

| 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. |

## Steps: goals

Each entry in `goals` is one [step](https://www.affiliateos.ai/glossary#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](https://www.affiliateos.ai/help/offers/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](https://www.affiliateos.ai/help/offers/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. |

## The offer detail

`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**.

## For networks

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.
