Traqio.

SDK

SDK serveur Python

Signalez inscriptions et achats depuis un backend Python avec le paquet traqio, et rattachez chacun à son clic publicitaire. Django, Flask, FastAPI.

traqio est le SDK Traqio pour les backends Python — la moitié serveur du SDK web de Traqio. La conversion qui compte sur un site — une inscription, un abonnement, un achat — a lieu sur votre backend, là où l’id utilisateur est connu. Ce paquet la signale avec le trackID, le click id de la publicité que @traqio/web a gardé en stockage first-party depuis la page d’arrivée, et Traqio crédite la campagne qui a amené l’utilisateur — de façon déterministe, par l’id de ce clic. Bibliothèque standard uniquement ; Django, Flask, FastAPI ou tout autre framework.

Pas encore sur PyPI — accès anticipé

Paquet traqio · version 0.1.0Les paquets du SDK ne sont pas encore sur leurs registres publics. Pour intégrer dès aujourd’hui, demandez le build : hello@traqio.appNiveau de preuve : Testé unitairement, et exécuté de bout en bout contre une API Traqio en fonctionnement : inscription avec un trackID → attribuée.

Prérequis#

  • Python 3.9 ou plus. Aucune dépendance ; typé (py.typed).
  • Une clé serveur pour le produit (tq_sk_…). Ni la clé SDK de l’app ni une clé web ne fonctionnent ici.
  • @traqio/web sur le site, et des publicités qui pointent vers des liens de tracking avec une destination site web — c’est ainsi que le trackID arrive jusqu’à votre formulaire d’inscription.

Mise en place#

  1. Créer une clé serveur#

    Dans la console, ouvrez Intégrations → SDK et créez une clé serveur. Elle n’est affichée qu’une fois : placez-la dans l’environnement du backend, jamais dans le code ni dans une page. Traqio n’en garde qu’une empreinte ; une clé perdue est remplacée par une nouvelle, et l’ancienne révoquée.

    .env
    TRAQIO_SECRET_KEY=tq_sk_...
  2. Installer le paquet#

    pip install traqio

    Tant que le paquet n’est pas sur PyPI, installez le wheel que nous vous envoyons :

    # the file you received, committed inside the backend's repository
    pip install ./vendor/traqio-0.1.0-py3-none-any.whl
  3. Créer le client#

    import os
    from traqio import Traqio
    
    # One client per process. The key comes from the server's environment, never from code.
    traqio = Traqio(os.environ["TRAQIO_SECRET_KEY"])

    Le client ne garde aucune connexion ouverte : un par processus suffit. Il refuse une clé web (tq_web_…).

  4. Signaler l’inscription avec son trackID#

    Appelez signup() une fois, là où le compte est créé. @traqio/web écrit le trackID dans le cookie traq_click sur votre propre domaine : le navigateur l’envoie donc avec la requête d’inscription.

    from traqio import TraqioError, track_id_from_request
    
    def signup(request):
        user = User.objects.create_user(...)
        try:
            traqio.signup(str(user.pk), track_id_from_request(request))
        except TraqioError as error:
            logger.warning("traqio: %s", error)  # never fail the sign-up itself
        return redirect("/welcome")

    Si le backend est sur un autre domaine que le site, le cookie ne lui parvient pas : envoyez plutôt Traqio.getTrackId() depuis le navigateur avec le formulaire. L’inscription est le moment où l’utilisateur est acquis ; le dernier clic qui la précède, dans votre fenêtre d’attribution, reçoit le crédit.

  5. Suivre les conversions#

    traqio.track(
        str(user.pk),
        "purchase",
        value=49,
        currency="EUR",
        transaction_id=payment_intent.id,  # one payment, one row — whoever reports it
        store="stripe",
    )

    Les conversions suivent l’utilisateur : elles sont créditées à la campagne qui l’a acquis.

Ce que dit la réponse#

result = traqio.signup(str(user.pk), track_id)

result.track_id                 # "matched" | "unknown" | "expired" | "claimed" | "refused" | None
result.acquired                 # True: the sign-up is recorded
result.attribution.network      # "meta", "tiktok"… or "organic"
result.attribution.campaign_id  # the campaign that brought the user
track_idSignification
matchedLe clic appartient désormais à cet utilisateur. Une nouvelle tentative répond de nouveau matched.
unknownAucun clic de ce produit n’a cet id — une faute de frappe, le lien d’un autre produit, ou une valeur que @traqio/web n’a pas écrite.
expiredLe clic est plus ancien que la fenêtre d’attribution du produit.
claimedUn autre utilisateur, ou une installation d’app, possède déjà ce clic. Un clic crédite une seule identité.
refusedLe clic a échoué à une règle anti-fraude (il est passé par un réseau d’anonymisation). Il est compté, jamais crédité.

Ce qu’il fait aujourd’hui, et ce qu’il ne fait pas#

Aujourd’hui
Rattacher une inscription à son clic, et dire qui a été créditéOui — dans la réponse
Enregistrer les achats avec valeur, devise et id de paiement, dédoublonnésOui
Laisser intacts les installations, revenus et ROAS de vos appsOui — jamais rattachés à une installation d’app
Afficher les conversions web dans les rapports de la consoleOui — par campagne, à côté des installations
Envoyer les conversions web à Meta ou TikTokPas encore

Les conversions envoyées ici apparaissent dans Événements en direct, marquées comme non rapprochées d’une installation — c’est normal pour un site web. Une inscription créditée à une campagne est comptée dans le rapport ROAS comme une conversion web de cette campagne, à côté de ses installations, et la réponse de chaque appel vous donne l’attribution tout de suite.

Erreurs et nouvelles tentatives#

Une erreur réseau, un timeout, un 429 ou un 5xx est retenté — deux fois par défaut, avec le même corps, donc rien n’est compté deux fois. Un 4xx (clé erronée ou révoquée, payload invalide) n’est pas retenté. Les deux se terminent par une TraqioError :

from traqio import TraqioError

try:
    traqio.signup(str(user.pk), track_id)
except TraqioError as error:
    # error.status: 401 = wrong or revoked key, 400 = invalid payload, None = network
    logger.warning("traqio: %s (status %s)", error, error.status)

Signalez après votre propre écriture

Appelez Traqio une fois le compte ou le paiement enregistré, et ne laissez jamais une erreur Traqio le faire échouer.

Référence de l’API#

Traqio(…)
Traqio(
    secret_key,            # the server key, tq_sk_… — required
    endpoint="https://api.traqio.app",
    timeout=10.0,          # seconds per attempt
    max_retries=2,         # after a network error, a 429 or a 5xx
    transport=None,        # a custom transport (proxies, tests)
)
MéthodeCe qu’elle fait
signup(user_id, track_id=None, events=())Signale l’inscription — l’acquisition — avec son trackID. La première est conservée.
track(user_id, name, *, value, currency, transaction_id, store, event_id, track_id)Enregistre une conversion d’un utilisateur connu.
send(user_id, *, track_id, signup, events)L’appel brut derrière les deux, pour plusieurs événements à la fois.
track_id_from_request(request)Le trackID tiré d’une requête Django, Flask ou Starlette, ou None.
track_id_from_cookie_header(header)La même chose, depuis un en-tête Cookie brut.

Niveau de preuve

Testé sur Python 3.9 et 3.11, transport HTTP réel compris, et exécuté de bout en bout contre une API Traqio en fonctionnement : une inscription portant un trackID est revenue matched avec sa campagne, un clic inconnu a reçu unknown, une clé erronée a été refusée. Pas encore exécuté dans le backend de production d’un client.

Questions fréquentes#

Existe-t-il un client asynchrone ?
Pas aujourd’hui : le client est synchrone et n’utilise que la bibliothèque standard. Dans FastAPI ou Starlette, confiez l’appel à une tâche d’arrière-plan, qui l’exécute dans un thread après la réponse — la page montre comment.
Quels frameworks peuvent lire le trackID ?
track_id_from_request lit les requêtes Django (l’en-tête Cookie), Flask et Starlette / FastAPI (leurs cookies), et tout objet doté d’un mapping headers. Il renvoie None quand le visiteur ne vient pas d’une publicité.
Et si le visiteur ne vient pas d’une publicité ?
Passez None. L’inscription est quand même enregistrée, et l’utilisateur est organique : aucune campagne n’est créditée.
Une nouvelle tentative compte-t-elle un achat deux fois ?
Non. Chaque appel génère ses ids d’événement une seule fois et renvoie exactement le même corps, et un achat est aussi identifié par son transaction_id : le même paiement signalé deux fois est stocké une fois.

Mis à jour le 16 octobre 2026