AdPlusMedia Docs
Docs API Reference

Offers API

The Offers API returns our offer catalogue as JSON so you can render it inside your own interface instead of using the hosted offerwall.

API access is granted separately from placement approval. Your placement needs request_api = approved before any of these endpoints return data. Request access from your placement settings.

Two modes, one endpoint

The feed serves two integration shapes. Which one you get depends on whether you include the [USER_ID] path segment — nothing else.

GET http://adplusmedia.com/api/v1/offers/[APP_ID]/[USER_ID]
GET http://adplusmedia.com/api/v1/offers/[APP_ID]
ModeRequestUse it for
Publisher /api/v1/offers/[APP_ID]/[USER_ID] Serving a feed to one of your signed-in users.
Partner /api/v1/offers/[APP_ID] Importing the catalogue into an external CPA network.

Targeting, ranking, filtering and pagination are identical in both modes. Only two things differ:

 PublisherPartner
reward_name, currency Returned Omitted
points, reward, usd_jmpt Returned Omitted
payout (advertiser USD) Returned Returned
Tracking url /api/redirect/[TOKEN] /api/redirect/[TOKEN]?subid={SUBID}
Default country targeting Resolved server-side Whole catalogue

Partner mode returns no reward or currency data — a network has no relationship with a publisher's virtual currency. You receive payout, the advertiser payout in USD, which is what your own economics are based on.

It also defaults to the entire catalogue. You import once and target your own users later, so resolving your server's country would hand you the wrong subset. Pass ip or country_code if you do want it narrowed.

Authentication

Send your API key either as an Authorization: Bearer header or as the api query parameter. Both are accepted on both modes.

An API key authorises only the App Placement it was issued for. A key for one placement will not open another, whichever transport you use.

bash
# Publisher mode - header auth
    curl -H "Authorization: Bearer ak_9f2c7e1b4d8a35660c1ee9b7a4f0d213" \n         "http://adplusmedia.com/api/v1/offers/1042/user_8837"

    # Partner mode - query auth, no user segment
    curl "http://adplusmedia.com/api/v1/offers/1042?api=ak_9f2c7e1b4d8a35660c1ee9b7a4f0d213"

Call this endpoint from your server, not from the browser. A client-side request exposes your API key and leaks your full offer catalogue and payouts to anyone inspecting network traffic.

Query parameters

ParameterRequiredDescriptionDefault
api Yes* Your placement API key. *Or send it as an Authorization: Bearer header instead.
country_code No Two-letter country code used to filter offers by targeting. Pass all to disable country targeting and receive the whole catalogue. Publisher: resolved server-side.
Partner: all
ip No The end user's IP address. When present, we resolve the country from it and country_code is ignored.
platform No Restrict the feed to a single platform. Accepts ios, android, desktop or web. All platforms
offer_type No Restrict the feed to a single offer type. All types
page No Page number to retrieve. 1
per_page No Offers per page. Capped at 200. 50
macro No Partner mode only. Overrides the subid macro, for example [USER_ID]. {SUBID}

Filtered example

bash
curl "http://adplusmedia.com/api/v1/offers/1042/user_8837?api=YOUR_API_KEY&country_code=US&platform=android"

Response

A successful call returns HTTP 200. The envelope depends on the mode.

Publisher mode

json
{
      "offers": [
        {
          "id": 4821,
          "name": "Monopoly GO!",
          "description": "Reach board level 15 within 7 days.",
          "image": "https://cdn.example.com/offers/4821.png",
          "offer_type": "offer",
          "payout": "1.96",
          "points": 196,
          "reward": 196,
          "usd_jmpt": "0.9800",
          "countries": ["US", "CA", "GB"],
          "instructions": "Install the game and reach board level 15.",
          "requirements": "New users only.",
          "is_game": 1,
          "incent": 1,
          "url": "http://adplusmedia.com/api/redirect/eyJpdiI6IlZ4..."
        }
      ],
      "reward_name": "Coins",
      "currency": { "name": "Coins", "icon": null },
      "pagination": { "page": 1, "per_page": 50, "total": 137, "total_pages": 3, "has_more": true }
    }

Partner mode

No reward_name, no currency, and no per-offer reward fields. The tracking url carries the subid macro.

json
{
      "offers": [
        {
          "id": 4821,
          "name": "Monopoly GO!",
          "description": "Reach board level 15 within 7 days.",
          "image": "https://cdn.example.com/offers/4821.png",
          "offer_type": "offer",
          "payout": "1.96",
          "countries": ["US", "CA", "GB"],
          "devices": ["android", "iphone"],
          "isPremium": false,
          "instructions": "Install the game and reach board level 15.",
          "requirements": "New users only.",
          "is_game": 1,
          "incent": 1,
          "url": "http://adplusmedia.com/api/redirect/eyJpdiI6IlZ4...?subid={SUBID}"
        }
      ],
      "pagination": { "page": 1, "per_page": 50, "total": 137, "total_pages": 3, "has_more": true }
    }

The feed is paginated. You receive 50 offers per page by default (maximum 200). Use page and per_page, and keep requesting until pagination.has_more is false.

Offer object

FieldTypeModeDescription
idIntegerBothUnique AdPlusMedia offer ID.
nameStringBothOffer title.
descriptionStringBothShort description of the required action.
imageStringBothOffer icon URL.
offer_typeStringBothCategory of the offer, for example offer or survey.
payoutStringBothAdvertiser payout in USD, formatted to two decimal places.
countriesArrayBothISO alpha-2 codes the offer is available in.
instructionsStringBothStep-by-step completion instructions, when the offer defines them.
requirementsStringBothEligibility requirements, when the offer defines them.
eventsArrayBothIndividual reward events for multi-step offers, when present.
incentIntegerBoth1 when incentivised traffic is allowed.
urlStringBothEncrypted tracking URL. In partner mode it ends with ?subid={SUBID}.
pointsNumberPublisherReward in your virtual currency (payout × your rate).
rewardNumberPublisherSame value as points, kept for older integrations.
usd_jmptString|nullPublisherPayout converted to JumpTask currency. null when that service is unavailable.
devicesArrayPartnerSupported devices, so you can run your own device targeting.
isPremiumBooleanPartnertrue for featured inventory.

devices and isPremium are returned in partner mode only. A partner runs its own targeting, so it needs them; a publisher feed is already targeted server-side by the time you receive it.

Sending users to an offer

Every offer carries a ready-to-use url. Open it and the platform records the click and forwards the user to the advertiser. Fetching the feed never creates a click — only a real visit to that URL does.

Publisher mode

The url is already bound to the [USER_ID] you requested the feed with. That identifier is sealed inside the encrypted token, so it cannot be altered by anything appended to the URL. Use it as-is.

If a subid parameter is present on a publisher link it is ignored entirely. The encrypted identifier always wins — it is never overwritten, merged or compared.

Partner mode — the subid macro

A partner has no end-user identifier when the catalogue is imported, so every tracking URL ends with a macro you replace before sending traffic:

text
http://adplusmedia.com/api/redirect/eyJpdiI6IjRhTn...In0=?subid={SUBID}
                                                              ^^^^^^^^
                                        replace this with your own identifier
RuleDetail
What it holds Your unique tracking identifier. It may be a user ID, click ID, transaction ID, session ID, wallet ID, UUID, or any other unique identifier generated by your platform. AdPlusMedia stores this value with the generated click and returns it in postbacks where appropriate. It is treated as opaque — we never parse or interpret it.
Maximum length 255 characters after trimming. Longer values are rejected, not truncated.
Required Yes. An empty, whitespace-only or missing subid is refused.
Custom macro Add ?macro=[USER_ID] to the feed request if your import tool needs a different token — for example [USER_ID], {sub1} or {s1}.

You must substitute the macro before redirecting traffic. A click arriving with {SUBID} or [SUBID] still in the URL returns an Integration Error and no click is created.

This is deliberate. Accepting an unsubstituted macro would produce clicks that can never be attributed or paid, while still costing you traffic — and they would look perfectly healthy in every report. Failing on the first click is far cheaper than discovering it in a reconciliation weeks later.

Tracking URLs never expire. Import them once and keep them for as long as you like — they are refused only if the App Placement or the offer itself is disabled.

Building a link yourself

You can also construct a click URL directly from an offer's id and your user's identifier:

GET http://adplusmedia.com/api/manual-offer/[APP_ID]/[OFFER_ID]/[USER_ID]
javascript
function offerClickUrl(offerId, userId) {
        return 'http://adplusmedia.com/api/manual-offer/1042/'
            + encodeURIComponent(offerId) + '/'
            + encodeURIComponent(userId);
    }

This endpoint accepts one extra optional parameter, source_id, which is stored against the click and returned to you for your own sub-ID reporting.

Caching

The feed is not paginated and can be large. Cache it on your server for a few minutes rather than calling it on every page view.

The v1 endpoints compute usd_jmpt by calling an external currency service on every single request, with no caching. If you do not need that field, use v2 — it is meaningfully faster.

Errors

Every failure on these endpoints returns HTTP 500 with a JSON error field, including client mistakes such as a bad API key. See Errors & Responses for the full list.

json
{
      "error": "Invalid API Key"
    }