Conversions & postbacks
Server-to-server conversions, pixels, statuses, de-duplication and outgoing partner postbacks.
4 min read
Browse documentation
A conversion is an action — a lead, a sale, an install — reported to ArcTrack by the advertiser. ArcTrack attributes it to the original click, calculates revenue and payout, removes duplicates and notifies the partner.
Server-to-server (S2S) postback#
https://track.example.com/pb? click_id=CLICK_ID &event=sale &amount=49.90 &txid=ORDER-1001 &token=TOKENGET or POST (form or query parameters). Aliases: /postback, /conversion.
Response (HTTP 200):
{"ok":true,"conversion_id":"5f0c…","status":"approved"}Errors return {"ok":false,"error":"…"} — with HTTP 200 for business errors (so advertiser systems do not retry
endlessly), 401 for a missing or wrong token and 400 for a malformed request.
Pixels#
When the advertiser cannot make server calls, place a pixel on the confirmation page. Pixels are accepted only when the offer's conversion method allows them.
<img src="https://track.example.com/px?offer_id=OFFERCODE&amount=49.90&txid=ORDER-1001" width="1" height="1" alt=""><script src="https://track.example.com/px.js?offer_id=OFFERCODE&amount=49.90&txid=ORDER-1001" async></script>The pixel takes the same parameters as the postback except token. The click ID is read from the click_id
parameter, or — only if the workspace enabled the pixel cookie — from a first-party cookie set on the tracking
domain at click time. The panel's offer page and the advertiser portal generate ready-to-paste snippets.
Browsers increasingly block cookies of other sites, so on a store or checkout domain the most reliable source of the
click ID is the landing-page SDK: it keeps the click ID in a first-party atk_cid cookie on the
store's own domain, and your thank-you page passes it on as click_id.
Shopify#
Shopify runs tracking code on checkout and thank-you pages only as a custom pixel (Settings → Customer events
→ Add custom pixel). Load the SDK in your theme (Online Store → Themes → Edit code → theme.liquid, before
</body>) so the click ID is stored on your store's domain, then add this custom pixel:
analytics.subscribe("checkout_completed", async (event) => {
const clickId = await browser.cookie.get("atk_cid");
if (!clickId) return; // not a tracked visit
const checkout = event.data.checkout;
const params = new URLSearchParams({
click_id: clickId,
offer_id: "OFFERCODE",
amount: String(checkout.totalPrice?.amount ?? ""),
currency: checkout.currencyCode ?? "",
txid: String(checkout.order?.id ?? checkout.token ?? ""),
});
fetch("https://track.example.com/px?" + params.toString(), { mode: "no-cors", keepalive: true });
});The order ID is sent as txid, so the same order is never counted twice even if the event fires again.
How a conversion is processed#
- Click lookup by click ID (or gclid).
- Attribution window — conversions later than the offer's window (1–365 days) are rejected as
outside_window. - Event — the event code selects the payout and revenue rules.
- Payout and revenue — most specific wins: partner + event override → partner override → event → offer.
Percentage types use
amount. - De-duplication — one conversion per click per event (unless the event allows multiples) and one per
advertiser transaction ID. Duplicates are stored as rejected with reason
duplicateand never fire postbacks. - Caps — over a conversion cap the conversion is rejected with reason
cap_exceeded. - Postbacks — matching partner postbacks are queued in the same transaction.
Statuses: approved, pending (awaiting your review) and rejected. Approving a pending conversion in the panel fires
the partner postbacks that have not fired yet.
Outgoing partner postbacks#
Partners — or you on their behalf — register URLs that are called for their conversions:
https://tracker.partner.example/postback? clickid={sub1} &payout={payout} &event={event} &tx={conversion_id}- Types: server-to-server URL, image pixel or HTML snippet.
- Method:
GET, orPOSTwith a body template (JSON-escaped when the body starts with{, otherwise form-escaped). - Scope: all offers or one offer; all events or one event. Private events never fire partner postbacks.
- Fire on: approved conversions (default) or any status.
- Delivery: 10-second timeout; a 2xx answer counts as delivered. Failures retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, then the postback is marked failed. Every attempt is visible in the postback log with the HTTP status and the start of the response.
See Macros for every placeholder.