API de servidor
Confirma una conversión desde tu backend con una petición HTTP autenticada con la clave de servidor del proyecto. No necesitas ningún SDK de servidor.
La evidencia del navegador puede perderse: una pestaña se cierra durante el pago, una extensión bloquea la solicitud o falla la red. Confirmar la conversión desde tu backend cubre ese hueco. La evidencia del navegador y la del servidor cuentan como una sola conversión porque comparten el mismo identificador estable.
Envía la conversión desde tu servidor con una petición HTTP y la clave de servidor del proyecto. No hay ningún SDK de servidor que instalar.
Endpoint
https://api.tracelog.io/v1/server/events
Envía un POST con Content-Type: application/json y la clave de servidor
del proyecto como bearer token en Authorization:
Authorization: Bearer tl_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxLa clave es secreta. No está limitada por una lista de orígenes, permite escribir eventos a cualquiera que la posea y nunca debe llegar al bundle del navegador. Rótala desde los ajustes del proyecto; el valor solo se muestra al crearla o rotarla.
El payload
{
"v": 1,
"events": [
{
"eventId": "019b9ae7-2c00-7000-8000-000000000001",
"sessionId": "019b9ae7-2c00-7000-8000-000000000002",
"kind": "conversion",
"name": "purchase",
"occurredAt": "2026-01-08T00:00:00.000Z",
"identifier": "wc-1042",
"value": 129.5,
"currency": "EUR"
}
]
}| Campo | Tipo | Descripción |
|---|---|---|
v | 1 | Versión del payload. Una versión desconocida se rechaza como unknown_version; nunca se interpreta por aproximación. |
eventId | UUID v7 | Clave de idempotencia. Reenviar el mismo valor no duplica el recuento, por lo que es seguro reintentar tras un timeout. |
sessionId | UUID v7 | Visita a la que pertenece la conversión. Usa el que creó el código de captura de TraceLog en el navegador si lo tienes; si no, crea uno. |
kind | string | conversion, step, session_start o error. |
name | string | Nombre del plan: minúsculas, empezar por una letra y continuar con letras, números o guiones bajos, hasta 64 caracteres. |
occurredAt | ISO 8601 | Momento del evento en UTC y con milisegundos. TraceLog asigna el evento a esta hora, no a la de llegada. |
identifier | string | Obligatorio para conversiones, entre 1 y 256 caracteres. Tu identificador estable. |
value | number | Opcional, igual o mayor que cero. |
currency | string | Opcional, código ISO 4217 de tres letras mayúsculas. |
mode | string | Opcional. verification marca tráfico de verificación, que no cuenta en las métricas ni en el límite de sesiones. Úsalo cuando el modo de prueba de tu sistema haya generado el pedido. |
context | object | Opcional. Objeto serializable como JSON, hasta 8 KB. |
Una conversión necesita seis campos: eventId, sessionId, kind, name,
occurredAt e identifier. Cada lote admite como máximo 50 eventos y cada
solicitud, 256 KB. Se rechaza
un evento situado más de cinco minutos en el futuro. Si tiene más de siete
días, se acepta pero queda marcado como tardío.
Respuesta
{ "accepted": 1, "rejected": [] }accepted cuenta los eventos que esa solicitud ha guardado. Un solo evento no
válido rechaza el lote completo: no se guarda nada, y rejected enumera cada
eventId que haya podido leerse con el motivo del lote (unknown_version,
invalid_schema o future_time). Un eventId o un sessionId que no sea un
UUID v7 es invalid_schema.
Un evento de hace más de 30 días, un día que TraceLog ya no conserva, es
expired: se rechaza él solo y el resto del lote se guarda.
Una solicitud de más de 256 KB o de más de 50 eventos se rechaza entera con un
HTTP 413 y sin recibo: eso es too_large. Si una misma clave envía demasiadas
solicitudes, recibe un HTTP 429 con una cabecera Retry-After en segundos.
Ejemplos
curl -X POST "$TRACELOG_API/v1/server/events" \
-H "Authorization: Bearer $TRACELOG_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{
"v": 1,
"events": [{
"eventId": "019b9ae7-2c00-7000-8000-000000000001",
"sessionId": "019b9ae7-2c00-7000-8000-000000000002",
"kind": "conversion",
"name": "purchase",
"occurredAt": "2026-01-08T00:00:00.000Z",
"identifier": "1042",
"value": 129.5,
"currency": "EUR"
}]
}'await fetch(`${process.env.TRACELOG_API}/v1/server/events`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TRACELOG_SERVER_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
v: 1,
events: [
{
eventId: order.eventId, // UUID v7 generado una vez por pedido y guardado con él
sessionId: order.sessionId,
kind: "conversion",
name: "purchase",
occurredAt: new Date().toISOString(),
identifier: order.number,
value: order.total,
currency: order.currency,
},
],
}),
});<?php
$response = wp_remote_post( $api . '/v1/server/events', array(
'headers' => array(
'Authorization' => 'Bearer ' . $server_key,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'v' => 1,
'events' => array( array(
'eventId' => $order->get_meta( '_tracelog_event_id' ), // UUID v7 guardado con el pedido
'sessionId' => $session_id,
'kind' => 'conversion',
'name' => 'purchase',
'occurredAt' => gmdate( 'Y-m-d\TH:i:s.000\Z' ),
'identifier' => (string) $order->get_order_number(),
'value' => (float) $order->get_total(),
'currency' => $order->get_currency(),
) ),
) ),
) );import json, os, urllib.request
request = urllib.request.Request(
f"{os.environ['TRACELOG_API']}/v1/server/events",
method="POST",
headers={
"Authorization": f"Bearer {os.environ['TRACELOG_SERVER_KEY']}",
"Content-Type": "application/json",
},
data=json.dumps({
"v": 1,
"events": [{
"eventId": order.tracelog_event_id, # UUID v7 guardado con el pedido
"sessionId": session_id,
"kind": "conversion",
"name": "purchase",
"occurredAt": occurred_at,
"identifier": str(order.number),
"value": float(order.total),
"currency": order.currency,
}],
}).encode(),
)
urllib.request.urlopen(request)Reintentos
Reintenta tras un error de red, una respuesta 5xx o un 429 una vez pasado su
Retry-After, siempre con el mismo eventId.
El eventId es la clave de idempotencia: una entrega repetida se guarda y se
cuenta una sola vez. Con un eventId nuevo, el reintento se contaría otra
vez.