Server-to-Server Callbacks: Complete Developer Guide for Offerwall Integration
What are S2S Callbacks?
Server-to-server (S2S) callbacks — also called postbacks — are HTTP requests sent from a monetization platform’s server to the developer’s server when a conversion event occurs. They’re the mechanism that makes server-side reward validation possible.
When a user completes an offer (installs an app, completes a survey), the advertiser reports the conversion to the tracking engine. The tracking engine validates the conversion and sends an HTTP request to your postback URL with the conversion data. Your server processes this, validates it, and credits the user. The user’s device is never involved in the validation.
The Postback Flow
User completes offer → Advertiser reports conversion → Tracking engine validates → S2S Postback → Your server validates → Credit user
Configuring Your Postback URL
In the Perkox Publisher Dashboard, set your postback URL with placeholders:
https://yourdomain.com/perkox/postback?user_id={player_id}&click_id={click_id}&offer_id={offer_id}&reward={reward_amount}&payout={payout}&status={status}
Perkox replaces the placeholders with real values at runtime. Supported: {player_id}, {click_id}, {offer_id}, {reward_amount}, {payout}, {status}.
The Four Reward Statuses
| Status | Meaning | Action |
|---|---|---|
| pending | Under review | Do NOT credit |
| approved | Validated | Credit the user |
| rejected | Not approved | Do NOT credit |
| reversed | Previously approved, reversed | REMOVE credit |
Implementation (Node.js)
app.get('/perkox/postback', async (req, res) => {
const { user_id, click_id, reward, status } = req.query;
if (status !== 'approved') return res.status(200).send('OK');
const existing = await db.query('SELECT id FROM rewards WHERE click_id = $1', [click_id]);
if (existing.rows.length > 0) return res.status(200).send('OK'); // dedup
await db.query('INSERT INTO rewards (user_id, click_id, amount) VALUES ($1,$2,$3)', [user_id, click_id, parseFloat(reward)]);
await db.query('UPDATE users SET balance = balance + $1 WHERE id = $2', [parseFloat(reward), user_id]);
res.status(200).send('OK');
});
FAQ
Why not use client-side callbacks? Client-side callbacks are spoofable. S2S postbacks are server-verified and cannot be manipulated by the user.
What if my server is down? Perkox will retry. Your handler must be idempotent — use click_id as a dedup key.
GET or POST? GET is simpler and recommended for most integrations. POST is available for advanced backends.
