vtexads-api-docs

5.6. Events

Event notification is crucial for attribution and measurement.

Best Practices

User and Session Identification

After identifying the user and the session, follow these guidelines when firing events:

There is no need to persist event state across page loads, but make sure each event is sent only once for the same Ad and context.

Impression, View, and Click Notification

Send a POST request to the respective event URL (impression_url, view_url, click_url) provided in the ad query, with a JSON body containing session_id (required) and user_id (when available).

See browser event sending examples in examples/EVENTS_IMPRESSIONS_VIEWS_CLICKS_BROWSER.md.

Example of sending an event using Beacon API:

// Function to send impression event
function sendImpressionEvent(impressionUrl, userId, sessionId) {
    // Event data
    const eventData = {
        user_id: userId,
        session_id: sessionId
    };

    // Check if browser supports Beacon API
    if (navigator.sendBeacon) {
        // Convert data to JSON
        const blob = new Blob([JSON.stringify(eventData)], {type: 'application/json'});

        // Send event asynchronously
        const success = navigator.sendBeacon(impressionUrl, blob);

        if (!success) {
            console.error('Failed to send event via Beacon API');
            // Implement fallback if needed
        }
    } else {
        // Fallback for browsers that don't support Beacon API
        const xhr = new XMLHttpRequest();
        xhr.open('POST', impressionUrl, true); // true for asynchronous
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(eventData));
    }
}

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

Important: Using the Beacon API is mandatory to ensure that events are sent even when the user navigates to another page or closes the browser. This prevents loss of events and ensures more accurate measurement.

Conversion Notification

When a purchase is completed, send the order data.

See conversion examples in examples/EVENTS_CONVERSION_BROWSER.md (Browser) and examples/EVENTS_CONVERSION_CURL.md (cURL).

Order Field Description Type Required?
publisher_id Publisher ID. String Yes
user_id ID of the user who made the purchase. String Yes
session_id Session ID of the purchase. String Yes
order_id Order ID. String Yes
created_at Order date/time (ISO 8601 in UTC). String Yes
items List of order items. Array[Item] Yes
channel Sales channel (e.g., ecommerce, app, physical store). String Yes
brand Brand/site where the sale occurred (required when there is more than one site). String No/Yes
gender Indicates the customer’s gender. F: for female, M: for male, O: for others, null: for unidentified. String No (Recommended)
uf Indicates the state of the order purchase. String No (Recommended)
city Indicates the city where the customer made the purchase. String No (Recommended)
is_company Indicates if the sale was made to a company or individual. Boolean No (Recommended)
email_hashed User’s email in hash format (SHA256). String Yes
phone_hashed User’s phone in hash (SHA256). String No (Recommended)
social_id_hashed User’s Tax ID (CPF/CNPJ) in hash (SHA256). String No (Recommended)
first_name_hashed User’s First Name (hashed). String No (Recommended)
last_name_hashed User’s Last Name (hashed). String No (Recommended)

Recommended normalization for hashing:

Order Items Structure

Item Object Fields
Field Description Type Required
sku Unique product SKU identifier String Required
quantity Quantity of product purchased Double Required
price Original product price (list price) Double Required
promotional_price Promotional product price (sale price) Double Required
seller_id Seller identifier String Optional
product_id Unique product identifier that encompasses the SKU String Optional
⚠️ Important Notes
  1. Unit values: The price and promotional_price fields must contain the unit value of the product, not multiplied by quantity
  2. Required fields for measurement: If price and promotional_price are not provided correctly, the conversion cannot be measured
  3. Monetary format: Values must be sent as decimal numbers (e.g., 1899.00)

Usage Examples

Individual Item Example
{
  "sku": "12221",
  "seller_id": "1234",
  "product_id": "4567",
  "quantity": 1,
  "price": 2000.00,
  "promotional_price": 1899.00
}
Complete Request Example
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"
}

Note: In the example above, observe that:

API Responses

✅ Success Response (HTTP 202)
{
  "messages": [
    "conversion will be processed soon"
  ]
}
❌ Validation Error Response (HTTP 422)

The API returns validation errors in a JSON Schema–compatible (Ajv-like) format.

Example error response:

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

🎯 Product Match Rule for Conversions

Important: Product and Campaign Matching

Conversions are only computed for campaigns when a product match occurs. This means:

Practical Example:

Scenario 1 - With Match (Conversion Computed)

Scenario 2 - Without Match (Conversion NOT Computed)

Code Example

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

  try {
    // Convert data to JSON
    const blob = new Blob([JSON.stringify(payload)], {type: 'application/json'});

    // Send event asynchronously using Beacon API
    if (navigator.sendBeacon) {
      const success = navigator.sendBeacon(
        'https://events.newtail-media.newtail.com.br/v1/beacon/conversion',
        blob
      );

      if (success) {
        console.log('Conversion sent successfully');
      } else {
        console.error('Failed to send conversion via Beacon API');
      }
    } else {
      // Fallback for browsers that don't support 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('Conversion sent successfully');
      } else if (response.status === 422) {
        const errors = await response.json();
        console.error('Validation errors:', errors);
      }
    }
  } catch (error) {
    console.error('Error sending conversion:', error);
  }
};

// Example usage
const order = {
  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
    }
  ]
};

sendConversion(order);

Attribution and Deduplication Rules