Postbacks: how your server learns a user earned something

When a conversion is approved, or reversed later, we call a URL on your server with the user's ID and the reward. Every call can be signed, failed calls are retried, and retries carry the same ID so you never credit twice.

Sent on
Approval, and reversal of an approved conversion.
Signature
HMAC-SHA256 with your own secret.
Retries
After 1, 5, 30, 120 and 720 minutes.
Success
Any 2xx response within 10 seconds.

When we send one

Two moments. When the advertiser confirms a conversion, we send status=approved and you credit the user. If the advertiser later reverses it, within 30 days, we send status=reversed for the same conversion and you take the reward back or flag the account.

Conversions the advertiser reports as pending are not sent until they are approved, so you never credit something that is not confirmed yet. Multi-step offers send one postback per step.

Building your URL

You set the URL in your dashboard and put placeholders where you want values. We fill them in, URL-encoded, and call it with a GET request:

https://api.yourapp.com/rewards?user={user_id}&points={reward}&status={status}&id={conversion_id}&sig={signature}

Available values: user_id, reward, payout, status, conversion_id, event, event_title, offer_id, offer_name, click_id, country and signature.

Checking the signature

Anyone who finds your postback URL could call it and credit themselves. The signature stops that. It is a code worked out from the postback's details and a secret that only you and we know. Your server works it out again and turns away any postback where the two don't match.

The postback docs have ready-to-use examples for Node.js, PHP and Python.

Crediting exactly once

Networks retry, and so do we: if your server is down or answers with an error, the same postback comes again later. Store each conversion_id with its status the first time you handle it. If you see the same ID and status again, answer 200 and do nothing.

Answer with any 2xx status once you have recorded it. Anything else, or no answer within 10 seconds, counts as a failure and is retried after 1, 5, 30, 120 and 720 minutes. After the last try it is marked failed in your dashboard and you get a notification.

Handling reversals

A reversal means the advertiser decided the conversion should not count, usually a refund, a chargeback or a fraud finding. Take the reward back if the user still has it. If they already spent it, a negative balance or a hold on their next withdrawal are both common. Either way, your own earnings for that conversion come off your next payout, so it pays to mirror the reversal.

Testing

Save your URL, then press Send a test postback in the dashboard. It calls your URL with sample values and shows the status code your server returned. Every real postback and its response is listed below it, which is the first place to look when a user says a reward never arrived. Building the rest of the integration? Start with the offers API.

Questions

What is a postback URL?

An address on your server that we call when one of your users' conversions is approved or reversed. It carries the user ID and the reward so you can credit them without trusting anything from the app.

How do I verify the HMAC signature?

Compute HMAC-SHA256 of conversion_id:user_id:reward:status with your postback secret, as hex, and compare it to the signature value using a constant-time comparison.

What happens if my server is down?

We retry after 1, 5, 30, 120 and 720 minutes. Each retry carries the same conversion ID, so you can safely ignore one you have already handled.

What is a reversal in an offerwall?

The advertiser taking back a conversion it had approved, for example after a refund or a fraud check. We send a postback with status reversed so you can remove the reward.