Postbacks
Postbacks
When a conversion is recorded, AffiLayer can notify your server. Postbacks are server-to-server GET requests to a URL you configure, with macros expanded and an HMAC signature you can verify.
Setting one up
Set your postback URL in the dashboard, on the Postbacks page of your affiliate account. You can configure a different URL per offer.
Macros
These placeholders in your URL are replaced with the conversion's real values:
| Macro | Value |
|---|---|
{click_id} | The click ID the conversion is attributed to. |
{conversion_id} | The conversion's own ID. |
{payout} | The conversion payout amount. |
{currency} | The payout currency. |
{status} | The conversion status at the time of the postback (starts as pending). |
{sub1} | The click's sub1 value, if one was passed. |
Example:
https://tracker.example/postback?click_id={click_id}&payout={payout}¤cy={currency}&status={status}
Verifying the signature
Every postback carries a signature header:
x-affilayer-signature: <hex>
The value is the HMAC-SHA256 of the raw request body, keyed with your postback secret, hex-encoded. An optional sha256= prefix is accepted. To verify, recompute the HMAC over the raw body with your secret and compare the two hex strings in constant time. If the header is missing or does not match, reject the postback.
Example verification (Node.js):
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyPostback(secret, rawBody, header) {
if (!header) return false;
const given = header.startsWith('sha256=') ? header.slice(7) : header;
const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
if (given.length !== expected.length) return false;
return timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
Delivery and retries
- One initial attempt plus up to 3 retries with exponential backoff, on network errors or non-2xx responses.
- Every delivery attempt is recorded as a postback event, so you can see what was sent, when, and what came back.
- A failed postback never fails the conversion itself โ the conversion is recorded regardless.
Keep your secret secret. Your postback secret signs every notification. Do not put it in client-side code, public repositories or shared documents.