Skip to content

Quickstart: Send your first search events with the Events API

View MD

This guide provides the core steps for tracking user search interactions by sending events directly to the Luigi’s Box Events API. This method gives you complete control over the data you send and is the standard approach for integrations in non-browser environments like mobile applications or for tracking events from your server’s backend.

  • How to structure and send a JSON payload for a search event.
  • How to structure and send a JSON payload for a click event to track user interactions.
  • How to use the Live Session Explorer in the Luigi’s Box app to verify your integration is working in real-time.

This guide is for developers who are:

  • Integrating Luigi’s Box in a mobile application (iOS, Android).
  • Sending analytics events from their backend server.
  • Working on a website but prefer not to use the JavaScript-based DataLayer Collector.

Before you start, please ensure you have the following:

  • The ability to make HTTP POST requests from your application or server.
  • Luigi’s Box tracker_id.
  • A method for generating a unique client_id for each user/device.

All events are sent via an HTTP POST request to https://api.luigisbox.com/.

When a user sees a list of search results, you must send an event to report precisely what they saw. This is the foundation of the feedback loop.

{
"id": "f3f6917c-2e94-4e38-a744-24cbb82f284d", // A globally unique ID for this event
"type": "event",
"tracker_id": "YOUR_TRACKER_ID",
"client_id": 6667519810961010000,
"lists": {
"Search Results": { // This exact name is critical
"query": {
"string": "white shirt" // The user's raw query
},
"items": [
{
"title": "White shirt v-neck",
"type": "item", // The catalog type of the object
"url": "39818", // The unique ID matching your catalog
"position": 1, // The item's position in the list
"price": 19
},
// ... add all other visible results here
]
}
},
"platform": "ios" // Optional: "ios", "android", "desktop", etc.
}
  • id: Must be a globally unique id for each event (e.g., a UUID).
  • lists."Search Results": The object key must be exactly “Search Results” to be processed correctly.
  • items.url: This is the object’s unique identifier. It must match the ID used in your product catalog.

These examples show how to make HTTP POST requests to the Events API.

require 'faraday'
require 'json'
require 'securerandom'
# --- Configuration ---
TRACKER_ID = "YOUR_TRACKER_ID"
API_ENDPOINT = "https://api.luigisbox.com/"
# In a real app, client_id would come from the user's session or device
CLIENT_ID = 6667519810961010000 # Example client_id
# --- Helper Function using Faraday ---
def send_luigis_box_event(payload)
# Create a new Faraday connection
conn = Faraday.new(url: API_ENDPOINT) do |faraday|
faraday.request :json # Automatically encode request body as JSON
faraday.adapter Faraday.default_adapter # Use the default HTTP adapter
end
begin
# Make the POST request
response = conn.post do |req|
req.url API_ENDPOINT
req.headers['Content-Type'] = 'application/json'
req.body = payload.to_json
end
puts "Response Code: #{response.status}"
puts "Response Body: #{response.body}"
# Faraday automatically raises errors for 4xx/5xx responses if you use response.success? or conn.response :raise_error
rescue Faraday::Error => e
puts "Error sending event: #{e.message}"
puts "Response body: #{e.response[:body]}" if e.response
end
end
# --- Search View Event Data ---
search_query_term = "white shirt"
search_results_items = [
{ title: "White shirt v-neck", type: "item", url: "39818", position: 1, price: 19 },
{ title: "Another white shirt", type: "item", url: "39819", position: 2, price: 25 }
]
search_view_payload = {
id: SecureRandom.uuid,
type: "event",
tracker_id: TRACKER_ID,
client_id: CLIENT_ID,
lists: {
"Search Results" => {
query: { string: search_query_term },
items: search_results_items
}
},
platform: "backend-ruby-faraday"
}
# --- Send the Event ---
puts "Sending Search View Event..."
send_luigis_box_event(search_view_payload)

When a user clicks on a search result, send a click event. This tells Luigi’s Box that the user showed interest in a specific item from the list you sent in Step 1.

{
"id": "cecceeef-f82f-4fd0-9caf-aaeef2981370", // A new unique ID for this event
"type": "click",
"tracker_id": "YOUR_TRACKER_ID",
"client_id": 6667519810961010000,
"action": {
"type": "click",
"resource_identifier": "39818" // The unique ID of the item that was clicked
},
"platform": "ios"
}

The resource_identifier must match the url of the item from the search results list so Luigi’s Box can link the click to the original search.

# (Continuing from the Ruby example above, assuming send_luigis_box_event and config are defined)
# --- Click Event Data ---
clicked_item_id = "39818"
click_payload = {
id: SecureRandom.uuid,
type: "click",
tracker_id: TRACKER_ID,
client_id: CLIENT_ID,
action: {
type: "click",
resource_identifier: clicked_item_id
},
platform: "backend-ruby-faraday"
}
# --- Send the Event ---
puts "Sending Click Event..."
send_luigis_box_event(click_payload)

Step 3: Send an event for no results queries

Section titled “Step 3: Send an event for no results queries”

You must send a search event even when a query returns zero results. This is critical for Luigi’s Box to identify queries that need improvement. Send the same event structure with an empty items array.

{
"id": "a7b8c9d0-e1f2-3456-a7b8-c9d0e1f23456",
"type": "event",
"tracker_id": "YOUR_TRACKER_ID",
"client_id": 6667519810961010000,
"lists": {
"Search Results": {
"query": {
"string": "xyznonexistent"
},
"items": []
}
}
}

You can watch your events arrive in real-time inside the Luigi’s Box application.

  1. Log in to your Luigi’s Box application.
  2. Navigate to “General settings” in the menu, and then select Live session explorer.
  3. From your app or backend, trigger the events from Step 1 and Step 2.
  4. You will see a new session appear in the explorer for your client_id, and clicking on it will show you the “Search event” and “Click event” you just sent.

To avoid common issues and ensure high-quality data collection, keep these points in mind:

  • Always send an event: If a search returns zero results, you should still send a “Search event” with an empty items array ([]). This is crucial for identifying poorly performing queries.
  • Use stable, matching IDs: The identifier you use in the url field for an item must be the unique and immutable (unchanging) identifier that matches your product catalog.
  • Handle timestamps correctly: If you choose to send the optional local_timestamp field, ensure the value is in seconds, not milliseconds. Sending milliseconds will cause the event to be decoded as a date far in the future and dropped.
  • Generate unique event IDs: Every single event you send must have a new, globally unique value for the top-level id field.
  • Handle pagination correctly: The position for each item must be its absolute position in the full list of results. For example, if you show 20 items per page, the first item on page 2 should have "position": 21, not "position": 1.

Now that you have foundational search tracking working, you can expand it to track critical conversions that provide even stronger signals to the AI models:

  • Track “add to cart”: To track this, send a click event, but change the action.type to a descriptive name like "add_to_cart".
  • Track purchases: To track a completed sale, send a transaction event. This event has its own specific structure for listing all the items in the order.