Home/Docs/Webhooks
Docs

Webhooks

Get push notifications when conversions, partner applications, or fraud signals fire — without polling the API.

What webhooks are for

Trcker webhooks deliver real-time events to a URL you control. Use them when you want to:

  • Pipe conversions into your CRM, data warehouse, or notification system as they happen.
  • Trigger email/Slack flows on partner application, approval, or rejection.
  • React to fraud signals (high-risk score, datacenter IP, IPsum hit) by pausing the partner or notifying ops.

Webhooks are a complement to postback URLs. Postbacks fire from the advertiser to Trcker on conversion. Webhooks fire from Trcker to your URL on a wider range of events.

Available events

| Event | When it fires | |---|---| | conversion.created | A new conversion lands (status may be pending or approved depending on offer config) | | conversion.approved | A pending conversion is approved (manual or auto via hold-time) | | conversion.rejected | A pending conversion is rejected | | partner.applied | Someone submits the public application form | | partner.approved | A partner moves to active | | partner.banned | A partner is banned (manual or by automation rule) | | fraud.high_risk | A click's fraud score exceeds the brand's threshold | | cap.reached | An offer's daily / weekly / monthly / global cap fires |

The full list (with payload schemas) lives in the API reference under /api/public/webhook-events.

Subscribing

Webhooks are configured per-brand under Settings → Webhooks (coming Q3 2026). Until that ships, subscribe via the public API:

`bash curl -X POST https://trcker.io/api/public/webhooks \ -H "Authorization: Bearer tk_your_key" \ -H "Content-Type: application/json" \ -d '{ "url": "https://yourapp.com/trcker-events", "events": ["conversion.created", "conversion.approved", "fraud.high_risk"], "secret": "your_signing_secret_here" }' `

The secret field is optional but recommended — Trcker uses it to sign every payload so you can verify the request came from us.

Payload format

Every webhook delivery is a POST with Content-Type: application/json:

`json { "id": "evt_2a4f8c1b9e7d3f2a", "event": "conversion.created", "createdAt": "2026-05-08T04:51:35.080Z", "brandId": "b29e7d3f-…", "data": { "conversionId": "c4f8c1b9-…", "partnerId": "p2a4f8c1-…", "offerId": "o9e7d3f2-…", "revenueCents": 4200, "payoutCents": 1260, "currency": "USD", "status": "pending", "sub1": "winter-promo", "externalTxnId": "shopify-order-12345" } } `

Verifying signatures

If you set a secret when subscribing, every delivery includes:

  • X-Trcker-Signature: t=,v1=
  • X-Trcker-Event: conversion.created
  • X-Trcker-Webhook-Id: wh_… (so you can dedupe)

Verify in your handler:

`typescript import crypto from "node:crypto";

function verifyTrckerWebhook( body: string, signatureHeader: string, secret: string, ): boolean { const parts = Object.fromEntries( signatureHeader.split(",").map((p) => p.split("=")), ); const expected = crypto .createHmac("sha256", secret) .update(${parts.t}.${body}) .digest("hex"); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(parts.v1 ?? ""), ); } `

Reject any request where the timestamp is more than 5 minutes old (replay protection) or the signature doesn't match.

Retries

Trcker treats a 2xx response as success. Anything else (3xx-5xx, timeout, network error) triggers a retry with exponential backoff: 1s, 5s, 30s, 5min, 30min, 2hr. After 6 attempts a delivery is marked failed and shows up in the Activity → Delivery log.

Aim for an idempotent handler. We resend the same evt_… ID on retry, so deduplicating on event ID is straightforward.

Common questions

Can I subscribe to events from multiple brands with one URL? Yes. Subscribe with each brand's API key separately. The payload includes brandId so you can route in your handler.

What if my endpoint is slow? We time out after 10 seconds. Best practice: respond 2xx immediately, queue the work in your own job system, process async. Don't hold the connection open while you do real work.

How do I test without setting up an endpoint? Use webhook.site — it gives you a one-time URL that displays incoming requests. Subscribe with that URL, fire a test event from the dashboard, watch the payload land.

Can I see what was delivered? Yes — Activity → Delivery log shows every webhook send (and postback send), including status, latency, and the response body the receiver returned. Filter to "webhook" type to see only webhook deliveries.