vtexads-api-docs

5.6. Eventos

A notificação de eventos é crucial para a atribuição e mensuração.

Boas Práticas

Identificação de Usuário e Sessão

Após identificar o usuário e a sessão, siga estas diretrizes para o disparo de eventos:

Não é necessário manter o estado dos eventos entre carregamentos de página, mas garanta que cada evento seja enviado apenas uma única vez para o mesmo Anúncio e contexto.

Notificação de Impressão, Visualização e Clique

Envie uma requisição POST para a respectiva URL de evento (impression_url, view_url, click_url) fornecida na consulta de anúncios, com um corpo JSON contendo session_id (obrigatório) e user_id (quando disponível).

Veja exemplos de envio no navegador em examples/EVENTS_IMPRESSIONS_VIEWS_CLICKS_BROWSER.md.

Exemplo de envio de evento usando Beacon API:

// Função para enviar evento de impressão
function sendImpressionEvent(impressionUrl, userId, sessionId) {
    // Dados do evento
    const eventData = {
        user_id: userId,
        session_id: sessionId
    };

    // Verifica se o navegador suporta a Beacon API
    if (navigator.sendBeacon) {
        // Converte os dados para JSON
        const blob = new Blob([JSON.stringify(eventData)], {type: 'application/json'});

        // Envia o evento de forma assíncrona
        const success = navigator.sendBeacon(impressionUrl, blob);

        if (!success) {
            console.error('Falha ao enviar evento via Beacon API');
            // Implementar fallback se necessário
        }
    } else {
        // Fallback para navegadores que não suportam Beacon API
        const xhr = new XMLHttpRequest();
        xhr.open('POST', impressionUrl, true); // true para assíncrono
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(eventData));
    }
}

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

Importante: O uso da Beacon API é obrigatório para garantir que os eventos sejam enviados mesmo quando o usuário navega para outra página ou fecha o navegador. Isso evita a perda de eventos e garante uma medição mais precisa.

Notificação de Conversão

Quando uma compra é finalizada, envie os dados do pedido.

Veja exemplos de conversão em examples/EVENTS_CONVERSION_BROWSER.md (Browser) e examples/EVENTS_CONVERSION_CURL.md (cURL).

Campo do Pedido Descrição Tipo Obrigatório?
publisher_id ID do publisher. String Sim
user_id ID do usuário que realizou a compra. String Sim
session_id ID da sessão da compra. String Sim
order_id ID do pedido. String Sim
created_at Data/hora do pedido (ISO 8601 em UTC). String Sim
items Lista de itens do pedido. Array[Item] Sim
channel Canal de venda (ex.: ecommerce, app, loja física). String Sim
brand Marca/site onde ocorreu a venda (necessário quando existe mais de um site). String Não/Sim
gender Indica qual o sexo do cliente. F: para feminino, M: para masculino, O: para outros, null: para não identificados. String Não (Recomendado)
uf Indica o estado da compra do pedido. String Não (Recomendado)
city Indica qual o nome da cidade o cliente comprou. String Não (Recomendado)
is_company Indica se a venda foi feita para pessoa física ou jurídica. Boolean Não (Recomendado)
email_hashed E-mail do usuário em formato hash (SHA256). String Sim
phone_hashed Telefone do usuário em hash (SHA256). String Não (Recomendado)
social_id_hashed CPF/CNPJ do usuário em hash (SHA256). String Não (Recomendado)
first_name_hashed Identificação do Primeiro Nome do usuário (hash). String Não (Recomendado)
last_name_hashed Identificação do Último Nome do usuário (hash). String Não (Recomendado)

Normalização recomendada para hashing:

Estrutura dos Itens do Pedido

Campos do Objeto Item
Campo Descrição Tipo Obrigatoriedade
sku Identificação única do SKU do produto String Obrigatório
quantity Quantidade comprada do produto Double Obrigatório
price Preço original do produto (preço “de”) Double Obrigatório
promotional_price Preço promocional do produto (preço “por”) Double Obrigatório
seller_id Identificação do vendedor/seller String Opcional
product_id Identificação única do produto que engloba o SKU String Opcional
⚠️ Observações Importantes
  1. Valores unitários: Os campos price e promotional_price devem conter o valor unitário do produto, não multiplicado pela quantidade
  2. Campos obrigatórios para mensuração: Se price e promotional_price não forem informados corretamente, a conversão não poderá ser mensurada
  3. Formato monetário: Valores devem ser enviados como números decimais (ex: 1899.00)

Exemplos de Utilização

Exemplo de Item Individual
{
  "sku": "12221",
  "seller_id": "1234",
  "product_id": "4567",
  "quantity": 1,
  "price": 2000.00,
  "promotional_price": 1899.00
}
Exemplo de Requisição 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: No exemplo acima, observe que:

Respostas da API

✅ Resposta de Sucesso (HTTP 202)
{
  "messages": [
    "conversion will be processed soon"
  ]
}
❌ Resposta de Erro de Validação (HTTP 422)

A API retorna erros de validação em um formato compatível com JSON Schema (semântica similar ao Ajv).

Exemplo de resposta com erros:

[
  {
    "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"
  }
]

🎯 Regra de Match de Produtos para Conversões

Importante: Correspondência entre Produto e Campanha

As conversões só são computadas para campanhas quando ocorre um match de produto. Isso significa que:

Exemplo Prático:

Cenário 1 - Com Match (Conversão Computada)

Cenário 2 - Sem Match (Conversão NÃO Computada)

Exemplo de Código

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

  try {
    // Converte os dados para JSON
    const blob = new Blob([JSON.stringify(payload)], {type: 'application/json'});

    // Envia o evento de forma assí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('Conversão enviada com sucesso');
      } else {
        console.error('Falha ao enviar conversão via Beacon API');
      }
    } else {
      // Fallback para navegadores que não suportam 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('Conversão enviada com sucesso');
      } else if (response.status === 422) {
        const errors = await response.json();
        console.error('Erros de validação:', errors);
      }
    }
  } catch (error) {
    console.error('Erro ao enviar conversão:', error);
  }
};

// Exemplo 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
    }
  ]
};

enviarConversao(pedido);

Regras de Atribuição e Deduplicação