Trackily Docs

Postback URLs

Le postback, c'est l'endpoint universel par lequel les ad networks et les advertisers affiliate signalent une conversion à Trackily. Server-to-server, un simple GET HTTP, format Keitaro-compatible (avec aliasing flexible des paramètres). C'est ce qui transforme un click en conversion attribuée.

Concept

Quand un utilisateur clique sur ton lien de tracking Trackily (/c/<slug>?click_id=xxx), tu lui attribues un identifiant unique (click_id). Ce click_id est forwardé à l'advertiser via les params de l'URL de redirect (typically ?subid=xxx ou ?aff_sub=xxx).

Quand l'utilisateur convertit (achat, lead, signup), l'advertiser/réseau pingue ton postback :

GET https://trackily.online/postback?subid=xxx&payout=4.50&status=approved&tid=42

Trackily récupère le click correspondant via subid, crée la conversion, attribue le revenue à la campagne / source / landing / offer du click original.

URL nominale

https://trackily.online/postback?cid={clickid}&payout={payout}&status={status}&tid={tid}

Mais en pratique, n'importe lequel des aliases connus est accepté pour chaque param (Keitaro-style aliasing).

Aliases par défaut

Trackily accepte plusieurs noms de query string pour chaque paramètre — utile car chaque réseau utilise sa propre convention.

subid (le click_id Trackily)

Aliases (ordre = priorité de lookup) :

subid, sub_id, click_id, clickid, trackID, subaccount,
aff_sub, aff_click_id, SubID, trackingCodes, sub1, sub2

status (approuvé / rejeté / en attente)

status, type

Valeurs typiques : approved, pending, rejected, chargeback. Trackily les résout via la table conversion_types (configurable côté Settings → Conversion types).

payout (le revenu)

payout, revenue, profit, summ_approved, payment, amount,
payout_amount, order_sum, order_amount, affiliateCommission, value

Toujours converti en parseFloat(). Le réseau envoie typiquement en USD ; si tu utilises une autre devise, configure-la côté offer.

tid (transaction id de l'advertiser)

tid, transaction_id, txid, trans_id, receipt

Optionnel mais recommandé — sert de dédup côté Trackily si le réseau retry le postback.

date (timestamp de la conversion)

date, conversion_time, action_time, postback_date, time

Optionnel. Si absent, Trackily utilise NOW(). Le format est libre — Trackily tente plusieurs parsers (ISO 8601, epoch seconds, epoch ms).

Customizer les aliases

Tu peux étendre les aliases par défaut pour matcher un nouveau réseau :

PUT /admin/api/postback-aliases HTTP/1.1
Content-Type: application/json

{
  "subid": ["subid", "click_id", "my_custom_param"],
  "payout": ["payout", "revenue", "ma_commission"]
}

L'admin UI a une page dédiée (Settings → Postback → Aliases) pour ça.

Sécurité — HMAC signature

Par défaut, le postback est non signé — n'importe qui peut générer un ?subid=<random uuid v4>&payout=10000 et créer une conversion fantôme (si jamais ils tombent sur un click_id qui existe, ce qui est astronomiquement improbable mais possible si tes click_ids fuitent dans les referer logs).

Pour activer la signature HMAC, configure postback_secret dans Settings :

INSERT INTO settings (key, value) VALUES ('postback_secret', '"<random 32 chars>"');

Une fois le secret défini, toutes les calls à /postback doivent inclure ?sig=<hmac> :

sig = HMAC-SHA256(secret, subid + "|" + status + "|" + payout + "|" + tid)

en hex. Trackily vérifie la signature constant-time et rejette 401 Unauthorized si invalide.

Configure le réseau pour ajouter le sig à son template d'URL. Si le réseau ne supporte pas HMAC, tu peux toujours protéger via :

  • IP whitelisting (côté nginx / Cloudflare)
  • VPN entre toi et le réseau (rare mais existe)
  • Le simple fait que les click_ids sont des UUID v4 (entropie suffisante pour les rendre non-guessables en pratique)

Format de réponse

/postback retourne toujours 200 OK avec le body "OK". Volontairement laconique — les réseaux retry sur tout ce qui n'est pas 200, et beaucoup retry "intelligently" sur du JSON inattendu.

Si tu veux logger le détail du processing, regarde les server logs :

[Postback] Received: { subid: 'abc-123', status: 'approved', payout: '4.50', tid: '42' }
[Postback] Resolved → subid=abc-123 status=approved payout=4.5 tid=42 type=sale postback=none
[Postback] Conversion recorded for click 1247 | Payout: 4.5 | Status: approved | Type: sale | InConv: true | InRev: true

Ou la table logs (Sidebar → Logs → filter by category postback).

Conversion types

Le status du postback est mappé vers un conversion type via db.resolveConversionType(). Les types sont configurables (Settings → Conversion types) :

Type Slug Include in conversions Include in revenue Send postback to source
Sale sale OK OK optionnel
Lead lead OK OK optionnel
Trial trial OK optionnel
Install install OK OK optionnel
Reject reject aucun
Chargeback chargeback OK (negative) OK (negative) aucun

Le type affecte 3 comportements :

  • include_in_conversions : est-ce que c'est compté dans les stats "Conversions" globales ?
  • include_in_revenue : est-ce que payout s'ajoute au revenue de la campagne ?
  • send_postback : est-ce qu'on forward le postback vers la source de trafic (pour faire fire son pixel) ?

Forward vers la source

Si la traffic source a une URL postback configurée (traffic_sources.postback_url), Trackily peut forward le postback vers l'ad network pour fire son pixel de conversion. Utile pour optimiser Meta / TikTok / Kadam algos qui apprennent des conversions.

Template macros disponibles :

  • {click_id} — Trackily click_id
  • {payout} — montant
  • {external_id} — id externe de la campagne côté source
  • {status} — status résolu

Exemple Kadam :

https://api.kadam.net/conversion?cid={external_id}&subid={click_id}&revenue={payout}

Le forward est best-effort, fire-and-forget (n'affecte pas le retour de /postback au réseau).

Trigger email enrollment

À chaque postback réussi, Trackily check les email_conversion_triggers actifs pour l'offer_id matché. Si trouvé et que l'email du buyer est résolu (via ?email= query, ou leads.email joint par click_id), enrolle le buyer dans target_list_id. Cf. Email — Automations.

Exemple complet

Côté Trackily, génération de l'URL de tracking

Quand tu setup une campagne, Trackily te fournit l'URL de redirect vers l'advertiser :

https://advertiser-network.com/click?offer=42&aff_sub={click_id}

Le {click_id} est remplacé par Trackily au moment du click avec un UUID v4 généré.

Côté ad network, postback configuré

L'ad network est configuré pour ping ton postback au moment de la conversion :

https://trackily.online/postback?aff_sub={subid}&status={status}&payout={revenue}&tid={transaction_id}

(Les {...} ici sont les macros DU RÉSEAU, pas de Trackily.)

Flux complet

  1. Visiteur clique https://yoursite.com/c/sweepstakes-fr → click_id abc-123 généré.
  2. Trackily redirige vers https://advertiser-network.com/click?offer=42&aff_sub=abc-123.
  3. Visiteur convertit côté advertiser.
  4. Advertiser ping https://trackily.online/postback?aff_sub=abc-123&status=approved&payout=4.50&tid=ord-987.
  5. Trackily :
    • Match aff_sub=abc-123 contre la clicks row → trouvé.
    • Crée conversion : revenue=4.50, status=approved, type=sale.
    • Forward (si configuré) vers Meta/TikTok pour fire le pixel d'algo.
    • Check email conversion triggers → si un trigger matche offer_id=42, enroll le buyer dans la liste cible.
  6. Stats de la campagne mises à jour en temps réel (revenue +4.50, conversions +1).

Erreurs courantes

  • /postback retourne 200 mais aucune conversion enregistrée — souvent un click_id non matched. Vérifie via list_clicks que l'UUID dans aff_sub existe. Si non : check les macros de redirect, peut-être que {click_id} n'est pas remplacé.
  • 401 Unauthorized — tu as activé postback_secret mais l'ad network n'envoie pas sig=. Soit configure le sig côté réseau, soit retire le secret (puis sécurise par IP whitelist).
  • Multiple conversions sur un même tid — Trackily ne dédup PAS par défaut (tid est optionnel). Si tu en as besoin, ajoute un unique index sur conversions(transaction_id).
  • Payout en mauvaise devise — Trackily prend payout en literal float. Si ton réseau envoie en cents (Stripe-style), divise par 100 côté réseau ou ajoute un custom alias.
  • Stats Meta Ads "Purchase" event ne fire pas — vérifie que send_postback est setté sur le conversion type ET que la traffic source a une postback_url Meta configurée.

Voir aussi