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, only COMPLETED and RECONCILED events 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:ID
  • TX
  • VALUE:CURRENCY
  • VALUE:USD

For offer callbacks, we additionally recommend including:

  • offer_id
  • task_id
  • offer_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 & timing

In rare cases, attribution delays or processing issues may result in callbacks being sent in batches. This can sometimes appear unusual and may be mistakenly flagged as fraudulent activity. Additionally, progression events may occasionally be received before the corresponding install event.

To avoid incorrectly rejecting valid conversions, please do not automatically flag these cases as fraud. If you encounter uncertain or unexpected event sequences, contact our team for assistance before taking action.

🚧

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 COMPLETED callback (reward approved)
  • A RECONCILED callback (reward adjusted or rejected)

Reconciled

A RECONCILED callback is sent when an offer reward is reverted, 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. We will always deduct the full event (task) reward amount; there are no partial deductions at the event (task) level.

Most reconciliations (≈95%) occur within the first 30 days, but they can technically happen at any time.

When does a RECONCILED callback occur?

A reconciliation callback may be sent:

  • After a PENDING or COMPLETED callback:
    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_minutes window (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.

Possible State Transitions & Final State

For offer callbacks and states, there is no definitive final state. Reconciliations can occur at any time. However, in the vast majority of cases, no reconciliation will be sent more than 30 days after the COMPLETED state was triggered.

The following state transitions are possible:

  • PENDINGCOMPLETED
  • PENDINGRECONCILED
  • COMPLETEDRECONCILED
  • RECONCILEDCOMPLETED (Rare case of false positive)

RECONCILED and COMPLETED states can also occur immediately.

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:

ParameterTypeDescription
[%BAN:REASON%]StringReturns the reason for a user ban.
[%BAN:STATUS%]StringReturns 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:

ParameterTypeDescription
[%OFFER:TASK:IAP:USD%]StringThe USD amount of a single in-app purchase of an app.
[%OFFER:TASK:HIDDEN%]IntegerShows 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%]IntegerList of all event types: https://developer.bitlabs.ai/docs/offer-api#event-type-ids
[%OFFER:TASK:TYPE:NAME%]StringReturns the corresponding name to the Type ID. List of all event types: https://developer.bitlabs.ai/docs/offer-api#event-type-ids

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:

ParameterTypeDescription
[%OFFER:ID%]IntegerID of the completed task's offer. One offer can have many tasks.
[%OFFER:TASK:ID%]IntegerID of the completed task.
[%OFFER:TASK:STATE%]StringIt can only be used when using Stateful Offer Callbacks. One of: NONE, COMPLETED, PENDING, RECONCILED. It isNONE if stateful offer conversion callbacks are disabled (this is the default). If they are enabled, however, it indicates the latest state of the offer conversion.
[%OFFER:NAME%]StringLocalized name of the offer. Language is equivalent to what the user saw.
[%OFFER:TASK:NAME%]StringLocalized name of the task. Language is equivalent to what the user saw.
[%OFFER:TITLE%]StringReturns the anchor name of an offer.
[%OFFER:DELAY%]IntegerReturns the user reward delay in minutes.
[%OFFER:TASK:IAP:USD%]FloatThe USD amount of a single in-app purchase of an app.
[%OFFER:TASK:HIDDEN%]IntegerShows 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%]IntegerShows 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%]StringReturns the corresponding name to the Type ID.
[%OFFER:REJECTION_REASON%]StringReturns a rejection reason. Find a list of reasons here.

For a full list of all parameters, click here.

Offer Callback Rejection Reasons

CodeDescription
DUPE_COOKIEDuplicate Cookie
POSTBACK_COUNTRY_MISMATCHCountry Mismatch
SKIPPED_EVENTSThe user skipped events.
HIGH_FRAUD_SCOREHigh Fraud Score
HIGH_IPQS_FRAUD_SCOREHigh IPQS Fraud Score
ADJUST_FRAUDAdjust MMP detected the conversion as fraud.
DCH_IP_BLOCKDCH IP Block
DEVICE_NOT_ALLOWEDDevice Not Allowed
VC_USER_ALREADY_CONVERTEDUser Already Converted
TXID_ALREADY_CONVERTEDTransaction ID Already Converted
IP_ALREADY_CONVERTEDIP Already Converted
CHARGEBACKChargeback of rewards.
EVENT_NOT_PROMISEDThe event_not_promised unapproved_reason is triggered when a conversion is attempted for an event that was not defined or available at the time of the original click. This typically occurs when the event configuration is created or updated after the user interaction, resulting in a mismatch between the tracked click and the expected conversion event.
CLICK_EXPIREDClick Expired
OFFER_EVENT_EXPIREDOffer Event Expired
VC_USER_BLOCKEDUser Blocked
NOT_TIME_PLAYED_EVENTNot Time Played Event
TIME_PLAYED_GOAL_MISMATCHTime Played Goal Mismatch
NO_TP_GOAL_ID_PROVIDED_FOR_TIME_PLAYED_EVENTNo TP Goal ID Provided
REATTRIBUTEDReattributed

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.