Errors & Responses
Our API returns bare, endpoint-specific JSON objects rather than a shared envelope. This page documents the shapes you should expect and how to handle failures correctly.
Success responses
There is no success flag. A successful call returns the data key for that endpoint.
| Endpoint | Response key |
|---|---|
| Offers API, Offerwall API | offers |
| Clicks API | clicks |
{
"offers": []
}
An empty offers array is a valid success, not an error. It usually means no offers match
the requested country and platform combination.
Error responses
Every failure returns a single error key containing a human-readable message.
{
"error": "Invalid API Key"
}
Do not branch on the HTTP status code alone. The Offers API returns HTTP
500 for every failure, including your own mistakes such as a bad API key or an
unapproved placement. Always check whether the body contains an error key.
Handling this correctly
const response = await fetch(offersUrl);
const body = await response.json();
// Status alone is not reliable here — inspect the payload.
if (body.error) {
throw new Error(`AdPlusMedia: ${body.error}`);
}
return body.offers;
Offers API messages
All of the following are returned with HTTP status 500.
| Message | Cause | Fix |
|---|---|---|
Missing parameters | The app ID is absent from the path. | Check your URL construction. |
App Not Found | No placement matches the app ID. | Verify the app ID in your dashboard. |
Invalid API Key | The api parameter does not match the placement's key. | Copy the key again from your placement settings. |
App Not Approved | API access has not been granted for this placement. | Request API access, then wait for review. |
App Pending | The placement or its API request is still under review. | Wait for approval. |
App Rejected | The placement or its API request was rejected. | Contact support. |
App Disabled | The placement has been disabled. | Contact support. |
App Deleted | The placement no longer exists. | Create a new placement. |
Offerwall and Clicks API statuses
These endpoints use conventional HTTP status codes.
| Status | Meaning |
|---|---|
200 | Success. |
400 | A required path parameter is missing, or the IP is invalid. |
403 | The placement is not active, or the user failed a VPN check. |
404 | The placement does not exist. |
500 | An unexpected server error. |
Postback intake statuses
These are returned to advertisers posting conversions to us. See MMP Postbacks for the full flow.
| Status | Body | Meaning |
|---|---|---|
200 | Postback Handled Successfully | The conversion was accepted. |
200 | Duplicate postback ignored | Already processed. Safe to stop retrying. |
200 | Event cap reached; conversion ignored | The campaign's cap for this event is exhausted. |
400 | clickid is required | The click identifier was not sent. |
400 | event is required | The event name was not sent. |
400 | Invalid Status | status was neither 1 nor 2. |
401 | Unauthorized Token | The postback token in the URL is wrong. |
401 | Unauthorized Password | The provider password in the URL is wrong. |
401 | Invalid signature | HMAC verification failed. |
403 | Forbidden | The calling IP is not on the allowlist. |
403 | Provider disabled | The provider integration is switched off. |
404 | Click not found | No click matches the supplied clickid. |
422 | Unknown event for this campaign | The event name is not configured on the campaign. |
A 200 response does not always mean a conversion was recorded. Read the
success message — capped, duplicate and ignored-reversal outcomes all return
200 by design, so that senders stop retrying.
Rate limiting
The postback intake endpoint is limited to 300 requests per minute. Exceeding it returns
HTTP 429. The offer feed endpoints are not rate limited, but you should still cache them.