The guide to the TDS on Cloudflare Workers stops at the redirect. The Worker answers the browser with a 302, the browser opens the offer, and from that moment the Worker sees nothing. The registration or the deposit happens on the network’s site, on a domain you do not control, where you cannot put a pixel.
A postback is how that event comes back. It is a server to server (S2S) request: when the visitor converts, the network calls a URL you gave it and puts the conversion details into the query string. For the call to mean anything, it has to say which click it belongs to. Getting the click into the network’s hands is the work of the redirect.
This article shows how the TDS in 301.st does both halves: what it adds to the offer link, what the network has to send back, what a conversion changes inside the platform, and how it gets back to the ad network that sold you the click. The TDS is the tracker here: the click, the rule and the conversion meet in one place, with nothing in between. Everything here was read from the platform’s source code on 6 October 2026. The general version of this loop, built by hand on a Worker, is in the article on attribution when the conversion page is not yours.
The loop
Two things have to hold. The redirect has to put an identifier into a parameter the network keeps, and the network has to return that parameter unchanged in its postback. The rest is the settings of the postback source, described below.
What travels with the click
For every request the Worker makes a click id: 32 hexadecimal characters, the first part of which is the time of the click. On a redirect, it also builds a click token around that id. The token carries the rule that matched, the visitor’s country and device, and, for a split, the page variant that was picked. It is signed with HMAC, and the signature is checked when the token comes back. A token that someone edited or made up fails that check.
The platform does not keep a table of clicks. The token is the record of the click, and that is why it is signed: everything the platform learns about a conversion, it reads out of the token the network returned. A token is 44 characters long, or 58 for a split rule, and the platform stops accepting it 90 days after the click.
Whether a rule adds the token is the setting Click key in the URL on the rule:
| Choice | What the offer link gets |
|---|---|
| Don’t add | nothing; the link goes out as you wrote it |
| 301 key (_cid) | the token in a parameter named _cid |
| Source parameter | the token in the parameter your postback source names, such as sub1 |
“Don’t add” is right for a white page, a bot filter, or any link that does not lead to an affiliate network. The other two are for conversions that come back to 301.st as postbacks. The third one needs a postback source picked on the rule, because the parameter name comes from it.
The Worker writes the token over any parameter of the same name already in the link. If your
offer URL contains sub1=something and the source’s parameter is sub1, the network gets
the token. The rule editor warns about this when you save.
The token is added to an HTTP redirect and to a split. A rule that sends visitors with a meta refresh, JavaScript or an iframe gets no token, and its conversions cannot be attributed.
{clickid} is not the key
Target URLs take macros, and two of them matter for tracking.
{clickid} puts the raw 32 character click id into the link. It is the same id that sits
inside the token, but it is not signed and it carries nothing else. A network that returns
it in a postback returns a value the platform cannot match: the conversion is recorded as
unmatched. Use {clickid} when a network wants your id in a field of its own,
and let the token go into the parameter the postback reads.
{q.name} puts a parameter of the incoming request into the link. A visitor who arrives as
go.example.com/promo?cid=AD123 can be sent on as
https://network.example/offer?sub2={q.cid}, and the network receives sub2=AD123. The
value is URL encoded and cut at 256 characters; a parameter that is not there becomes an
empty string. This is how the ad network’s own click id, or the gclid from Google Ads,
rides along to the affiliate network and comes back in the postback. {q.name} works in any target URL today but is not yet in the macro list of the
editor, so type it by hand.
The postback source
A postback source is one network, or one campaign of a network, as 301.st sees it. You find the list under Postbacks, Postback sources. When you add one, the platform can fill most of it for you in two ways. You can paste a postback URL the network gave you, with its macros, and the platform tries to recognize the network. Or you can save the source as a draft, ask the network to fire one test postback at the address shown, and let the platform learn the field names from that request.
The settings that decide whether conversions match:
Click parameter. The name of the parameter that carries the token, _cid if you leave
it empty. Set it when the network dictates its own name, as most do: sub1, subid,
data1, btag.
Macro syntax. How the network writes its macros in postback URLs: {sub1}, [SUB1],
${sub1} and so on. The platform uses it to build the URL you paste back.
Field mapping. For each field the platform understands, the name of the parameter the network sends: Click ID, Event type, Transaction ID, Gross amount and currency, Payout amount and currency, External user ID. A source without a Click ID mapping records every conversion as unmatched, and the editor shows a banner until you set it.
Event mapping. Networks name their events differently. This table translates the
network’s names into the ones 301.st reports on, such as registration and ftd. An event
the table does not know is recorded as unknown and does not reach your numbers. A network
that cannot send the event name at all gets one postback URL per event instead, each with
the event written into it as event_type=ftd, as in the example below.
Then there is how the network proves it is the network. The default is a secret token in every postback URL, generated for the source. The alternatives are a list of the network’s IP addresses, an HMAC signature in a header, or nothing at all. An extra IP check can sit on top of the token.
Three more settings shape what is counted. The attribution window in days, 90 by default: a conversion that arrives later than that after the click is recorded as expired. The payout currency: a postback that reports a different currency is set aside rather than added to your totals. And the program key: give several sources the same key when they are campaigns of one affiliate program, so the same transaction arriving through two of them is counted once.
When the source is saved, the platform builds the postback URLs, one per event:
https://api.301.st/tds/postback/<source_id>?token=<secret>&sub1={sub1}&event_id={event_id}&user_id={user_id}&amount={amount}&event_type=ftd
Paste each into the matching field of the network’s postback form. The parts in braces are the network’s own macros, which it fills in when it calls.
What happens when a postback arrives
The platform answers the network at once and stores the request. Processing starts immediately; anything left over is picked up by an hourly job. Then, in order:
- The fields are read through the mapping. A macro the network failed to fill in, such as a
literal
{sub1}, counts as an empty field rather than as a value. - The token is checked. A valid one gives the rule, the country, the device and the split variant of the original click.
- The conversion is deduplicated. With a transaction id, the same transaction and event are counted once, however many times the network retries. Without one, the platform falls back to click, event, amount and minute.
- The conversion is recorded as matched, unmatched, or expired.
A matched conversion goes into hourly totals per rule, variant, country, device, event and currency. A refund or a chargeback comes in as a negative amount and is attached to the conversion it cancels.
Not every event teaches a split. The split counts acquisition events, such as a registration
or a first deposit, against the clicks each page got. Later money events, deposit,
revshare and ngr, add revenue to the rule but do not move the split, because they come
from a player the page has already brought in. The Worker picks up the new split numbers
with its next sync. Click counters travel the other way: your Worker sends them to the
platform once an hour, for each hour that has ended, so a rule’s click numbers run an hour or
two behind its conversions.
Revenue share outlives the token. A network that pays revshare sends payments for months, long after the 90 days. If the network sends a stable id for the player, mapped as External user ID, the first matched conversion links that player to the click. For the next 365 days, payments for the same player are attributed to the same rule even without a valid token. These payments count toward the rule’s revenue and, like other money events, leave the split alone.
Passing the conversion on
301.st can send each conversion on to three places, set per postback source.
A GET to the traffic source, the ad network that sold you the click. It optimizes your
campaign on the conversions it is told about, against its own click id. You give a URL
template with the macros {source_click_id}, {event}, {payout}, {currency} and
{txid}. It is sent only for the events you list, never for negative ones, and only when the
conversion carries the network’s click id.
A signed POST to your own endpoint. The field Outbound target URL on the source. Each
conversion is sent as JSON with an X-301-Signature header, so the receiver can check it
came from the platform. This is the way into your own reports or CRM.
A GET to any other URL that takes a postback. You give a template, and the platform fills
these macros: {click_id}, {source_click_id}, {event}, {payout}, {gross},
{currency}, {txid}, {conversion_id}, {rule_id}, {country}, {device}.
The two GETs have no screen in the 301.st interface yet; they are set through the API, on
PATCH https://api.301.st/tds/postback-sources/<id>, as source_postback_url,
source_postback_events and outbound_get_url. The same goes for the source click id
mapping, source_click_id in field_map, which the next example needs. A screen for them
is being built.
Templates must use https and a host name, not an IP address. Values are URL encoded, and a value the conversion does not have becomes empty. A failed delivery is retried on a server error, a timeout or a rate limit answer: six attempts in all, after waits of 30 seconds, 2 minutes, 10 minutes, an hour and 6 hours. Any other 4xx answer stops the retries, because sending the same request again will not change it.
One click, end to end
Here is the whole loop as one setup: an ad network sends the click, an affiliate network pays for the deposit, and the ad network learns which of its clicks paid off.
The ad network puts its own click id into the ad’s link, as cid. The postback source for
the affiliate network has the click parameter sub1. Through the API, the source maps
source_click_id to sub2, lists ftd in source_postback_events, and has this template
for the ad network:
https://ads.example/conversion?click_id={source_click_id}&event={event}&payout={payout}¤cy={currency}
The rule redirects with the click key in the source parameter, to this target:
https://network.example/offer?sub2={q.cid}&geo={country}
- The ad is clicked, and the visitor lands on
https://go.example.com/promo?cid=AD123. - The TDS rule matches and the Worker answers
302withLocation: https://network.example/offer?sub2=AD123&geo=DE&sub1=<token>. - The visitor registers and deposits. The affiliate network calls the postback URL for
ftd, withsub1=<token>andsub2=AD123filled in. It has to return both. - 301.st checks the token, records an
ftdfor the rule in Germany, and fills the template:https://ads.example/conversion?click_id=AD123&event=ftd&payout=....
The ad network now sees a deposit on its own click AD123 and can bid on it. One thing is left
to you: the event arrives under 301.st’s name, ftd here. If the ad network expects a name
of its own, write that name into the template in place of {event}; with only ftd in the
list, the template is used for nothing else.
Where it does not reach
- A conversion is attributed only through the token. A network that cannot return a parameter verbatim cannot be attributed, whatever else it sends.
- Rules that redirect with meta refresh, JavaScript or an iframe send no token.
- A token older than 90 days is not read, and the source’s attribution window can make that shorter. Revenue share is covered by the player link, if the network sends a player id.
- Postbacks are stored and processed in the platform’s own database, so they do not count against your Cloudflare D1 allowance. The click counters do: each click on a rule writes to your D1, which the TDS guide counts in its section on the Free plan.
If conversions do not match, check the redirect first. Open the rule’s link in a browser and look at the address the offer opens with: the token has to be there, in the parameter the network keeps. Then check that the network’s postback URL returns that parameter.