Skip to content

Thrad Server-Side Conversion Quickstart (Advertiser)

This guide is for advertisers who want server‑side conversion tracking (no browser pixel).

Overview

  1. User clicks a Thrad ad.
  2. We redirect to your landing page with click parameters.
  3. You store the parameters (cookie + database + payment metadata).
  4. On payment success, your backend calls Thrad’s conversion API.

Click Parameters (from the landing URL)

We append the following to your landing page URL:

  • thrad_click_id (string)
  • thrad_exp (unix seconds)
  • thrad_sig (HMAC signature)
  • thrad_bid_id (string, optional but useful)

Example landing URL:

https://www.imagerestoreai.com/?thrad_click_id=...&thrad_exp=...&thrad_sig=...&thrad_bid_id=...

Store these values when the user lands (cookie + database), and pass them through your payment flow (e.g., Stripe metadata).

One‑paste landing script

Paste this once on your landing site. It captures Thrad click params and stores them in cookie + localStorage.

<script>
  (function () {
    var params = new URLSearchParams(window.location.search);
    var clickId = params.get("thrad_click_id");
    var exp = params.get("thrad_exp");
    var sig = params.get("thrad_sig");
    var bidId = params.get("thrad_bid_id");
    if (!clickId || !exp || !sig) {
      return;
    }
    var maxAge = 90 * 24 * 60 * 60;
    var cookieParts = [
      "Path=/",
      "Max-Age=" + maxAge,
      "SameSite=Lax",
    ];
    if (location.protocol === "https:") {
      cookieParts.push("Secure");
    }
    document.cookie =
      "thrad_click_id=" + encodeURIComponent(clickId) + ";" + cookieParts.join("; ");
    document.cookie =
      "thrad_exp=" + encodeURIComponent(exp) + ";" + cookieParts.join("; ");
    document.cookie =
      "thrad_sig=" + encodeURIComponent(sig) + ";" + cookieParts.join("; ");
    if (bidId) {
      document.cookie =
        "thrad_bid_id=" + encodeURIComponent(bidId) + ";" + cookieParts.join("; ");
    }
    try {
      localStorage.setItem("thrad_click_id", clickId);
      localStorage.setItem("thrad_exp", exp);
      localStorage.setItem("thrad_sig", sig);
      if (bidId) {
        localStorage.setItem("thrad_bid_id", bidId);
      }
    } catch (e) {
      // ignore storage failures
    }
  })();
</script>

Conversion API

Endpoint
POST /v1/conversion

This guide uses the signed click-token flow (click_id + exp + sig). For Bearer-authenticated partner S2S integrations, use: - POST /v1/api/collect (general server events) - POST /v1/api/conversion (server conversions)

Content-Type
application/json

Required fields

  • click_id (from thrad_click_id)
  • exp (from thrad_exp)
  • sig (from thrad_sig)
  • order_id (your transaction id, e.g. Stripe PaymentIntent id)
  • event_ts (unix seconds, UTC)

Optional fields

  • event_name (e.g. purchase_completed)
  • value (number)
  • currency (ISO 4217)
  • page_url, referrer, user_agent
  • channel, session_id
  • bid_id (from thrad_bid_id)

Example payload

{
  "click_id": "abc123",
  "exp": 1772809451,
  "sig": "b940315e...",
  "order_id": "pi_3SLYwiE6uXqAK89I1Hr89px9",
  "event_ts": 1770215430,
  "event_name": "purchase_completed",
  "value": 2.99,
  "currency": "USD",
  "bid_id": "3f4a8d5b-3b2f-4e3b-9a9e-0b0d5d6b8c3a"
}

Response

{ "status": "ok" }

Duplicates are ignored when we see the same order_id (or event_id) for the same click.

Minimal Stripe Webhook Flow (Server‑Side)

  1. Save thrad_click_id, thrad_exp, thrad_sig (and thrad_bid_id) when the user lands.
  2. Store the values in Stripe PaymentIntent metadata.
  3. On payment_intent.succeeded, read metadata and POST to /v1/conversion.

Notes

  • No browser SDK required.
  • If you don’t have a click id (organic traffic), skip the API call.
  • Default API rate limit is modest (300 req/min). Tell us if you need more.