curl --request POST \
--url https://search.glood.ai/api/storefront/v1/headless/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-shop: <x-shop>' \
--data '
{
"event": {
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"context": {
"navigator": {
"user_agent": "<string>"
},
"document": {},
"window": {}
},
"client_id": "<string>",
"data": {},
"custom_data": {
"track": {
"source": "<string>",
"page_type": "<string>",
"pages": [
{
"page_id": "<string>"
}
],
"products": [
{
"product_id": "<string>",
"variant_id": "<string>",
"quantity": 123
}
],
"request_id": "<string>",
"filters": [
{
"key": "<string>",
"value": [
"<string>"
]
}
],
"search_term": "<string>",
"checkout_token": "<string>",
"campaign": "<string>"
}
}
},
"session_id": "<string>",
"visitor_id": "<string>",
"client_id": "<string>",
"customer_id": "<string>",
"page_type": "<string>",
"page_url": "<string>",
"cart_identifier": "<string>",
"cart": {},
"customer": {},
"customer_privacy": {
"analytics_processing_allowed": true,
"marketing_allowed": true,
"preferences_processing_allowed": true,
"sale_of_data_allowed": true
}
}
'import requests
url = "https://search.glood.ai/api/storefront/v1/headless/events"
payload = {
"event": {
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"context": {
"navigator": { "user_agent": "<string>" },
"document": {},
"window": {}
},
"client_id": "<string>",
"data": {},
"custom_data": { "track": {
"source": "<string>",
"page_type": "<string>",
"pages": [{ "page_id": "<string>" }],
"products": [
{
"product_id": "<string>",
"variant_id": "<string>",
"quantity": 123
}
],
"request_id": "<string>",
"filters": [
{
"key": "<string>",
"value": ["<string>"]
}
],
"search_term": "<string>",
"checkout_token": "<string>",
"campaign": "<string>"
} }
},
"session_id": "<string>",
"visitor_id": "<string>",
"client_id": "<string>",
"customer_id": "<string>",
"page_type": "<string>",
"page_url": "<string>",
"cart_identifier": "<string>",
"cart": {},
"customer": {},
"customer_privacy": {
"analytics_processing_allowed": True,
"marketing_allowed": True,
"preferences_processing_allowed": True,
"sale_of_data_allowed": True
}
}
headers = {
"x-shop": "<x-shop>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-shop': '<x-shop>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event: {
id: '<string>',
timestamp: '2023-11-07T05:31:56Z',
context: {navigator: {user_agent: '<string>'}, document: {}, window: {}},
client_id: '<string>',
data: {},
custom_data: {
track: {
source: '<string>',
page_type: '<string>',
pages: [{page_id: '<string>'}],
products: [{product_id: '<string>', variant_id: '<string>', quantity: 123}],
request_id: '<string>',
filters: [{key: '<string>', value: ['<string>']}],
search_term: '<string>',
checkout_token: '<string>',
campaign: '<string>'
}
}
},
session_id: '<string>',
visitor_id: '<string>',
client_id: '<string>',
customer_id: '<string>',
page_type: '<string>',
page_url: '<string>',
cart_identifier: '<string>',
cart: {},
customer: {},
customer_privacy: {
analytics_processing_allowed: true,
marketing_allowed: true,
preferences_processing_allowed: true,
sale_of_data_allowed: true
}
})
};
fetch('https://search.glood.ai/api/storefront/v1/headless/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://search.glood.ai/api/storefront/v1/headless/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'event' => [
'id' => '<string>',
'timestamp' => '2023-11-07T05:31:56Z',
'context' => [
'navigator' => [
'user_agent' => '<string>'
],
'document' => [
],
'window' => [
]
],
'client_id' => '<string>',
'data' => [
],
'custom_data' => [
'track' => [
'source' => '<string>',
'page_type' => '<string>',
'pages' => [
[
'page_id' => '<string>'
]
],
'products' => [
[
'product_id' => '<string>',
'variant_id' => '<string>',
'quantity' => 123
]
],
'request_id' => '<string>',
'filters' => [
[
'key' => '<string>',
'value' => [
'<string>'
]
]
],
'search_term' => '<string>',
'checkout_token' => '<string>',
'campaign' => '<string>'
]
]
],
'session_id' => '<string>',
'visitor_id' => '<string>',
'client_id' => '<string>',
'customer_id' => '<string>',
'page_type' => '<string>',
'page_url' => '<string>',
'cart_identifier' => '<string>',
'cart' => [
],
'customer' => [
],
'customer_privacy' => [
'analytics_processing_allowed' => true,
'marketing_allowed' => true,
'preferences_processing_allowed' => true,
'sale_of_data_allowed' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-shop: <x-shop>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://search.glood.ai/api/storefront/v1/headless/events"
payload := strings.NewReader("{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-shop", "<x-shop>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://search.glood.ai/api/storefront/v1/headless/events")
.header("x-shop", "<x-shop>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://search.glood.ai/api/storefront/v1/headless/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-shop"] = '<x-shop>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"ok": true
}
{
"ok": false,
"error": "At least one of visitor_id or client_id is required"
}
{
"ok": false,
"error": [
{
"message": "\"channel\" must be one of [HYDROGEN, HEADLESS, MOBILE]",
"path": ["channel"],
"type": "any.only",
"context": { "label": "channel", "key": "channel" }
}
]
}
Send Search Events
Ingest storefront / personalization events (standard Shopify pixel events and custom glood:search:* attribution events). Shop is taken from x-shop. Auth: Authorization: Bearer <gl_sf_...> + x-shop.
curl --request POST \
--url https://search.glood.ai/api/storefront/v1/headless/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-shop: <x-shop>' \
--data '
{
"event": {
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"context": {
"navigator": {
"user_agent": "<string>"
},
"document": {},
"window": {}
},
"client_id": "<string>",
"data": {},
"custom_data": {
"track": {
"source": "<string>",
"page_type": "<string>",
"pages": [
{
"page_id": "<string>"
}
],
"products": [
{
"product_id": "<string>",
"variant_id": "<string>",
"quantity": 123
}
],
"request_id": "<string>",
"filters": [
{
"key": "<string>",
"value": [
"<string>"
]
}
],
"search_term": "<string>",
"checkout_token": "<string>",
"campaign": "<string>"
}
}
},
"session_id": "<string>",
"visitor_id": "<string>",
"client_id": "<string>",
"customer_id": "<string>",
"page_type": "<string>",
"page_url": "<string>",
"cart_identifier": "<string>",
"cart": {},
"customer": {},
"customer_privacy": {
"analytics_processing_allowed": true,
"marketing_allowed": true,
"preferences_processing_allowed": true,
"sale_of_data_allowed": true
}
}
'import requests
url = "https://search.glood.ai/api/storefront/v1/headless/events"
payload = {
"event": {
"id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"context": {
"navigator": { "user_agent": "<string>" },
"document": {},
"window": {}
},
"client_id": "<string>",
"data": {},
"custom_data": { "track": {
"source": "<string>",
"page_type": "<string>",
"pages": [{ "page_id": "<string>" }],
"products": [
{
"product_id": "<string>",
"variant_id": "<string>",
"quantity": 123
}
],
"request_id": "<string>",
"filters": [
{
"key": "<string>",
"value": ["<string>"]
}
],
"search_term": "<string>",
"checkout_token": "<string>",
"campaign": "<string>"
} }
},
"session_id": "<string>",
"visitor_id": "<string>",
"client_id": "<string>",
"customer_id": "<string>",
"page_type": "<string>",
"page_url": "<string>",
"cart_identifier": "<string>",
"cart": {},
"customer": {},
"customer_privacy": {
"analytics_processing_allowed": True,
"marketing_allowed": True,
"preferences_processing_allowed": True,
"sale_of_data_allowed": True
}
}
headers = {
"x-shop": "<x-shop>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'x-shop': '<x-shop>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event: {
id: '<string>',
timestamp: '2023-11-07T05:31:56Z',
context: {navigator: {user_agent: '<string>'}, document: {}, window: {}},
client_id: '<string>',
data: {},
custom_data: {
track: {
source: '<string>',
page_type: '<string>',
pages: [{page_id: '<string>'}],
products: [{product_id: '<string>', variant_id: '<string>', quantity: 123}],
request_id: '<string>',
filters: [{key: '<string>', value: ['<string>']}],
search_term: '<string>',
checkout_token: '<string>',
campaign: '<string>'
}
}
},
session_id: '<string>',
visitor_id: '<string>',
client_id: '<string>',
customer_id: '<string>',
page_type: '<string>',
page_url: '<string>',
cart_identifier: '<string>',
cart: {},
customer: {},
customer_privacy: {
analytics_processing_allowed: true,
marketing_allowed: true,
preferences_processing_allowed: true,
sale_of_data_allowed: true
}
})
};
fetch('https://search.glood.ai/api/storefront/v1/headless/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://search.glood.ai/api/storefront/v1/headless/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'event' => [
'id' => '<string>',
'timestamp' => '2023-11-07T05:31:56Z',
'context' => [
'navigator' => [
'user_agent' => '<string>'
],
'document' => [
],
'window' => [
]
],
'client_id' => '<string>',
'data' => [
],
'custom_data' => [
'track' => [
'source' => '<string>',
'page_type' => '<string>',
'pages' => [
[
'page_id' => '<string>'
]
],
'products' => [
[
'product_id' => '<string>',
'variant_id' => '<string>',
'quantity' => 123
]
],
'request_id' => '<string>',
'filters' => [
[
'key' => '<string>',
'value' => [
'<string>'
]
]
],
'search_term' => '<string>',
'checkout_token' => '<string>',
'campaign' => '<string>'
]
]
],
'session_id' => '<string>',
'visitor_id' => '<string>',
'client_id' => '<string>',
'customer_id' => '<string>',
'page_type' => '<string>',
'page_url' => '<string>',
'cart_identifier' => '<string>',
'cart' => [
],
'customer' => [
],
'customer_privacy' => [
'analytics_processing_allowed' => true,
'marketing_allowed' => true,
'preferences_processing_allowed' => true,
'sale_of_data_allowed' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"x-shop: <x-shop>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://search.glood.ai/api/storefront/v1/headless/events"
payload := strings.NewReader("{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-shop", "<x-shop>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://search.glood.ai/api/storefront/v1/headless/events")
.header("x-shop", "<x-shop>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://search.glood.ai/api/storefront/v1/headless/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-shop"] = '<x-shop>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"event\": {\n \"id\": \"<string>\",\n \"timestamp\": \"2023-11-07T05:31:56Z\",\n \"context\": {\n \"navigator\": {\n \"user_agent\": \"<string>\"\n },\n \"document\": {},\n \"window\": {}\n },\n \"client_id\": \"<string>\",\n \"data\": {},\n \"custom_data\": {\n \"track\": {\n \"source\": \"<string>\",\n \"page_type\": \"<string>\",\n \"pages\": [\n {\n \"page_id\": \"<string>\"\n }\n ],\n \"products\": [\n {\n \"product_id\": \"<string>\",\n \"variant_id\": \"<string>\",\n \"quantity\": 123\n }\n ],\n \"request_id\": \"<string>\",\n \"filters\": [\n {\n \"key\": \"<string>\",\n \"value\": [\n \"<string>\"\n ]\n }\n ],\n \"search_term\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"campaign\": \"<string>\"\n }\n }\n },\n \"session_id\": \"<string>\",\n \"visitor_id\": \"<string>\",\n \"client_id\": \"<string>\",\n \"customer_id\": \"<string>\",\n \"page_type\": \"<string>\",\n \"page_url\": \"<string>\",\n \"cart_identifier\": \"<string>\",\n \"cart\": {},\n \"customer\": {},\n \"customer_privacy\": {\n \"analytics_processing_allowed\": true,\n \"marketing_allowed\": true,\n \"preferences_processing_allowed\": true,\n \"sale_of_data_allowed\": true\n }\n}"
response = http.request(request)
puts response.read_body{
"ok": true
}
{
"ok": false,
"error": "At least one of visitor_id or client_id is required"
}
{
"ok": false,
"error": [
{
"message": "\"channel\" must be one of [HYDROGEN, HEADLESS, MOBILE]",
"path": ["channel"],
"type": "any.only",
"context": { "label": "channel", "key": "channel" }
}
]
}
{
"ok": true
}
{
"ok": false,
"error": "At least one of visitor_id or client_id is required"
}
{
"ok": false,
"error": [
{
"message": "\"channel\" must be one of [HYDROGEN, HEADLESS, MOBILE]",
"path": ["channel"],
"type": "any.only",
"context": { "label": "channel", "key": "channel" }
}
]
}
Event payload structure
Every request posts one event in the same envelope. All fields are snake_case. The full request body:{
"channel": "HEADLESS",
"visitor_id": "gl_s_uid_9f2c",
"client_id": "c_18a4",
"customer_id": "7234891234567",
"session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"page_type": "search",
"page_url": "https://your-store.com/search?q=shoe",
"cart_identifier": "cart-token?key=abc123",
"cart": { "cost": { "totalAmount": { "amount": 49.99, "currencyCode": "USD" } } },
"customer": { "id": "7234891234567", "email": "jane@example.com", "phone": "+14155550100" },
"customer_privacy": {
"analytics_processing_allowed": true,
"marketing_allowed": true,
"preferences_processing_allowed": true,
"sale_of_data_allowed": false
},
"event": {
"id": "b7f91c2e-1d44-4b50-8888-8dd25736052a",
"client_id": "c_18a4",
"name": "<event name>",
"type": "standard | custom",
"timestamp": "2026-08-05T10:30:00.000Z",
"context": {
"document": {
"title": "Search",
"referrer": "https://your-store.com/",
"character_set": "UTF-8",
"location": {
"href": "https://your-store.com/search?q=shoe",
"pathname": "/search",
"search": "?q=shoe",
"hash": "",
"host": "your-store.com",
"hostname": "your-store.com",
"origin": "https://your-store.com",
"port": "",
"protocol": "https:"
}
},
"navigator": {
"user_agent": "Mozilla/5.0 ...",
"language": "en-US",
"languages": ["en-US", "en"],
"cookie_enabled": true
},
"window": { "screen": { "width": 1920, "height": 1080 } }
},
"data": {},
"custom_data": {}
}
}
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
channel | string | ✓ | HYDROGEN, HEADLESS, or MOBILE |
event | object | ✓ | The event envelope (below) |
visitor_id | string | ✓* | Anonymous persistent visitor UID. *At least one of visitor_id / client_id is required |
client_id | string | ✓* | Client/device id, persists across sessions |
customer_id | string | — | Shopify customer id when logged in |
session_id | string | — | Browsing-session id — the unit of funnel and attribution analytics. The server generates a UUID when absent; send a stable one per visit for accurate analytics |
page_type | string | — | Page type the event fired from |
page_url | string | — | URL the event fired from |
cart_identifier | string | — | Cart token/key identifier (<token>?key=<key>) |
cart | object | — | Cart state at event time (Shopify cart shape) |
customer | object | — | Customer info at event time (id, email, phone) |
customer_privacy | object | — | Consent flags: analytics_processing_allowed, marketing_allowed, preferences_processing_allowed, sale_of_data_allowed (booleans) |
The event object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | ✓ | Unique event id (UUID) |
name | string | ✓ | Event name — a standard Shopify event name or a glood: custom event name (see below) |
type | string | ✓ | standard or custom |
timestamp | string | ✓ | ISO 8601 event time, must be within ±2 days of now |
context | object | ✓ | Browser context — see below |
data | object | ✓ when type=standard | The Shopify standard event payload (may be {}) |
custom_data | object | ✓ when type=custom | Must contain a track object (see Glood search events) |
client_id | string | — | Client id carried on the event; defaults from the top-level identity |
The context object
All context keys are snake_case on the wire. Unknown keys are accepted but only the fields
marked as persisted below are stored on the event; anything else is discarded at ingestion.
| Field | Required | Persisted | Description |
|---|---|---|---|
navigator.user_agent | ✓ | ✓ | Client user-agent string — browser, OS, and device are derived from it server-side |
navigator.language | — | ✓ | Client language (e.g. en-US) |
navigator.cookie_enabled | — | ✓ | Whether cookies are enabled |
navigator.languages | — | — | Accepted, not persisted |
document.location | — | ✓ | Full URL breakdown — href, pathname, search, hash, host, hostname, origin, port, protocol — persisted as sent. Not validated as required, but always send it: analytics scope page and session funnels by document.location.pathname (e.g. a page_viewed under /search counts toward the search-page funnel). Events without it are accepted but can’t be attributed to a surface |
document.title | — | ✓ | Page title |
document.referrer | — | ✓ | Referring URL |
document.character_set | — | ✓ | Document character set (e.g. UTF-8) |
window.screen | — | ✓ | Screen dimensions (width, height) |
window.inner_width, window.inner_height, window.outer_width, window.outer_height, window.page_x_offset, window.page_y_offset, window.screen_x, window.screen_y, window.scroll_x, window.scroll_y, window.location, window.origin | — | — | Accepted, not persisted |
userAgent, cookieEnabled,
characterSet). The headless API is snake_case: a body sent with navigator.userAgent is
rejected with "navigator.user_agent" is required, and camelCase fields like
characterSet pass validation but are silently dropped. Convert the pixel context to
snake_case before posting.event.name, event.type, and where the payload lives:
- Standard events — Shopify standard (pixel) events.
type: "standard", payload inevent.data. - Glood search events — custom attribution events emitted by the Glood search app.
type: "custom", payload inevent.custom_data.track.
Standard search events
Any Shopify standard event can be forwarded:page_viewed, product_viewed, collection_viewed, cart_viewed,
search_submitted, product_added_to_cart, product_removed_from_cart,
checkout_started, checkout_completed, and the other checkout events. event.data
carries the standard event’s payload as defined by Shopify. Some standard events
(page_viewed) have an empty data by design — their information lives in
event.context.document.
{
"channel": "HEADLESS",
"visitor_id": "gl_s_uid_9f2c",
"event": {
"id": "b7f91c2e-1d44-4b50-8888-8dd25736052a",
"name": "search_submitted",
"type": "standard",
"timestamp": "2026-08-05T10:30:00.000Z",
"context": {
"document": {
"title": "Search",
"location": { "href": "https://your-store.com/search?q=shoe", "pathname": "/search", "search": "?q=shoe" }
},
"navigator": { "user_agent": "Mozilla/5.0 ..." },
"window": { "screen": { "width": 1920, "height": 1080 } }
},
"data": {
"searchResult": {
"query": "shoe"
}
}
}
}
Glood search events
Custom attribution events usetype: "custom" and carry a track object under
event.custom_data. All track fields are optional; always send request_id (from the
search response) when you have it — it ties the interaction back to the serve.
| Field | Type | Description |
|---|---|---|
request_id | string | request_id from the search response |
search_term | string | The search term |
search_type | string | text or image |
source | string | Where the interaction originated (e.g. instant, search_page) |
page_type | string | Page type of the interaction |
products | array | { product_id, variant_id?, quantity? } — products involved |
filters | array | { key, value } — filter selections (value is an array, or null when nothing is selected) |
checkout_token | string | Checkout token, for conversion attribution |
campaign | string | Campaign identifier |
event.name and event.custom_data — the rest of the envelope is
identical to the one above.
glood:search_result_rendered
Send when search results are rendered / enter the viewport.products lists the rendered
results; include filters when the result set was rendered with facets applied:
{
"name": "glood:search_result_rendered",
"type": "custom",
"custom_data": {
"track": {
"request_id": "req_01j8x2v9",
"search_term": "shoe",
"search_type": "text",
"source": "search_page",
"page_type": "search",
"products": [
{ "product_id": "9311227838783" },
{ "product_id": "9311227838784" }
],
"filters": [{ "key": "color", "value": ["red"] }]
}
}
}
glood:search_result_clicked
Send when a result is clicked.products carries the clicked product; include the filters
active at click time:
{
"name": "glood:search_result_clicked",
"type": "custom",
"custom_data": {
"track": {
"request_id": "req_01j8x2v9",
"search_term": "shoe",
"search_type": "text",
"source": "search_page",
"products": [
{ "product_id": "9311227838783", "variant_id": "48792371233087" }
],
"filters": [{ "key": "color", "value": ["red"] }]
}
}
}
glood:search_filter_appeared
Send when the filter UI is rendered for a result set.filters lists the facets shown, with
value: null while nothing is selected:
{
"name": "glood:search_filter_appeared",
"type": "custom",
"custom_data": {
"track": {
"request_id": "req_01j8x2v9",
"search_term": "shoe",
"search_type": "text",
"source": "search_page",
"filters": [
{ "key": "color", "value": null },
{ "key": "price", "value": null }
]
}
}
}
glood:search_filter_updated
Send when a facet is applied or changed.filters carries the full current selection (not
the delta):
{
"name": "glood:search_filter_updated",
"type": "custom",
"custom_data": {
"track": {
"request_id": "req_01j8x2v9",
"search_term": "shoe",
"search_type": "text",
"source": "search_page",
"filters": [{ "key": "color", "value": ["red", "blue"] }]
}
}
}
track shape is used by the other custom search events
(glood:instant_search_triggered, glood:instant_search_rendered,
glood:image_search_triggered, glood:image_search_results_rendered,
glood:search:add_to_cart) — see the event.name enum in the schema for the full list.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Shopify store URL. Resolves the shop for the request (headless does not accept ?shop=).
"shop.myshopify.com"
Body
Request body
Storefront / personalization event ingestion. Shop is taken from the x-shop header (not the body). Requires channel and at least one of visitor_id / client_id.
Originating storefront channel.
HYDROGEN, HEADLESS, MOBILE The event envelope.
Show child attributes
Show child attributes
Browsing-session id (the unit of funnel + attribution analytics). Optional; the server generates a uuid when absent, but send a stable one per visit for accurate analytics.
Anonymous persistent visitor UID. At least one of visitor_id / client_id is required.
Client/device id (persists across sessions). At least one of visitor_id / client_id is required.
Shopify customer id when logged in.
Page type the event fired from.
URL the event fired from.
Cart token/key identifier.
Cart state at event time.
Customer info at event time.
Customer consent flags.
Show child attributes
Show child attributes
Response
Event accepted
Event ingestion acknowledgement.
Indicates the event was accepted.
true Was this page helpful?