LootHQ

Publisher docs

Integrate your app with LootHQ

The same integration guide publishers see inside the dashboard.

Worked example

One user, one two-goal offer, and every request you would actually receive.

Worked example, end to end

One user, one offer, every request you would actually receive, with real-shaped values you can trace from step to step. This example is an Offers API placement running a two-goal offer ("signup", then "deposit") and the shipped default templates. The cast:

  • Your user: u123 (the user_id you sent on the feed call).
  • The offer: id 64f3b2a1c9d4e5f601234567, paying you $2.50 for signup and $7.50 for deposit; your placement margin leaves the user reward at $1.25 / $3.75.
  • Your shared secret: kq8Zw3vN7Rp2 (what you swapped in for YOUR_SECRET when you saved the templates).
  1. 1u123 opens the offer. You linked them to the feed's trackingUrl; we record the click and mint its id: b3f1c9a2-7e44-4f1a-9c2d-0a6e8d5b21c7. Everything that follows hangs off that one id.
  2. 2The signup goal is approved → we GET your primary postback URL. With the default template, every param is present; note points= arriving empty (no coin step on this channel) and event=signup:
    Primary postback: goal 1 (signup)
    https://your-site.com/postback?key=kq8Zw3vN7Rp2&user_id=u123&tx=b3f1c9a2-7e44-4f1a-9c2d-0a6e8d5b21c7&points=&payout=1.25&currency=USD&offer_id=64f3b2a1c9d4e5f601234567&status=approved&event=signup
    Your handler: status is approved, the pair (b3f1c9a2…, signup) is new → store it, convert payout=1.25 into your currency, credit u123, answer 200.
  3. 3A week later u123 deposits → a second, separate credit on the same click. Same tx, different event:
    Primary postback: goal 2 (deposit)
    https://your-site.com/postback?key=kq8Zw3vN7Rp2&user_id=u123&tx=b3f1c9a2-7e44-4f1a-9c2d-0a6e8d5b21c7&points=&payout=3.75&currency=USD&offer_id=64f3b2a1c9d4e5f601234567&status=approved&event=deposit
    The pair (b3f1c9a2…, deposit) is new → credit again. A handler deduping on tx alone would have answered "already processed" here and silently kept u123's deposit reward. That is the bug the pair exists to prevent.
  4. 4The signup conversion is charged back → a reversal arrives, on your reversal URL only, never on the URL above. With the default reversal template:
    Reversal postback (separate URL)
    https://your-site.com/reversal?key=kq8Zw3vN7Rp2&user_id=u123&tx=b3f1c9a2-7e44-4f1a-9c2d-0a6e8d5b21c7&event=d9c1e6b0-2f7a-4c3e-8a11-6f2b8c4d7e90&coins=0&points=0&payout=2.00&reason=chargeback&status=reversed
    Read it carefully against step 2: tx is the same click id, so you can join it to the credits you stored, but event is now a fresh delivery UUID, not "signup", and coins=0 and points=0 because an Offers API conversion has no coin layer; payout=2.00 carries the full USD value credited at approval, which is the amount to take back. Your handler: status is reversed → take the reversal branch, check the UUID d9c1e6b0… is unseen (dedupe key on this channel), record it, take back what you credited for the signup, answer 200. If the delivery is retried, the same UUID arrives again and your check swallows it.

On a hosted wall the ids are identical; only the amounts change: points arrives filled (the amount in your currency), coins shows the coin grant, and currency is your currency's name instead of USD. Same click id in tx, same goal id in event, and a reversal's tx joins to your stored credits the same way. See Dedupe keys per channel.