A postback (s2s, server-to-server) is a request that AFF1 sends to your tracker or another service when something happens to a lead: it is created, approved or cancelled. The tracker matches the request to the click by the click ID and counts the conversion and its status.
Before you start
Your tracker must pass its click ID to AFF1 — otherwise the postback has nothing to match. When you get the flow link, tick Use clickid for external tracker integration and enter the tracker’s click ID macro, for example {subid} in Keitaro or {clickid} in Binom (see How to get the traffic link). AFF1 stores this value and returns it in the {clickid} token.
You also need the postback URL of your tracker. Trackers show it in their settings; see the guides for Keitaro, Binom and AdsBridge.
Add a postback to a flow
- Open Tools → Flows and click the flow name.
- Expand the Postback section and click Create postback.
- Type: keep s2s. (The Facebook Conversion API type is described in a separate article.)
- Tick the events that should trigger the postback: Creating lead, Confirming lead, Cancelling lead.
- Paste the postback URL of your tracker into URL and add AFF1 tokens with the buttons under Available URL tokens (see the table below).
- Request method: GET works for almost all trackers; choose POST only if your tracker requires it.
- Click Add. The postback is saved immediately and appears in the list.

A typical URL:
https://tracker.example.com/postback?subid={clickid}&status={type}&payout={payout}¤cy={currency}
The URL must point to a public address that resolves in DNS, otherwise AFF1 rejects it with The url must point to a public address. The same URL cannot be added to one flow twice.
A flow can have several postbacks, for example to a tracker and to Facebook. Use the gear icon next to a postback to Edit or Delete it.

URL tokens
| Token | What AFF1 puts into it |
|---|---|
{clickid} | External click ID — the value from clickid in the flow link |
{type} | Event: lead_add (lead created), lead_approve (lead confirmed), lead_cancel (lead cancelled) |
{substatus} | Lead substatus: trashed if the lead was sent to trash |
{payout} | Amount credited to the hold, in the offer currency |
{payout_usd} | The same amount in USD |
{currency} | Offer currency: USD or EUR |
{lead_hash} | Lead ID in AFF1 |
{offer_hash}, {flow_hash} | Offer ID and flow ID |
{landing_hash}, {transit_hash} | Landing ID and pre-landing ID |
{data1} … {data4} | Values of the data parameters from the flow link |
{ip} | Visitor IP |
{unixtime} | Date and time of the event (Unix time) |
The Parameters details link in the window shows the same descriptions.
Most trackers need to know which event the postback reports. Pass {type} in the status parameter and map the values lead_add, lead_approve and lead_cancel to the tracker’s statuses — the tracker guides show how.
Check the tracker’s response (optional)
Tick Response verification if you want AFF1 to check what the tracker answers. Check type:
- Response HTTP code — the response must have the code you enter, for example
200; - String availability in response content — the response must contain the text you enter;
- Exact response content match — the response must be exactly the text you enter.
Global postback for all flows
If one tracker receives all your traffic, you don’t have to add the postback to each flow. Open Account Settings → Global postback (you can also get there with the Global postback link on the Tools → Flows page) and click Create postback. The form is the same; the global postback supports only the s2s type.

The switch Use as a priority s2s postbacks at flow level decides what happens when a flow has its own s2s postback:
- on (default) — for such flows only the flow postback is sent, the global one is skipped;
- off — both are sent: the global postback for every conversion plus the flow postback where it exists.
| Your setup | Where to add postbacks | Switch |
|---|---|---|
| One tracker | Global postback only | Doesn’t matter |
| Several trackers | A postback in each flow | Doesn’t matter |
| One main tracker, some flows tested in another tracker | Global postback + postbacks in the test flows | On |
| One main tracker, some sources also need conversions in another service | Global postback + extra postbacks in those flows | Off |
Check that it works
- Open Tools → Postback logs, choose the Created date range and click Apply. The log lists the sent postbacks with the tracker’s response. Secret parameters such as tokens are hidden in the logged URL.
- If your tracker was unavailable for a while, click Resend postbacks to send the postbacks for the selected dates again.
- In the tracker, open its postback or conversion log and check that the click ID and status arrived.
Common problems
- The tracker gets an empty click ID — the flow link has no
clickidparameter, or the tracker macro is misspelled. Get the link again with Use clickid for external tracker integration ticked. - Every lead is counted as a sale — the URL has no status, or
lead_addis not mapped to a “lead/pending” status in the tracker. - Trash leads look like ordinary cancellations — trash arrives as
lead_cancelwith{substatus}=trashed. Pass{substatus}in a separate parameter if you need to tell them apart. - Revenue in the tracker is in the wrong currency —
{payout}is in the offer currency. Pass{currency}or use{payout_usd}. - The global postback is not sent for some flows — those flows have their own s2s postback and the priority switch is on.