vtexads-api-docs

5.6. Eventos

La notificación de eventos es crucial para la atribución y la medición.

Buenas Prácticas

Identificación de Usuario y Sesión

Después de identificar al usuario y la sesión, siga estas directrices para el disparo de eventos:

No es necesario mantener el estado de los eventos entre cargas de página, pero asegúrese de que cada evento se envíe solo una vez para el mismo Anuncio y contexto.

Notificación de Impresión, Visualización y Clic

Envíe una solicitud POST a la respectiva URL de evento (impression_url, view_url, click_url) proporcionada en la consulta de anuncios, con un cuerpo JSON que contenga session_id (obligatorio) y user_id (cuando esté disponible).

Consulte ejemplos de envío desde el navegador en examples/EVENTS_IMPRESSIONS_VIEWS_CLICKS_BROWSER.md.

Ejemplo de envío de evento usando Beacon API:

// Función para enviar evento de impresión
function sendImpressionEvent(impressionUrl, userId, sessionId) {
    // Datos del evento
    const eventData = {
        user_id: userId,
        session_id: sessionId
    };

    // Verifica si el navegador soporta la Beacon API
    if (navigator.sendBeacon) {
        // Convierte los datos a JSON
        const blob = new Blob([JSON.stringify(eventData)], {type: 'application/json'});

        // Envía el evento de forma asíncrona
        const success = navigator.sendBeacon(impressionUrl, blob);

        if (!success) {
            console.error('Error al enviar evento vía Beacon API');
            // Implementar fallback si es necesario
        }
    } else {
        // Fallback para navegadores que no soportan Beacon API
        const xhr = new XMLHttpRequest();
        xhr.open('POST', impressionUrl, true); // true para asíncrono
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(eventData));
    }
}

// Ejemplo de uso
sendImpressionEvent(
    'https://events.newtail-media.newtail.com.br/v1/beacon/impression/123456',
    'user-123',
    'session-456'
);

Importante: El uso de la Beacon API es obligatorio para garantizar que los eventos se envíen incluso cuando el usuario navega a otra página o cierra el navegador. Esto evita la pérdida de eventos y asegura una medición más precisa.

Notificación de Conversión

Cuando una compra es finalizada, envíe los datos del pedido.

Consulte ejemplos de conversión en examples/EVENTS_CONVERSION_BROWSER.md (Browser) y examples/EVENTS_CONVERSION_CURL.md (cURL).

Campo del Pedido Descripción Tipo ¿Obligatorio?
publisher_id ID del publisher. String
user_id ID del usuario que realizó la compra. String
session_id ID de la sesión de la compra. String
order_id ID del pedido. String
created_at Fecha/hora del pedido (ISO 8601 en UTC). String
items Lista de artículos del pedido. Array[Item]
channel Canal de venta (ej.: ecommerce, app, tienda física). String
brand Marca/sitio donde ocurrió la venta (necesario cuando existe más de un sitio). String No/Sí
gender Indica el género del cliente. F: para femenino, M: para masculino, O: para otros, null: para no identificados. String No (Recomendado)
uf Indica el estado de la compra del pedido. String No (Recomendado)
city Indica el nombre de la ciudad donde el cliente realizó la compra. String No (Recomendado)
is_company Indica si la venta fue realizada a una persona jurídica o física. Boolean No (Recomendado)
email_hashed E-mail del usuario en formato hash (SHA256). String
phone_hashed Teléfono del usuario en hash (SHA256). String No (Recomendado)
social_id_hashed ID social/fiscal del usuario (CUIT/CUIL) en hash (SHA256). String No (Recomendado)
first_name_hashed Nombre del usuario (hash). String No (Recomendado)
last_name_hashed Apellido del usuario (hash). String No (Recomendado)

Normalización recomendada para hashing:

Estructura de los Artículos del Pedido

Campos del Objeto Item
Campo Descripción Tipo Obligatoriedad
sku Identificación única del SKU del producto String Obligatorio
quantity Cantidad comprada del producto Double Obligatorio
price Precio original del producto (precio “de”) Double Obligatorio
promotional_price Precio promocional del producto (precio “por”) Double Obligatorio
seller_id Identificación del vendedor/seller String Opcional
product_id Identificación única del producto que engloba el SKU String Opcional
⚠️ Observaciones Importantes
  1. Valores unitarios: Los campos price y promotional_price deben contener el valor unitario del producto, no multiplicado por la cantidad
  2. Campos obligatorios para medición: Si price y promotional_price no se informan correctamente, la conversión no podrá ser medida
  3. Formato monetario: Los valores deben enviarse como números decimales (ej: 1899.00)

Ejemplos de Utilización

Ejemplo de Artículo Individual
{
  "sku": "12221",
  "seller_id": "1234",
  "product_id": "4567",
  "quantity": 1,
  "price": 2000.00,
  "promotional_price": 1899.00
}
Ejemplo de Solicitud Completa
POST https://events.newtail-media.newtail.com.br/v1/beacon/conversion HTTP/1.1
Accept: application/json
Content-Type: application/json
{
  "channel": "ecommerce",
  "publisher_id": "xxx",
  "user_id": "6f92d1e9-00b6-4f8b-9645-faeab321e1cc",
  "session_id": "5898b8d1-c250-4bb5-931b-8b9d0ee7b499",
  "order_id": "123",
  "email_hashed": "xyz",
  "items": [
    {
      "sku": "12221",
      "seller_id": "1234",
      "product_id": "4567",
      "quantity": 1,
      "price": 2000.00,
      "promotional_price": 1899.00
    },
    {
      "sku": "12222",
      "seller_id": null,
      "product_id": "4568",
      "quantity": 2,
      "price": 500.00,
      "promotional_price": 400.00
    }
  ],
  "created_at": "2023-01-01T09:20:00Z"
}

Nota: En el ejemplo anterior, observe que:

Respuestas de la API

✅ Respuesta Exitosa (HTTP 202)
{
  "messages": [
    "conversion will be processed soon"
  ]
}
❌ Respuesta de Error de Validación (HTTP 422)

La API devuelve errores de validación en un formato compatible con JSON Schema (similar a Ajv).

Ejemplo de respuesta con errores:

[
  {
    "instancePath": "",
    "keyword": "required",
    "message": "must have required property 'user_id'",
    "params": {
      "missingProperty": "user_id"
    },
    "schemaPath": "#/required"
  },
  {
    "instancePath": "",
    "keyword": "required",
    "message": "must have required property 'order_id'",
    "params": {
      "missingProperty": "order_id"
    },
    "schemaPath": "#/required"
  },
  {
    "instancePath": "",
    "keyword": "required",
    "message": "must have required property 'publisher_id'",
    "params": {
      "missingProperty": "publisher_id"
    },
    "schemaPath": "#/required"
  },
  {
    "instancePath": "",
    "keyword": "required",
    "message": "must have required property 'items'",
    "params": {
      "missingProperty": "items"
    },
    "schemaPath": "#/required"
  },
  {
    "instancePath": "",
    "keyword": "required",
    "message": "must have required property 'created_at'",
    "params": {
      "missingProperty": "created_at"
    },
    "schemaPath": "#/required"
  }
]

🎯 Regla de Match de Productos para Conversiones

Importante: Correspondencia entre Producto y Campaña

Las conversiones solo se computan para campañas cuando ocurre un match de producto. Esto significa que:

Ejemplo Práctico:

Escenario 1 - Con Match (Conversión Computada)

Escenario 2 - Sin Match (Conversión NO Computada)

Ejemplo de Código

JavaScript (Browser)
const enviarConversion = async (datosPedido) => {
  const payload = {
    channel: "ecommerce",
    publisher_id: "xxx",
    user_id: datosPedido.userId,
    session_id: datosPedido.sessionId,
    order_id: datosPedido.orderId,
    email_hashed: datosPedido.emailHash,
    items: datosPedido.items.map(item => ({
      sku: item.sku,
      seller_id: item.sellerId || null,
      product_id: item.productId || null,
      quantity: item.quantity,
      price: item.unitPrice,  // Valor unitario, no multiplicado
      promotional_price: item.unitPromotionalPrice  // Valor unitario, no multiplicado
    })),
    created_at: new Date().toISOString()
  };

  try {
    // Convierte los datos a JSON
    const blob = new Blob([JSON.stringify(payload)], {type: 'application/json'});

    // Envía el evento de forma asíncrona usando Beacon API
    if (navigator.sendBeacon) {
      const success = navigator.sendBeacon(
        'https://events.newtail-media.newtail.com.br/v1/beacon/conversion',
        blob
      );

      if (success) {
        console.log('Conversión enviada con éxito');
      } else {
        console.error('Error al enviar conversión vía Beacon API');
      }
    } else {
      // Fallback para navegadores que no soportan Beacon API
      const response = await fetch('https://events.newtail-media.newtail.com.br/v1/beacon/conversion', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
      });

      if (response.status === 202) {
        console.log('Conversión enviada con éxito');
      } else if (response.status === 422) {
        const errors = await response.json();
        console.error('Errores de validación:', errors);
      }
    }
  } catch (error) {
    console.error('Error al enviar conversión:', error);
  }
};

// Ejemplo de uso
const pedido = {
  userId: "6f92d1e9-00b6-4f8b-9645-faeab321e1cc",
  sessionId: "5898b8d1-c250-4bb5-931b-8b9d0ee7b499",
  orderId: "123",
  emailHash: "xyz",
  items: [
    {
      sku: "12221",
      sellerId: "1234",
      productId: "4567",
      quantity: 1,
      unitPrice: 2000.00,
      unitPromotionalPrice: 1899.00
    }
  ]
};

enviarConversion(pedido);

Reglas de Atribución y Deduplicación