SDK
SDK de servidor Python
Reporta registros y compras desde un backend Python con el paquete traqio y vincula cada uno a su clic en el anuncio. Django, Flask, FastAPI.
traqio es el SDK de Traqio para backends Python — la mitad servidor del SDK web de Traqio. La conversión que cuenta en un sitio web — un registro, una suscripción, una compra — ocurre en tu backend, donde se conoce el id de usuario. Este paquete la reporta con el trackID, el click id del anuncio que @traqio/web guardó en almacenamiento first-party desde la página de llegada, y Traqio acredita la campaña que trajo al usuario — de forma determinista, por el id de ese clic. Solo la biblioteca estándar; Django, Flask, FastAPI o cualquier otro framework.
Aún no está en PyPI — acceso anticipado
traqio · versión 0.1.0Los paquetes del SDK aún no están en sus registros públicos. Para integrarlo hoy, pide la build: hello@traqio.appNivel de prueba: Con pruebas unitarias y ejecutado de extremo a extremo contra una API de Traqio en marcha: registro con un trackID → atribuido.Requisitos#
- Python 3.9 o posterior. Sin dependencias; tipado (
py.typed). - Una clave de servidor para el producto (
tq_sk_…). Ni la clave SDK de la app ni una clave web funcionan aquí. - @traqio/web en el sitio, y anuncios que apunten a enlaces de seguimiento con un destino web — así es como el trackID llega a tu formulario de registro.
Configuración#
Crear una clave de servidor#
En la consola, abre Integraciones → SDK y crea una clave de servidor. Se muestra una sola vez: ponla en el entorno del backend, nunca en el código ni en una página. Traqio solo guarda su huella; una clave perdida se sustituye por una nueva y la antigua se revoca.
TRAQIO_SECRET_KEY=tq_sk_...Instalar el paquete#
pip install traqioMientras el paquete no esté en PyPI, instala el wheel que te enviamos:
# the file you received, committed inside the backend's repository pip install ./vendor/traqio-0.1.0-py3-none-any.whlCrear el cliente#
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"])El cliente no mantiene ninguna conexión: basta con uno por proceso. Rechaza una clave web (
tq_web_…).Reportar el registro con su trackID#
Llama a
signup()una vez, donde se crea la cuenta. @traqio/web escribe el trackID en la cookietraq_clickde tu propio dominio, así que el navegador lo envía con la petición de registro: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")from flask import request from traqio import track_id_from_request @app.post("/signup") def signup(): user = create_user(request.form) traqio.signup(str(user.id), track_id_from_request(request)) return redirect("/welcome")from fastapi import BackgroundTasks, Request from traqio import track_id_from_request @app.post("/signup") async def signup(request: Request, background: BackgroundTasks): user = await create_user(await request.json()) # The client is synchronous: a background task runs it in a thread, after the response. background.add_task(traqio.signup, str(user.id), track_id_from_request(request)) return {"id": user.id}Si el backend está en otro dominio que el sitio, la cookie no le llega: envía en su lugar
Traqio.getTrackId()desde el navegador con el formulario. El registro es el momento en que el usuario es captado; el último clic anterior, dentro de tu ventana de atribución, se lleva el crédito.Registrar las conversiones#
traqio.track( str(user.pk), "purchase", value=49, currency="EUR", transaction_id=payment_intent.id, # one payment, one row — whoever reports it store="stripe", )Las conversiones siguen al usuario: se acreditan a la campaña que lo captó.
Qué te dice la respuesta#
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_id | Significado |
|---|---|
matched | El clic pertenece ahora a este usuario. Un reintento vuelve a responder matched. |
unknown | Ningún clic de este producto tiene ese id — una errata, un enlace de otro producto o un valor que no escribió @traqio/web. |
expired | El clic es más antiguo que la ventana de atribución del producto. |
claimed | Otro usuario, o una instalación de app, ya tiene ese clic. Un clic acredita una sola identidad. |
refused | El clic no superó una regla antifraude (pasó por una red de anonimización). Se contabiliza, nunca se acredita. |
Qué hace hoy y qué no#
| Hoy | |
|---|---|
| Vincular un registro a su clic e indicar a quién se acreditó | Sí — en la respuesta |
| Registrar compras con valor, moneda e id de pago, sin duplicados | Sí |
| Dejar intactas las instalaciones, los ingresos y el ROAS de tus apps | Sí — nunca se vincula a una instalación de app |
| Mostrar las conversiones web en los informes de la consola | Sí — por campaña, junto a las instalaciones |
| Enviar las conversiones web a Meta o TikTok | Todavía no |
Las conversiones enviadas aquí aparecen en Eventos en directo, marcadas como no vinculadas a una instalación — lo esperado para un sitio web. Un registro acreditado a una campaña se cuenta en el informe de ROAS como una conversión web de esa campaña, junto a sus instalaciones, y la respuesta de cada llamada te da la atribución al instante.
Errores y reintentos#
Un error de red, un timeout, un 429 o un 5xx se reintenta — dos veces por defecto, con el mismo cuerpo, así que nada se cuenta dos veces. Un 4xx (clave errónea o revocada, payload no válido) no se reintenta. Ambos terminan en un 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)Reporta después de tu propia escritura
Referencia de la API#
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étodo | Qué hace |
|---|---|
signup(user_id, track_id=None, events=()) | Reporta el registro — la captación — con su trackID. Se conserva el primero. |
track(user_id, name, *, value, currency, transaction_id, store, event_id, track_id) | Registra una conversión de un usuario conocido. |
send(user_id, *, track_id, signup, events) | La llamada en bruto detrás de ambos, para varios eventos a la vez. |
track_id_from_request(request) | El trackID de una petición Django, Flask o Starlette, o None. |
track_id_from_cookie_header(header) | Lo mismo, a partir de una cabecera Cookie en bruto. |
Nivel de prueba
matched con su campaña, un clic desconocido recibió unknown, una clave errónea fue rechazada. Todavía no se ha ejecutado en el backend de producción de un cliente.Preguntas frecuentes#
- ¿Hay un cliente asíncrono?
- Hoy no: el cliente es síncrono y solo usa la biblioteca estándar. En FastAPI o Starlette, pasa la llamada a una tarea en segundo plano, que la ejecuta en un hilo después de la respuesta — la página muestra cómo.
- ¿Qué frameworks pueden leer el trackID?
- track_id_from_request lee las peticiones de Django (la cabecera Cookie), las de Flask y Starlette / FastAPI (sus cookies) y cualquier objeto con un mapping headers. Devuelve None cuando el visitante no vino de un anuncio.
- ¿Y si el visitante no vino de un anuncio?
- Pasa None. El registro se guarda igualmente, y el usuario es orgánico: no se acredita ninguna campaña.
- ¿Un reintento contará una compra dos veces?
- No. Cada llamada genera sus ids de evento una sola vez y reintenta exactamente el mismo cuerpo, y una compra se identifica además por su transaction_id, así que el mismo pago reportado dos veces se guarda una sola vez.