Postbacks
Inbound server-to-server postbacks and the JSON conversions API, matching and idempotency rules, and outbound postback templates to partners.
Updated 2026-09-02
Inbound postback#
Fire a request from your server (never the browser — it carries the API key) when a conversion happens.
GET https://app.whichclick.is/postback?api_key=wc_live_…&click_id={wc_click_id}&event=purchase&value=49.90¤cy=USD&order_id=ORD-1001POST with the same query parameters is accepted. The JSON form is POST /api/v1/conversions with a bearer token:
curl -X POST https://app.whichclick.is/api/v1/conversions \
-H "Authorization: Bearer wc_live_…" -H "Content-Type: application/json" \
-d '{"click_id":"k3Zp9Qw1mR7tXc2b","event":"purchase","value":49.9,"currency":"USD","order_id":"ORD-1001"}'
# 201 {"ok":true,"id":"clx…","matched":true}| Parameter | Required | Notes |
|---|---|---|
click_id | one of click_id / gclid | wc_click_id from the landing page |
gclid | Falls back to the most recent click with this gclid in your organization | |
event | no (default conversion) | Any name ≤ 64 chars: lead, purchase, signup |
value | no | ≥ 0 |
currency | no | ISO 4217, upper-cased; default USD |
order_id | recommended | Idempotency key together with event |
Matching and idempotency#
- The conversion is upserted on (
organization,order_id,event). Repeats updatevalue/currencyand return the same id, so retries are safe. - Without
order_ida synthetic key from the click id and timestamp is used and every call creates a new conversion. matched: falsemeans no click was found; the conversion is still stored (unattributed) and counted in reports.- The matched click's campaign and link are copied onto the conversion for reporting and ROAS.
Capturing the click id on the web#
whichclick.js stores wc_click_id from the landing-page URL for 7 days (first-party storage) and exposes it as window.whichclick.clickId. Pass it to your backend with the order, then postback from there. Alternatively use gclid, which Google appends via the final URL suffix.
Outbound postbacks#
Under Postbacks define endpoints that WhichClick calls whenever a conversion is recorded. Templates support these macros:
| Macro | Value |
|---|---|
{click_id} | Matched click id (empty if unattributed) |
{gclid} | gclid from the conversion or click |
{event} | Event name |
{value}, {currency} | As recorded |
{order_id} | Your order id |
{campaign_id}, {campaign_external_id} | Campaign ids |
{ts} | Unix seconds |
https://partner.example/pb?cid={click_id}&ev={event}&amt={value}&cur={currency}&oid={order_id}Deliveries are logged with status code and latency (Postbacks → Deliveries) and retried three times on 5xx / timeouts. Mobile installs and in-app events additionally flow to SAN partners (Meta CAPI, TikTok Events, Snap CAPI, Apple Search Ads) and to 60+ network templates configured under Partners.
Offline conversion import to Google Ads#
Export clicks with GET /api/v1/clicks?since=… (or MCP list_clicks), join your CRM outcomes on wc_click_id, and upload gclid + conversion time + value through Google Ads offline conversions. The click record keeps gclid, gbraid and wbraid for this purpose.