Skip to content
Browse documentation

Server-to-server postback reference

Every parameter, response body and HTTP status of the /pb conversion endpoint, with working examples.

Last updated 6 min read

On this page

The server-to-server (S2S) postback is the most reliable way to report a conversion: the advertiser's server calls TrackCrown directly, so no browser, cookie or ad blocker is involved.

URL
https://trackcrown.com/pb?click_id=0192f3c1a2b4e1f0c9d84b2a7e6f5d3c&event=sale&amount=49.90&txid=ORDER-1001&token=YOUR_TOKEN

Endpoint#

ItemValue
Paths/pb, /postback, /conversion (identical)
HostAny active tracking domain of the offer's workspace (or a shared domain of the same brand)
MethodsGET and POST. HEAD and others → 405 with Allow: GET, POST.
POST bodiesapplication/x-www-form-urlencoded, multipart/form-data, application/json (a flat object of strings, numbers or booleans) or text/plain starting with { (read as JSON). Max 64 KiB.
Parameter namesCase-insensitive. Body values win over query values; the first non-empty value of a repeated name is used.

Where to find the URL#

  1. Open the offer → Tracking tab → Advertiser conversion tracking.
  2. Choose the Event, tick Sale amount and Order ID (dedupe) if the advertiser can send them.
  3. Copy Server-to-server postback URL. It contains {click_id}, {amount} and {order_id} placeholders for the advertiser's platform to fill, and the right token: the advertiser's token when the offer has an advertiser, otherwise the workspace token. Only managers and above see the token.

Tokens live under Settings → Postback tokens. Regenerating a token stops every integration that uses the old one immediately (401).

Parameters#

Identification#

ParameterAliasesDescription
token—Required. Workspace postback token or the offer's advertiser postback token. The token of a Paused or Inactive advertiser is refused (401 advertiser_inactive); the workspace token keeps working.
click_idtransaction_id, tidThe 32-hex click ID passed to the advertiser. Case-insensitive. Another tracker's ID (letters, digits, . _ : -, up to 128 characters) is accepted only for the migration postback; anything else (for example an unexpanded {click_id}) is 400.
gclid—Join by Google click ID: the newest click of the workspace with this value. Max 1,024 characters.
gbraid, wbraid—Google iOS click IDs, joined like gclid (used only when gclid is absent).
msclkid—Microsoft Ads click ID, joined like gclid.
conversion_id—UUID of an existing conversion to update (reversal / status update).
first_click_id—First click of the visit (sent by the SDK; used for first-touch attribution).
default_offer—Offer id or code used only when the click carries no offer (a /c/<workspace> click); ignored for offer-linked clicks. Sent by the SDK from data-offer.
offer_idofferOffer ID or code. Required when there is no click; must match the click's offer when sent with one.
aff_idaffiliate_id, affPartner ID or code for a click-less conversion, or for a click that has no partner (workspace-level link). Ignored when the click has a partner.
coupon_codecouponCoupon code (max 64 characters) for click-less coupon attribution.
email—Buyer e-mail (max 320 characters) for e-mail ownership attribution and hashed macros. Never stored in clear: the conversion keeps email_sha256.

Conversion data#

ParameterAliasesDescription
event—Event code; empty or default = the offer's default event. Max 64 characters.
adv_event—Advertiser-level event code, mapped to the linked offer event when event is not sent.
amountsale_amountSale amount, used by percentage payouts/revenue (CPS / RPS) and dynamic revenue.
revenue—Overrides the calculated revenue (any valid token).
payout—Overrides the calculated payout — only with the workspace token; ignored with an advertiser token.
txidadv_txid, order_idThe advertiser's order or transaction ID (max 255). Used for de-duplication and reversals.
status—approved, pending or rejected. Also accepted: approve, 1 → approved; reject, declined, 0 → rejected. Default: the offer's default status.
currency—ISO 4217 code of the amounts (EUR). Converted to the offer currency at the ECB daily rate when one is available.
adv1 … adv5—Free values stored on the conversion and available as postback macros and rule fields.
any other name—Stored in the conversion's parameters (up to 50, names ≤ 64 characters, values ≤ 512 bytes) and testable in postback rules as param:<name>. The names flags, fraud and reject_reason are written by TrackCrown itself and ignored when sent.
test—1, true or yes: validate and return the result without storing anything.

Money format: a plain decimal with . as decimal separator, rounded to 4 decimals. Comma thousands separators (1,234.50) are accepted; a decimal comma (49,90), a negative value or a value above 9,999,999,999.9999 is 400.

Responses#

Every answer is JSON (Content-Type: application/json; charset=utf-8, Cache-Control: no-store).

New conversion:

JSON
{"ok":true,"conversion_id":"5f0c2a8e-1d3b-4c6e-9f7a-2b8d4e6f1a3c","status":"approved"}

Stored but not payable (the reason explains why):

JSON
{"ok":true,"conversion_id":"7a1d…","status":"rejected","reason":"outside_window"}

Duplicate (stored as a rejected row, no postbacks):

JSON
{"ok":true,"conversion_id":"9c2e…","status":"rejected","reason":"duplicate","duplicate":true}

Existing conversion changed by a reversal or status update:

JSON
{"ok":true,"conversion_id":"5f0c…","status":"rejected","reason":"postback_reversal","updated":true}

Business error (nothing stored):

JSON
{"ok":false,"error":"unknown click_id"}

HTTP status codes#

HTTPWhenExamples of error
200Stored, updated, duplicate, test, or a business error. Advertiser systems retry anything else, so business errors use 200.unknown click_id, no click found for gclid, unknown offer_id, offer_id does not match the click, offer does not accept server-to-server conversions, unknown conversion_id, unknown coupon_code
400Malformed request.invalid click_id (expected 32 hex characters), invalid amount (plain decimal expected), invalid status "x" (approved|pending|rejected), invalid currency (ISO 4217 code expected), unknown event "x" for this offer, malformed JSON body: …
401Token problem.token required, invalid token, token not valid for this offer, advertiser_inactive (the advertiser is paused or inactive)
403A conversion_id update or migration forward from an IP outside the advertiser's allowlist.postback IP not allowed for this offer
405Method other than GET or POST.method not allowed
413Body larger than 64 KiB.request body too large
503A dependency is briefly unavailable, or the click may still be in the write queue. Sent with Retry-After: 30; retry.click lookup unavailable, retry later, temporarily unavailable, retry later

The full list is in Error and reason codes.

Test mode#

Add test=1 to see what would happen. Nothing is stored and no cap counter moves:

Shell
curl -s "https://trackcrown.com/pb?click_id=0192f3c1a2b4e1f0c9d84b2a7e6f5d3c&event=sale&amount=49.90&token=YOUR_TOKEN&test=1"
JSON
{"ok":true,"status":"approved","test":true,"details":{"click_id":"0192f3c1a2b4e1f0c9d84b2a7e6f5d3c",
 "click_ts":"2026-10-12T09:14:03.512Z","offer_id":12,"offer_code":"SHOP01","affiliate_id":7,"event":"sale",
 "event_name":"Sale","revenue":"10.00","payout":"6.00","sale_amount":"49.90","currency":"USD",
 "payout_source":"offer","revenue_source":"offer","caps_checked":true,"token":"workspace",
 "postbacks":[{"postback_id":31,"affiliate_id":7,"kind":"s2s","method":"GET","url":"https://tracker.example/pb?cid=abc&payout=6.00"}]}}

payout, payout_source and postbacks are shown only to the workspace token. *_source names the level that set the amount: override_event, override_offer, event, offer, param, amount or dynamic_none.

Examples#

POST with a JSON body:

Shell
curl -s https://trackcrown.com/pb -H 'Content-Type: application/json' \
  -d '{"click_id":"0192f3c1a2b4e1f0c9d84b2a7e6f5d3c","event":"sale","amount":"49.90","txid":"ORDER-1001","token":"YOUR_TOKEN"}'

Click-less conversion for a partner (for example a phone order):

Shell
curl -s "https://trackcrown.com/pb?offer_id=SHOP01&aff_id=partner7&amount=120&txid=PHONE-88&token=YOUR_TOKEN"

Google Ads parallel tracking, where the advertiser only has the gclid:

Shell
curl -s "https://trackcrown.com/pb?gclid=EAIaIQobChMI8x&offer_id=SHOP01&amount=49.90&token=YOUR_TOKEN"

Cancellation of an earlier order (see Reversals):

Shell
curl -s "https://trackcrown.com/pb?txid=ORDER-1001&offer_id=SHOP01&status=rejected&token=YOUR_TOKEN"

Every request — including refused ones — appears in the inbound postback log.

Something unclear or missing in this article?Tell us