Skip to content
All articles
10 min read

Postback URL Parameters: Click ID, Sub ID and Macros Explained

One click token completing a server-to-server conversion loop through three differently shaped tracking relays

The most confusing postback URL often looks harmless:

https://track.example.com/p?click_id={subid}&status={status}&payout={payout}

Why does the left side say click_id while the right side says {subid}? Which one is the real click ID? And why might another tracker use cid={s2} for the same job?

The short answer is that a postback parameter has two owners. The receiving tracker defines the key on the left of =. The affiliate network sending the request defines the macro on the right. At runtime, the network replaces that macro with a real value. The names do not need to match; the value does.

This guide explains that mapping, the difference between click ID and sub ID, and the exact tests that prove a postback works. If you need the broader server-to-server concept first, start with what S2S postback tracking is.

The three parts people call “a macro”

Take this pair:

click_id={subid}

It contains three distinct things:

LayerExampleWho controls itJob
Target parameter keyclick_id=The receiving trackerTells the receiver where to read the value
Source macro{subid}The sending networkTells the sender which stored value to insert
Resolved runtime value8f2a91c0d3Created earlier in the click flowIdentifies the actual click

After macro replacement, the request no longer contains braces:

https://track.example.com/p?click_id=8f2a91c0d3&status=deposit&payout=45.00

If the raw request still contains click_id={subid}, the network did not recognize or expand the macro. A browser may still return 200 OK, but attribution is broken.

An empty receiver socket, a replaceable token stencil and the final resolved token shown as three separate layers

A click ID is a unique identifier for one tracked click. It is the join key between the outbound click and the later conversion. If 10,000 people click, a tracker should create 10,000 click IDs.

A sub ID is a generic field used to carry or store a value. It might contain a tracker click ID, but it can also contain a placement, buyer code, creative angle or campaign label. sub1=facebook_feed is useful segmentation; it is not a unique click identifier.

This is why a network may ask you to pass your click ID into its subid, aff_sub, s2 or sub1 field. The network is not changing the identity. It is storing your click ID in an available slot so it can send the same value back after conversion.

Do not confuse either of them with:

  • Campaign, ad set or ad ID: identifies a group of clicks, not one click. Use the Facebook URL parameter mapping or TikTok macro mapping to capture that hierarchy.
  • fbclid or ttclid: a platform click identifier. It can help platform attribution, but your tracker still needs a stable internal click ID for its own conversion lookup.
  • Transaction ID: identifies one conversion. One click can produce registration, first deposit and redeposit transactions, each with a different transaction ID.

The complete click-to-postback round trip

Imagine DarkCore sends traffic to an affiliate network whose available storage field is aff_sub.

1. The tracker creates the click ID

A user opens the Track Link. DarkCore logs the source context and creates:

dc_01K2A7M9X4

2. The tracker passes it to the offer

The offer URL contains a DarkCore-owned outbound macro:

https://network.example/offer?aff_sub={click_id}

DarkCore expands its macro before redirecting:

https://network.example/offer?aff_sub=dc_01K2A7M9X4

The network receives the real value under its aff_sub key and stores it.

3. The network sends it back

In the network’s postback settings, the direction reverses:

https://track.example.com/p?click_id={aff_sub}&status={status}&payout={payout}&transaction_id={conversion_id}

Now click_id and transaction_id are keys understood by the receiving tracker. {aff_sub}, {status}, {payout} and {conversion_id} are macros understood by the sending network.

4. The tracker attributes the conversion

The live callback might be:

https://track.example.com/p?click_id=dc_01K2A7M9X4&status=ftd&payout=45.00&transaction_id=conv_7719

The tracker finds the original click, maps ftd to the intended conversion status, attaches the payout and uses conv_7719 to recognize a literal retry.

That round trip is the entire postback contract: send one exact click value forward, store it unchanged, return it under a key the tracker accepts.

Why macro syntax differs between trackers and networks

There is no universal macro standard. Each product owns its template engine and parameter vocabulary.

Keitaro’s official postback guide uses subid to find the click and documents aliases for incoming parameter names. Voluum’s documentation shows the same value changing labels across the route: a Voluum {clickid} can be stored in a network field such as s2, then returned to Voluum as cid={s2}. Affise documents {clickid} and {click_id} variants depending on the integration.

The practical rule is:

On the left, use the parameter name your receiving system accepts. On the right, use the macro syntax your sending system documents.

Never copy a whole postback template from another tracker just because the concepts look familiar. {click_id}, {clickid}, {subid}, ${click_subid} and {s2} may all refer to a click value in some platform, but they are not interchangeable template syntax.

Postback parameters DarkCore accepts

DarkCore accepts common aliases so a partner does not always need to rename its existing fields:

MeaningAccepted incoming keys
Click IDclick_id, clickid, cid, subid, sub_id
Statusstatus, goal, event
Payoutpayout, sum, amount, revenue
Transaction IDtransaction_id, txid, tx_id, transactionid, conversion_id, conv_id
Conversion timeevent_at, event_time

These are incoming query keys, not a promise that every network understands macros with the same spelling. If a network documents {click_subid}, a valid mapping can be:

https://track.example.com/p?click_id={click_subid}&status={goal}&payout={commission}

Use the network’s exact macros on the right. Use one of the tracker’s accepted keys on the left.

Status, payout and transaction ID need separate mapping

Returning the click ID is necessary, but it is not a complete conversion record.

Status

Networks may send lead, reg, registration, sale, deposit, dep or ftd. Map raw network values into the conversion statuses used by your workspace. A successful click match with the wrong status can still route the event incorrectly or exclude it from the metric you optimize.

Payout

Pass the numeric commission, not a formatted string such as $45 USD. Confirm whether the network macro represents gross revenue, your commission or order value. A parsed number can still be the wrong business metric.

Transaction ID

Use the network’s unique conversion identifier whenever available. In DarkCore, a supplied transaction ID makes idempotency specific to that conversion and status. Without it, the safe fallback is the click ID plus canonical status. The distinction matters when one click may generate multiple real transactions.

A conversion ledger accepts the first token while a guarded side gate safely holds an identical retry

A pass/fail test for the full chain

Do not sign off with “the URL opened” or “the endpoint returned 200.” Record evidence at every handoff:

TestPass conditionPass?
Original clickThe tracker logs one new click and creates a click ID
Outbound offer URLThe network receives the exact click ID, with no literal {click_id} left
Network storageIts click/conversion log shows that same value in the configured sub field
Raw postbackThe returned value is byte-for-byte identical under an accepted click key
StatusThe raw status maps to the intended canonical conversion
TransactionA unique conversion ID is present when the network provides one
RevenuePayout is numeric and represents the agreed business value
RetryRepeating the same transaction does not duplicate conversion or revenue
ReportingThe conversion appears on the original click, campaign and stream

Use the Postback URL Builder and S2S tester to assemble a callback and generate a safe test command. Then verify the raw ingress log and the final conversion row. A 200 OK only confirms how the endpoint responded; it does not prove the click was found, the status was right or the payout meant what you thought it meant.

For a complete outbound-link-to-callback example, use the affiliate tracking link guide. If Keitaro owns the click, follow the dedicated Keitaro postback setup for subid, status training, payout and tid.

Common failure patterns

  • Literal braces return in production. The sender did not recognize the macro. Check its documentation and the field in which postback macros are actually supported.
  • The click ID changes case, length or encoding. Treat it as an opaque string. Do not parse, trim or rebuild it between systems.
  • A campaign ID is returned as click_id. Thousands of clicks collapse onto one non-unique value, so attribution cannot be trusted.
  • The forward mapping works, the return mapping does not. Offer URL macros belong to the tracker; postback macros belong to the network. The direction changed, so the template engine changed too.
  • Only registration is visible. Deposit may use a separate URL field or a raw status that was never mapped.
  • Every retry adds revenue. Add a stable transaction ID and verify idempotency with the exact same callback twice.
  • Sensitive data is stored in sub IDs. Do not pass email, phone, name or another direct identifier in query parameters. URLs are routinely stored in access logs and partner dashboards.

FAQ

Is subid the same as click_id?

Not by definition. click_id describes the role of a value: uniquely identify one click. subid describes a flexible storage field. A sub ID becomes the carrier of a click ID only when you deliberately put that click ID into it.

Must the names on both sides of = match?

No. click_id={subid} is valid when the receiver expects click_id and the sender stores your click value under subid. Matching the resolved value is what matters.

Can I use one postback URL for every conversion status?

Yes, if the network expands a status macro and your tracker maps every value you need. If the network provides separate callback fields per goal, configure each one explicitly.

Why did the postback return 200 but no conversion appeared?

Many endpoints intentionally acknowledge malformed, unknown or duplicate callbacks with a generic success response to prevent retry storms and information leakage. Check the raw ingress result, click lookup, status mapping and final conversion record.

The durable mental model

Stop memorizing macro spellings and trace ownership instead:

  1. Who creates the click value?
  2. Under which key does the next system receive and store it?
  3. Which macro does that system use to return the stored value?
  4. Which incoming key does the tracker accept?
  5. Which transaction ID prevents a retry from becoming extra revenue?

Once those five answers are written down, different tracker syntaxes stop being mysterious. They are simply adapters around one invariant: the same click identifier must survive the entire round trip unchanged.

  • postback url parameters
  • postback macros
  • click id tracking
  • sub id tracking
  • affiliate tracking