Offer callbacks
This page describes on how to utilize offer specific callbacks and for different offer states.
What is an offer callback for?
You can use the Offer Callback field when you want to receive only offer-related postbacks or if you prefer to handle offers through a separate endpoint rather than using the standard Reward Callback field.
How to set up offer-specific callbacks
Create a new advanced offer callback. Once added, a new configuration window will appear, allowing you to define all settings for this specific callback:
Multiple fields must be configured:
Callback URL Host
Enter the callback endpoint URL your system is prepared to receive postbacks on.
Protocol
Choose the protocol to use for your callback URL.
In most cases, you can leave the default (HTTPS).
Stateful Callbacks
Enabling stateful callbacks changes how offer callbacks are delivered:
- You will receive callbacks for all offer states.
(Previously, onlyCOMPLETEDandRECONCILEDevents were sent.)- Make sure to configure your Offer Reward Callback and Offer Reconciliation Callback separately.
- The transaction ID remains the same across all state changes.
- Reconciliation callbacks no longer include negative values.
If you do not enable stateful callbacks, reconciled events will use a transaction ID prefixed with or instead of o.
You can still link back to the initial event by checking the ref parameter.
Callback Activity
Select the specific activity (state) you want to receive callbacks for. The State Change option corresponds to the PENDING state.
Allow $0 Rewarded Callbacks
This will allow you to receive $0 rewarded callbacks, e.g., for offer installs or in-app purchase events that are not rewarded.
Callback Parameters
Add the parameters your system requires to properly process callbacks.
We strongly recommend including the following:
USER:IDTXVALUE:CURRENCYVALUE:USD
For offer callbacks, we additionally recommend including:
offer_idtask_idoffer_state
The parameter offer_state communicates the current state of the offer:
PENDING, RECONCILED, or COMPLETED. Learn more about offer states here.
Custom Parameter
If you want to attach your own static parameter, you can add it here. Note that only static values are supported.
Example URL
This section displays an example callback URL your system might receive. The hash shown is illustrative and not a valid signature.
Below is an example of how a callback URL could be configured:
Press the Save button and then the Save Changes button in the top right.
Callback batches
In rare cases, event attribution issues may occur, leading us to send batches of callbacks. Your system might mistakenly flag this as fraud.
If you encounter any discrepancies, please contact our team for clarification.
Offer States
Offer callbacks are delivered with different states depending on the lifecycle of the offer task. The following states are available:
Completed
A COMPLETED callback is sent when an offer task is successfully completed.
In some cases, a COMPLETED callback may be sent for completing an install task, which often carries a $0 reward.
Pending
A PENDING callback is sent when an offer is completed but the reward is still pending.
This commonly occurs when delayed crediting (a security feature) is enabled.
After a PENDING callback, one of the following may occur:
- A
COMPLETEDcallback (reward approved) - A
RECONCILEDcallback (reward adjusted or rejected)
Reconciled
A RECONCILED callback is sent when an offer reward is adjusted, either due to:
- A reconciliation event, or
- A rejected event completion (e.g., fraud, timeout, invalid activity)
If a reward is deducted, the deduction amount is included in the VALUE:CURRENCY and VALUE:USD parameters.
Most reconciliations (≈95%) occur within the first 30 days, but they can technically happen at any time.
When does a RECONCILED callback occur?
RECONCILED callback occur?A reconciliation callback may be sent:
-
After a
PENDINGorCOMPLETEDcallback:
When a previously granted reward must be reduced or revoked. -
Without a prior callback:
When the event is reconciled directly—commonly due to rejection.
Reconciliation amount of 0
A reconciliation may have a value of 0 when:
- The reconciled event was non-rewarded (e.g., install-only events), or
- The event was rejected, such as when completed after the
ttc_minuteswindow (time-to-complete).
ttc_minutes defines how long a user has to complete the event after the install occurs.
Behavior with stateful callbacks enabled
- Reconciliations are never negative.
- The transaction ID remains the same for all state changes.
Behavior with stateful callbacks disabled
- Each reconciliation callback receives a unique transaction ID, different from the completed callback.
- To link a reconciliation back to the original event, use the
[%REF%]parameter.
Separate reconciliation endpoint
A dedicated callback field is available if you prefer to receive reconciliation callbacks on a separate endpoint.
Multi-Conversion
In some cases, the same event may be converted multiple times. This does not indicate a state change but rather represents a multi-convertible event. To prevent duplicate processing, always check the transaction ID and implement deduplication logic accordingly.
Make sure to only reward users for offer_state=COMPLETED callbacks!
Ban callbacks
In case of fraud, our system bans users. To help you recognize it, we will send a ban callback:
Use the following macros to properly handle ban callbacks:
| Parameter | Type | Description |
|---|---|---|
| [%BAN:REASON%] | String | Returns the reason for a user ban. |
| [%BAN:STATUS%] | String | Returns ACTIVE or BANNED. |
This will ban the user from all games and offers, and only games and offers. They will still be able to complete surveys and upload receipts.
In-App purchases
Our callback system supports In-App purchase events. When a user makes a purchase in a game, you'll receive a callback event with the purchase amount. It functions like a standard offer task completion callback but includes additional details.
The following callback parameters will help you identify the In-App purchase events:
Parameter | Type | Description |
|---|---|---|
[%OFFER:TASK:IAP:USD%] | String | The USD amount of a single in-app purchase of an app. |
[%OFFER:TASK:HIDDEN%] | Integer | Shows if the in-app purchase event was visible to the user or not: 0 when the event is visible, 1 when it's hidden. |
[%OFFER:TASK:TYPE:ID%] | Integer | 1 – INSTALL: User completed an app install. 2 – EVENT: User completed an in-app event. 3 – PURCHASE: User made an in-app purchase. 4 – ADJUST: Adjust-tracked event. 5 – PLAYTIME: Time-based events (e.g., “Play 5 days in a row”). 6 – APPSFLYER: Appsflyer-tracked event. 7 – SPONSORSHIP: Sponsorship-based reward. 8 – SIGN_UP: User signed up or registered. 9 – DEPOSIT: User made a deposit (e.g., casino/finance apps). 10 – DIRECT_DEPOSIT: Direct deposit event. 11 – ORDERED_LEVEL_EVENT: Level-based ordered actions (e.g., “Reach level 10”). 12 – AD_VIEW: User viewed an ad. 13 – ANY_PURCHASE: Any purchase, regardless of category. 14 – OTHER_SALE: Other types of sales not covered above. null – UNKNOWN: Event type not recognized or not provided. |
[%OFFER:TASK:TYPE:NAME%] | String | Returns the corresponding name to the Type ID. |
You can test in-app purchase callbacks using the callback tester on the dashboard. To do this, simply click the "$1 Offer Completion" button.
Special cases
- In some cases, In-App purchase events will be sent via two callbacks. The first is for the event completion, and the second is for the IAP data. This depends on the advertiser's setup.
- When we don't get the USD value from an IAP from an advertiser, then
[%OFFER:TASK:IAP:USD%]will be empty. - IAP events can be reconciled due to various reasons.
Offer parameters
For offers, we do provide additional parameters for additional information:
Parameter | Type | Description |
|---|---|---|
[%OFFER:ID%] | Integer | ID of the completed task's offer. One offer can have many tasks. |
[%OFFER:TASK:ID%] | Integer | ID of the completed task. |
[%OFFER:TASK:STATE%] | String | It can only be used when using Stateful Offer Callbacks. One of: |
[%OFFER:NAME%] | String | Localized name of the offer. Language is equivalent to what the user saw. |
[%OFFER:TASK:NAME%] | String | Localized name of the task. Language is equivalent to what the user saw. |
[%OFFER:TITLE%] | String | Returns the anchor name of an offer. |
[%OFFER:DELAY%] | Integer | Returns the user reward delay in minutes. |
[%OFFER:TASK:IAP:USD%] | Float | The USD amount of a single in-app purchase of an app. |
[%OFFER:TASK:HIDDEN%] | Integer | Shows if the in-app purchase event was visible to the user or not: 0 when the event is visible, 1 when it's hidden. |
[%OFFER:TASK:TYPE:ID%] | Integer | Shows which type of offer callback it is as a number: 1 for install, 2 for event, 3 for in-app purchase and 4 for time played events (e.g. "Play 5 days in a row"). |
[%OFFER:TASK:TYPE:NAME%] | String | Returns the corresponding name to the Type ID. |
[%OFFER:REJECTION_REASON%] | String | Returns a rejection reason. Find a list of reasons here. |
For a full list of all parameters, click here.
Offer Callback Rejection Reasons
| Code | Description |
|---|---|
| DUPE_COOKIE | Duplicate Cookie |
| POSTBACK_COUNTRY_MISMATCH | Country Mismatch |
| SKIPPED_EVENTS | Skipped Events |
| HIGH_FRAUD_SCORE | High Fraud Score |
| HIGH_IPQS_FRAUD_SCORE | High IPQS Fraud Score |
| ADJUST_FRAUD | Adjust Fraud |
| DCH_IP_BLOCK | DCH IP Block |
| DEVICE_NOT_ALLOWED | Device Not Allowed |
| VC_USER_ALREADY_CONVERTED | User Already Converted |
| TXID_ALREADY_CONVERTED | Transaction ID Already Converted |
| IP_ALREADY_CONVERTED | IP Already Converted |
| CHARGEBACK | Chargeback |
| EVENT_NOT_PROMISED | Event Not Promised |
| CLICK_EXPIRED | Click Expired |
| OFFER_EVENT_EXPIRED | Offer Event Expired |
| VC_USER_BLOCKED | User Blocked |
| NOT_TIME_PLAYED_EVENT | Not Time Played Event |
| TIME_PLAYED_GOAL_MISMATCH | Time Played Goal Mismatch |
| NO_TP_GOAL_ID_PROVIDED_FOR_TIME_PLAYED_EVENT | No TP Goal ID Provided |
| REATTRIBUTED | Reattributed |
How to test offer callbacks
We offer a callback tester on the dashboard to test your configured callback endpoints. Learn more about it here.
Testing with real offers
To test with a real offer you can visit the offer wall, select a game, and install it. This way you will either receive a COMPLETED offer callback or a PENDING one, depending on whether delayed crediting is enabled or not.
Frequently Asked Questions
Find a list of frequently asked questions.
I'm getting a 3103 error when testing
This issue can appear due to many factors. Please contact your account manager for more insights, and make sure to provide your user ID.
Updated 6 days ago
