Tracking events
There are two ways to track data: Through front-end or back-end.Front-end means that you will use a tracking pixel on your website. Back-end means you use server to server communication to track your data via our API.
The goal is to send events to us with user behavior, so we can create segments that you can use on the connected channels.
This integration guide will help you set up the event tracking.
Front-end tracking
Almost all tracking will be done through front-end.Place the following personalized code snippet in the head section of every page you want to use tracking on.
NOTE: Please log in to see your personalized snippet.
<script type="text/javascript">
(function(s,q,z,l,y){s._sqzl=s._sqzl||[];l=q.createElement('script'),
y=q.getElementsByTagName('script')[0];l.async=1;l.type='text/javascript';
l.defer=true;l.src=z;y.parentNode.insertBefore(l,y)})
(window,document,'https://squeezely.tech/tracker//sqzl.js');
</script>
Tracking events
You can track Standard Events or Custom Events.For example. if you want to track a pageview through the standard PageView event, use the following code:
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "PageView"
});
</script>
That's all, your visitors are now being tracked!
The more info we have the better your segments will be. To provide more data, use the available properties as shown in the documentation of the event.
Another example: Track a Purchase event:
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "Purchase",
"email" : "jan@schmit.com",
"firstname" : "Jan",
"lastname" : "Schmidt",
"gender" : "M",
"birthdate" : "1985-12-31",
"city" : "Berlin",
"country" : "DE",
"orderid" : "12345",
"currency" : "EUR",
"products" : [{
"id": "ABC123",
"name": "Product 1",
"price": 29.99,
"quantity": 2
}]
});
</script>
All events work this way, you can track as many events on a page as you want. Please refer to the event specific documentation (found in the menu on the left) to find out which events and properties are supported.
Managing visitor consent
By default all tracking pixels are sent immediately. It is possible however to give customers more control. You can implement your own privacy policy by implementing custom pixel consent.Enabling custom pixel consent:
- Implement reject & grant consent as shown below.
- Enable the Custom consent management setting in the settings panel.
NOTE: Pixels will stop being sent by default after enabling the Custom consent management setting.
Please enable this option after you have implemented the consent constols shown in code below.
Please enable this option after you have implemented the consent constols shown in code below.
Granting all permissions:
<script type="text/javascript">
_sqzl.push({
"consent": "grant"
});
</script>
Granting only specific permissions:
<script type="text/javascript">
_sqzl.push({
"consent": "grant",
"permissions": [
"analytics"
]
});
</script>
Revoking all permissions:
<script type="text/javascript">
_sqzl.push({
"consent": "revoke"
});
</script>
Revoking only specific permissions:
<script type="text/javascript">
_sqzl.push({
"consent": "revoke",
"permissions": [
"marketing"
]
});
</script>
Pixels sent while permission is revoked will be queued. All events in the queue will be sent as soon as permission is granted again.
NOTE: Consent has to be set on every page. This is not a setting that will be stored in a cookie.
NOTE: Queued pixels are lost as soon as a customer reloads or leaves the page. Any unsent pixels will not be stored.
Available permissions:
Permission | Description |
---|---|
analytics | Allows 3rd party pixels and cookies for analytical purposes |
marketing | Allows 3rd party pixels and cookies for marketing purposes |
Anonymizing events
By default all data sent to us will be used. It is also possible to anonymize events by enabling the anonymization feature. This will disable the marketing consent, remove any fields containing personal information and anonymize IP addresses by removing the last octet before it is forwarded.Enabling the anonymization feature:
<script type="text/javascript">
_sqzl.push({
"anonymize": "yes"
});
</script>
Disabling the anonymization feature:
<script type="text/javascript">
_sqzl.push({
"anonymize": "no"
});
</script>
NOTE: Anonymization has to be enabled on every page. This is not a setting that will be stored in a cookie.
NOTE: Anonymization has to be enabled before any events are sent to be effective.
Event: PageView
Event should be fired when someone views a page.Note: This event must be implemented on all pages, regardless if other events are triggered.
Available properties:
Name | Description | |
---|---|---|
event | PageView | Mandatory |
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional |
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional |
Event: Purchase
Event should be fired when someone makes a purchase.Available properties:
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
event | Purchase | Mandatory | ||||||||
Customer email or SHA256 of the email | Mandatory | |||||||||
orderid | Order reference of the purchase. Used to calculate revenue correctly. | Mandatory | ||||||||
firstname | Customer first name | Mandatory | ||||||||
lastname | Customer last name | Mandatory | ||||||||
userid | User id or username of the customer. Your unique identifier for the customer. | Optional | ||||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||||
source | Source of the customer (e.g. facebook or adwords). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||||
gender | Customer gender (M/F/U) | Optional | ||||||||
birthdate | Customer birthdate (yyyy-mm-dd) | Optional | ||||||||
phone | Customer phone | Optional | ||||||||
postcode | Customer postcode | Optional | ||||||||
city | Customer city | Optional | ||||||||
country | Customer 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | Optional | ||||||||
currency | Currency of the purchase (e.g. GBP/EUR/USD, ISO 4217) | Optional | ||||||||
newsletter | Has the user opted in for email/newsletter. Correct value are yes or no. If you don't know, don't send this field. | Optional | ||||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Mandatory |
Event: PrePurchase
Fire the PrePurchase event when a user has shared details with you, but still has to confirm the payment.For example fire the event just before a customer is redirected to an external payment environment.
Note: The PrePurchase event is not mandatory, however we highly recommend using it. Implementing this event will give you more accurate sales tracking and more complete profile information.
Available properties:
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
event | PrePurchase | Mandatory | ||||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||||
Customer email or SHA256 of the email | Mandatory | |||||||||
userid | User id or username of the customer. Your unique identifier for the customer. | Optional | ||||||||
firstname | Customer first name | Mandatory | ||||||||
lastname | Customer last name | Mandatory | ||||||||
gender | Customer gender (M/F/U) | Optional | ||||||||
birthdate | Customer birthdate (yyyy-mm-dd) | Optional | ||||||||
phone | Customer phone | Optional | ||||||||
postcode | Customer postcode | Optional | ||||||||
city | Customer city | Optional | ||||||||
country | Customer 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | Optional | ||||||||
orderid | Order reference of the purchase. Used to calculate revenue correctly. | Optional | ||||||||
currency | Currency of the purchase (e.g. GBP/EUR/USD, ISO 4217) | Optional | ||||||||
newsletter | Has the user opted in for email/newsletter. Correct value are yes or no. If you don't know, don't send this field. | Optional | ||||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Optional |
Event: AddToCart
Event should be fired when someone adds something to their cart.Available properties:
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
event | AddToCart | Mandatory | ||||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||||
currency | Currency of the product (e.g. GBP/EUR/USD) | Optional | ||||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Mandatory |
Event: ViewContent
Event should be fired when someone visits a product page on your website.Available properties:
Name | Description | |||||||
---|---|---|---|---|---|---|---|---|
event | ViewContent | Mandatory | ||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||
currency | Currency of the product (e.g. GBP/EUR/USD) | Optional | ||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Mandatory |
Event: ViewCategory
Event should be fired when someone views a category page.Available properties:
Name | Description | |||||||
---|---|---|---|---|---|---|---|---|
event | ViewCategory | Mandatory | ||||||
category_id | Id of the viewed category (e.g. ABC123) | Mandatory | ||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||
source | Source of the customer (e.g. facebook or adwords). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||
objectname | Name of the viewed category | Optional | ||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Optional |
Event: Search
Event should be fired when someone searched for something on your website.Available properties:
Name | Description | |||||||
---|---|---|---|---|---|---|---|---|
event | Search | Mandatory | ||||||
keyword | Search keyword | Mandatory | ||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||
checkin_date | Travel. The check-in date the customer is looking for. (this is only useful when products are added with availability) Format: yyyy-mm-dd | Optional | ||||||
checkout_date | Travel. The check-out date the customer is looking for, we will automatically convert this amount_nights. checkin_date must be supplied! (this is only useful when products are added with availability) Format: yyyy-mm-dd | Optional | ||||||
amount_nights | Travel. The amount of nights the customer wants to stay. (this is only useful when products are added with availability) | Optional | ||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Optional |
Event: Custom PRO
You can add a custom event to target people with certain website behavior.Available properties:
Name | Description | |
---|---|---|
event | Your custom event | Mandatory |
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional |
source | Source of the customer (e.g. facebook or adwords). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional |
value | Value of your custom event | Optional |
Event: Lead
You can add a lead event to target people who sign up.Available properties:
Name | Description | |
---|---|---|
event | Lead | Mandatory |
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional |
source | Source of the customer (e.g. facebook or adwords). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional |
value | Value of your lead event | Optional |
Event: EmailOptIn
Event should be fired when someone subscribes to or unsubscribes from your newsletter, marketing or service e-mails.Available properties:
Name | Description | |
---|---|---|
event | EmailOptIn | Mandatory |
Customer email or SHA256 of the email | Optional | |
newsletter | Is the user opt-in for newsletters. Correct value are yes or no. If you don't know, don't send this field. | Mandatory |
marketing | Is the user opt-in for marketing letters. Correct value are yes or no. If you don't know, don't send this field. | Optional |
service | Is the user opt-in for service messages. Correct value are yes or no. If you don't know, don't send this field. | Optional |
Event: CompleteRegistration
Event should be fired when someone completes a registration/signup form.Available properties:
Name | Description | |
---|---|---|
event | CompleteRegistration | Mandatory |
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you don't have to pass this. Saved in client session. | Optional |
source | Source of the customer (e.g. facebook or adwords). If this is in the url of your landing page as variable sqzl_source or utm_source, you don't have to pass this. Saved in client session. | Optional |
Event: InitiateCheckout
Event should be fired when someone starts the checkout flow.Available properties:
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
event | InitiateCheckout | Mandatory | ||||||||
Customer email or SHA256 of the email | Optional | |||||||||
firstname | Customer first name | Optional | ||||||||
lastname | Customer last name | Optional | ||||||||
userid | User id or username of the customer. Your unique identifier for the customer. | Optional | ||||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional | ||||||||
gender | Customer gender (M/F/U) | Optional | ||||||||
birthdate | Customer birthdate (yyyy-mm-dd) | Optional | ||||||||
phone | Customer phone | Optional | ||||||||
postcode | Customer postcode | Optional | ||||||||
city | Customer city | Optional | ||||||||
country | Customer 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | Optional | ||||||||
currency | Currency of the purchase (e.g. GBP/EUR/USD, ISO 4217) | Optional | ||||||||
newsletter | Has the user opted in for email/newsletter. Correct value are yes or no. If you don't know, don't send this field | Optional | ||||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Mandatory |
Contacts
It is not needed to create new contacts.When an event contains an email address, userid, or cookie we don't know or can't connect to an existing user, we will create a new contact.
If you want to add a contact to Squeezely, but there is no user activity like a PageView, send a CRMUpdate event through our backend(!) API.
Callback
It's possible to add a callback to the frontend tracking pixel.Callback per event
You can set a callback per event send through the frontend tracking pixel. Using the following code:
<script type="text/javascript">
_sqzl.push({
"event" : "PageView",
"callback": function(eventData) {
// This function is called whenever the img pixel is finished
// eventData contains the event Object
}
});
</script>
Callback on all events
It's also possible to hook on all events and register a callback for that. Using the following code:
<script type="text/javascript">
_sqzl.push({
"SetCallback" : function(eventData) {
// This function is called whenever the img pixel is finished
// eventData contains the event Object
}
});
</script>
NOTE: Keep in mind, the callback is fired when the pixel image is finished loading in the browser. This depends heavily on the network speed of the client.
Using the back-end API
This API is meant for server to server HTTP calls.
Authentication
All API endpoints require authentication. Authentication will be performed by checking two values in the HTTP request headers.Header | Description |
---|---|
X-AUTH-ACCOUNT | This is the Account-identifier |
X-AUTH-APIKEY | This is the secret API key. Consider this value as being a password. |
The API key can be found and if so desired, modified in the settings panel.
NOTE: Examples in the documentation will contain the Account-identifier and API key when logged in.
Data formatting
All information sent to the API has to be in either or JavaScript Object Notation (JSON) format or included as HTTP POST parameters. Responses will always be in JSON format. We currently do not support other formats like XML or other methods of serialization.Base API URL
All back-end API endpoints can be reached at https://squeezely.techExample requests
PHP
$url = "https://squeezely.tech/api/v1/<ENDPOINT>";
$fields = [
"some_field" => "some_value"
];
$json = json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-AUTH-ACCOUNT: <ACCOUNT_IDENTIFIER>",
"X-AUTH-APIKEY: <API_KEY>",
"Content-Type: application/json",
"Content-Length: " . strlen($json)
]);
$result = curl_exec($ch);
curl_close($ch);
NOTE: Please log in to see your Account-identifier and API Key.
Response values
When correctly authorized, we will return a JSON response with the result.Example response for a correct call:
{
"success": true,
// ...
"errors": []
}
Example response for an incorrect call:
{
"success": false,
"errors": [
// ...
]
}
NOTE: Please make sure you do not implement any of these server to server endpoints in front-end code. This would be a security issue as authentication headers are included in every request.
Response codes
HTTP status code | Description | Error codes |
---|---|---|
403 | Invalid credentials | MISSING_API_KEY_OR_ACCOUNT INVALID_CREDENTIALS MISSING_ACCOUNT_ACTIVE_USER |
Back-end Tracking
With backend tracking you can send server to server events.
Backend events have the same parameters as frontend events, but also allow you to set the date & time.
You can send up to 250 events at a time. See the PHP example code below:
$url = "https://squeezely.tech/api/v1/track";
$fields = [
"events" => [
[
"event" => "Purchase",
"email" => $email,
"firstname" => $firstname,
"lastname" => $lastname,
"gender" => $order->getCustomerGender(),
"birthdate" => $order->getCustomerDob(),
"phone" => $order->getShippingAddress()->getTelephone(),
"postcode" => $order->getShippingAddress()->getPostcode(),
"city" => $order->getShippingAddress()->getCity(),
"country" => $order->getShippingAddress()->getCountry(),
"currency" => $order->getOrderCurrencyCode(),
"orderid" => $orderId,
"newsletter" => $newsletterOptin ? "yes" : "no",
"marketingletter" => $marketingletterOptin ? "yes" : "no",
"serviceletter" => $serviceletterOptin ? "yes" : "no",
"products" => [
[
"id" => "ABC123",
"name" => "Product 1",
"category_id" => "CAT_1",
"price" => 29.99,
"quantity" => 2
],
[
"id" => "XYZ_789",
"name" => "Product 2",
"category_id" => "CAT_2",
"price" => 39.99,
"quantity" => 1
]
]
]
]
];
$json = json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-AUTH-ACCOUNT: <ACCOUNT_IDENTIFIER>",
"X-AUTH-APIKEY: <API_KEY>",
"Content-Type: application/json",
"Content-Length: " . strlen($json)
]);
$result = curl_exec($ch);
curl_close($ch);
NOTE: Please log in to see your Account-identifier and API Key.
Just replace the values with your values and you're ready to go!Response values
When correctly authorized, we will return a JSON response with the result.API Response when the request has been handled successfully:
{
"success": true,
"count": 12,
"errors": []
}
API Response when the request has not been handled successfully:
{
"success": false,
"count": 0,
"errors": [
"NO_EMAIL_OR_USERID"
]
}
API Response when the request has duplicate events:
{
"success": false,
"count": 0,
"duplicate_count": 1,
"errors": [
"DUPLICATE_EVENT"
]
}
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created (partially) | NO_EMAIL_OR_USERID NO_MERCHANT UNKNOWN_ERRROR |
400 | No resource created | NO_EVENTS TOO_MANY_EVENTS NO_EMAIL_OR_USERID NO_MERCHANT UNKNOWN_ERRROR DUPLICATE_EVENT |
Event: Purchase
Endpoint: /api/v1/trackPOSTEvent should be fired when someone makes a purchase.
Available properties:
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
event | Purchase | Mandatory | ||||||||
Customer email or SHA256 of the email | Mandatory | |||||||||
firstname | Customer first name | Mandatory | ||||||||
lastname | Customer last name | Mandatory | ||||||||
orderid | Order reference of the purchase. Used to calculate revenue correctly. | Mandatory | ||||||||
timestamp | Timestamp of the event, only needed for events in the past. Formats allowed: unix epoch timestamp or yyyy-mm-dd | Optional | ||||||||
userid | User id or username of the customer. Your unique identifier for the customer. | Optional | ||||||||
gender | Customer gender (M/F/U) | Optional | ||||||||
birthdate | Customer birthdate (yyyy-mm-dd) | Optional | ||||||||
phone | Customer phone | Optional | ||||||||
postcode | Customer postcode | Optional | ||||||||
city | Customer city | Optional | ||||||||
country | Customer 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | Optional | ||||||||
currency | Currency of the purchase (e.g. GBP/EUR/USD, ISO 4217) | Optional | ||||||||
newsletter | Has the user opted in for email/newsletter. Correct value are yes or no. If you don't know, don't send this field. | Optional | ||||||||
products |
Array of product(s). Supported properties:
Example 2:
|
Mandatory | ||||||||
campaign | The identifier for this campaign. If this is in the url of your landing page as variable sqzl_campaign or utm_campaign, you can omit this. Saved in client session. | Optional | ||||||||
source | Source of the customer (e.g. facebook or Google Ads). If this is in the url of your landing page as variable sqzl_source or utm_source, you can omit this. Saved in client session. | Optional |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created (partially) | NO_EMAIL_OR_USERID NO_MERCHANT UNKNOWN_ERRROR |
400 | No resource created | NO_EVENTS TOO_MANY_EVENTS NO_EMAIL_OR_USERID NO_MERCHANT UNKNOWN_ERRROR DUPLICATE_EVENT |
Products
Create or update up to 250 products at a time through our API:Endpoint: /api/v1/productsPOST
Name | Description | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
products |
Array of product(s) you want to add/update. Supported properties:
Example success response:
Example error response (2 products with missing title):
Example error response (2 products, 1 with incorrect condition):
|
Mandatory |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | WRONG_CONTENTTYPE, NO_PRODUCTS, TOO_MANY_PRODUCTS, |
Categories
Create or update up to 250 categories at a time through our API:Endpoint: /api/v1/categoriesPOST
Name | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
categories |
Array of categories you want to add/update. Supported properties:
Example success response:
Example error response (2 categories with missing title):
|
Mandatory |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | WRONG_CONTENTTYPE, NO_CATEGORIES, TOO_MANY_CATEGORIES, |
Reporting
You can the export data you collected with Squeezely.Call the resource endpoint and we will generate a CSV file.
Optionally you can supply a callback url which we call when the file is generated.
CSV files are purged after 7 days.
Example request:
$url = "https://api.squeezely.tech/v1/reporting/events";
$fields = [
"from" => "2018-01-01",
"to" => "2018-02-01"
];
$json = json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-AUTH-ACCOUNT: <ACCOUNT_IDENTIFIER>",
"X-AUTH-APIKEY: <API_KEY>",
"Content-Type: application/json",
"Content-Length: " . strlen($json)
]);
$result = curl_exec($ch);
curl_close($ch);
Example response:{
"success": true,
"url": "https://api.squeezely.tech/v1/reporting/download/cf2acd31eac8c5288f05dd6366dc1e4f.csv"
}
Available reports
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, UNKNOWN_ERROR |
Events export
Endpoint: /api/v1/reporting/eventsPOSTYou can use these filters:
Name | Description | |
---|---|---|
from | YYYY-mm-dd or Unix epoch timestamp. | Mandatory |
to | YYYY-mm-dd or Unix epoch timestamp. | Mandatory |
custom_fields | Whether to export custom fields. Correct value are yes (default) or no. | Optional |
callback_url | URL we call once when the file is available for download. | Optional |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, NO_JSON_PARAMETER_SUPPORT, NO_DATE_RANGE_PROVIDED, INVALID_FROM_DATE, INVALID_TO_DATE, UNKNOWN_ERROR |
CSV content
NOTE: The field order is not guaranteed. Please map to the correct fields by using the field names in the first row of the CSV file.
The following fields can be expected in a report after it has been generated and downloaded:
Field name | Description | |
---|---|---|
id | Unique identifier for this event | |
event | Event name or Unknown if not known | |
created_at | Event date & time (e.g. yyyy-mm-dd HH:ii:ss) | |
platform | The platform. (e.g. android, ios, iphone, ipad, mac, unix, widows) | |
url | The URL the event was triggered on | |
source | The source sent with the event. (e.g. facebook) | |
api | This event was received via our API. Values: 0 or 1 | |
cookie | A string value that identifies a contact | |
customer_id | Unique identifier for this contact | |
userid | Your unique user identifier | |
Contact email | ||
firstname | Contact first name | |
lastname | Contact last name | |
gender | Contact gender. Value as sent in the event. | |
birthdate | Contact birthdate (yyyy-mm-dd, 0000-00-00 if unknown) | |
phone | Contact phone | |
city | Contact city | |
country | Contact country | |
offlinelocation | A location if a purchase was done offline | |
totalvalue | Total value of a purchase | |
products | JSON array of product(s) | |
category_id | Id of a viewed category (e.g. ABC123) | |
objectname | Name of the viewed category | |
currency | Currency of the contact (e.g. GBP/EUR/USD) | |
orderid | The order id | |
utm_campaign | The event UTM campaign | |
utm_source | The event UTM source | |
sqzl_campaign | The event squeezely campaign | |
sqzl_source | The event squeezely source | |
keyword | The keyword received in the event | |
value | The value of a custom event | |
ip | The IP address the event was received from | |
custom_fields | JSON array of custom fields | |
device | The contact's device type. Values: mobile, desktop |
Contacts export
Endpoint: /api/v1/reporting/contactsPOSTYou can use these filters:
Name | Description | |
---|---|---|
userids | Comma separated list of your unique user identifier(s) of the contacts you want to select. | Optional |
emails | Comma separated list of emails of the contacts you want to select. | Optional |
custom_fields | Whether to export custom fields. Correct value are yes (default) or no. | Optional |
callback_url | URL we call once when the file is available for download. | Optional |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, NO_JSON_PARAMETER_SUPPORT, UNKNOWN_ERROR |
CSV content
NOTE: The field order is not guaranteed. Please map to the correct fields by using the field names in the first row of the CSV file.
The following fields can be expected in a report after it has been generated and downloaded:
Field name | Description | |
---|---|---|
id | Unique identifier for this contact | |
userid | Your unique user identifier | |
cookie | Contact cookie | |
Contact email | ||
email_hash | A sha256 hash of the email Please replace this field with the new emailhash field |
Deprecated |
firstname | Contact first name | |
lastname | Contact last name | |
gender | Contact gender (M/F/U) | |
birthdate | Contact birthdate (yyyy-mm-dd) | |
phone | Contact phone | |
zipcode | Contact zipcode | |
city | Contact phone | |
country | Contact 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | |
currency | Currency of the contact (e.g. GBP/EUR/USD) | |
optin | Has the contact opted in for newsletters. Values: yes or no. Please replace this field with the new newsletter field |
Deprecated |
emailhash | A sha256 hash of the email | |
newsletter | Has the contact opted in for newsletters. Values: yes or no. | |
marketing | Has the contact opted in for marketing emails. Values: yes or no. | |
service | Is the user opt-in for service emails. Values: yes or no. |
Download an export
Endpoint: /api/v1/reporting/download/XXX.csvGETUse this endpoint to download a previously created report.
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
404 | Resource not available | RESOURCE_NOT_FOUND, RESOURCE_NOT_READY, RESOURCE_EXPIRED |
Privacy requests
Conforming with the European General Data Protection Regulation law, known as GDPR has become mandatory.By implementing this server to server API endpoint it is possible to give customers a custom experience when giving insight to the personal information that has been stored. Implementing all features of this endpoint will give customers the opportunity to view, change or delete personal information.
Flow
Privacy requests work as follows:- Request profiles for a specific customer.
- After the request has been handled you will receive a callback containing the profiles that have been found and the personal information contained within them.
- Present the data to the customer and/or provide a way to change data for each profile.
- Delete or modify the profile when required.
Implementation
Step 1: Requesting profiles matching a cookie or e-mail address for a customerEndpoint: /api/v1/privacy/requestPOST
Searching for profiles by e-mail:
{
"callback_url": "https://example.com",
"email": "example@example.com"
}
Searching for profiles by cookie:
{
"callback_url": "https://example.com",
"cookie": "<COOKIE_IDENTIFIER>"
}
Searching for profiles by email_hash (sha256 of the email):
{
"callback_url": "https://example.com",
"email_hash": "31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66"
}
API Response:
{
"success": true,
"callbackHash": "<CALLBACK_HASH>"
}
Step 2: Receiving the profiles on the specified callback URL
After processing the request the callback URL will receive a HTTP POST request with a JSON formatted string containing the profiles as payload.
{
"callbackHash": "<CALLBACK_HASH>",
"profiles": [
{
"profileHash": "<PROFILE_HASH>",
"entities": {
"12344": {
"firstname": "Fist",
"lastname": "Last",
"gender": "m",
"zipcode": "1234AB",
"city": "Amsterdam",
"country": "nl",
"phone": "+31612345678",
"email": "example@example.com",
"birthdate" => "1970-01-01",
"updated_at": "1970-01-01 01:00:00"
}
}
}
]
}
Step 3: Changing fields in user profiles, or deleting them
NOTE: The profile hashes could differ from the callback hash received when creating the privacy request. Please always use the profile hashes received in the callback payload.
NOTE: The callback & profile hashes are always 64 character strings.
Deleting a profile
Endpoint: /api/v1/privacy/request/{PROFILE_HASH}DELETE
{}
API Response:
{
"success": true
}
Modifying a profile
Endpoint: /api/v1/privacy/request/{PROFILE_HASH}PATCH
{
"entities": {
"12345": {
"firstname": "New first name",
"lastname": "New last name",
"gender": "f",
"zipcode": "",
"city": "",
"country": "",
"phone": "",
"email": "example@example.com"
}
}
}
API Response when the request has been handled successfully:
{
"success": true
}
API Response when the request has not been handled successfully:
{
"success": false,
"errors": {
"INVALID_TEXT_FIELD_VALUE": {
"entities": {
"12345": {
"fields": {
"firstname": "Maximum length of 255 exceeded"
}
}
}
},
"INVALID_DATE_FIELD_VALUE": {
"entities": {
"12345": {
"fields": {
"custom_date_field": "Unrecognized date format"
}
}
}
},
"INVALID_NUMERIC_FIELD_VALUE": {
"entities": {
"12345": {
"fields": {
"custom_numeric_field": "Numeric value out of range (-99999.99999 to 99999.99999)"
}
}
}
}
}
}
Error codes for PATCH requests:
Error codes | Description |
---|---|
NO_FIELDS_TO_UPDATE_SPECIFIED | A profile was detected without any specified fields |
INVALID_FIELDS_SPECIFIED | One or more specified fields do not extist |
INVALID_TEXT_FIELD_VALUE | A textual string has a maximum size of 255 characters |
INVALID_NUMERIC_FIELD_VALUE | Numerical fields have a range and precision of -99999.99999 to 99999.99999 |
INVALID_DATE_FIELD_VALUE | Dates should be specified in unix epoch timestamps or yyyy-mm-dd format |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
202 | Request was received, please wait for the callback | |
400 |
|
MISSING_IDENTIFIER IDENTIFIER_AMBIGUOUS MISSING_CALLBACK_URL CALLBACK_URL_NOT_SECURE NO_PROFILES_TO_MODIFY |
404 |
|
MISSING_PROFILE_HASH INVALID_PROFILE_HASH |
Contacts
It is not needed to create new contacts.When an event contains an email address, userid, or cookie we don't know or can't connect to an existing user, we will create a new contact.
If you want to add a contact to Squeezely, but there is no user activity like a PageView, send a CRMUpdate event through our backend(!) API.
Webhooks
You can use webhooks to get data or events from Squeezely to somewhere else.For example, a webhook can be fired whenever someone unsubscribes from a newsletter list.
You can configure webhooks in the Squeezely interface.
Implementation examples on your webserver.
PHP
// Example of parsing a application/x-form-urlencoded type webhook
$data = $_POST;
// Example of parsing a application/json type webhook
$data = json_decode(file_get_contents('php://input'), true);
// Example of parsing a GET request type webhook:
parse_str($_SERVER['QUERY_STRING'], $data);
// Squeezely will provide a signature for security
$signature = $_SERVER['HTTP_X_SQUEEZELY_SIGNATURE'];
Security
We highly recommend to always verify the origin of received webhook callbacks.Please read the documentation specific to verifying the origin of our webhooks.
Webhooks security
It is always a good idea to verify the origin of our webhook callbacks for security reasons.Verification of provided signature
We send a signature along with every webhook call, contained in the HTTP request headers.X-Squeezely-Signature: NzUxNzBmYzIzMGNkODhmMzJlNDc1ZmY0MDg3ZjgxZDk=
To validate this signature you need a private key, which you should handle like being a password. We use this key to generate a string, a base64 encoded binary representation HMAC hash.
Verifying the signature can be done as follows:
-
Creating the formatted data:
-
Form URL encoded callback:
- Take all received data, in order it was received.
- JSON encode the data.
-
Callback with raw JSON body:
- Take all data in the message body as a JSON encoded string.
-
Form URL encoded callback:
- Create a binary representation of a HMAC hash by using the data from step 1, the `Webhook Key` using the SHA256 algorithm.
- Base64 encode the bytes obtained in the previous step.
-
Compare the created hash with the hash obtained from the HTTP request headers. If they are equal the origin is confirmed.
Implementation examples
PHP
/**
* Verify a squeezely webhook signature
*
* @param string $secretKey The secret key
* @param string $data Contains a JSON string of all data received in the webhook callback
* @param string $signature The HMAC signature sent in the HTTP request header `X-Squeezely-Signature`
*
* @return bool Whether the message has been verified
*/
function validSqueezelyWebhook(string $secretKey, string $data, string $signature): bool {
if(version_compare(PHP_VERSION, "7.2.0") >= 0 && !in_array("sha256", hash_hmac_algos())) {
throw new Exception("sha256 no longer supported");
}
$calculatedSignature = base64_encode(hash_hmac("sha256", $data, $secretKey, true));
// Preventing timing attacks by using timing attack safe string comparison
return hash_equals($signature, $calculatedSignature);
}
// Full usage example using an application/json formatted callback
$signature = $_SERVER["HTTP_X_SQUEEZELY_SIGNATURE"];
$rawData = file_get_contents("php://input");
if(!validSqueezelyWebhook("SECRET_KEY", $data, $signature)) {
// The message has not been validated
exit;
}
// You can now use the contents of the callback
$data = json_decode($rawData, true);
Products
Product feed
Setting your feed up is not a difficult process.Make sure there is a feed available with products and categories. Categories are optional.
The feed can be in xml or json format and should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<products>
<product>
<name>Product X</name>
<description>Product X description</description>
<price>19.99</price>
<currency>EUR</currency>
<availability>in stock</availability>
<image>http://www.yourstore.com/productx.jpg</image>
<url>http://www.yourstore.com/productx</url>
<inventory>24</inventory>
<condition>new</condition>
<brand>Brand Y</brand>
<product_id>PR00019X</product_id>
<category_ids>["1234","1235"]</category_ids>
<parent_id>ABC123</parent_id>
</product>
...
</products>
<categories>
<category>
<name>Category X</name>
<description>Category X description</description>
<url>http://www.yourstore.com/categoryx</url>
<category_id>1234</category_id>
</category>
...
</categories>
</data>
Products property description:
property | description |
---|---|
name | Name of the product |
description | Description of the product |
price | Price in decimals (no thousand separator, dot for decimal separator). Example: 1345.50 |
currency | Currency (EUR/USD/GBP) |
availability | in stock, out of stock or available for order |
image | URL of the main image of the product |
url | URL of the product |
inventory | Amount of products in stock |
condition | new or used |
brand | Brand of the product |
product_id | SKU or EAN you communicate with your customers. This needs to be unique. |
category_ids | Categories that have this product. JSON list of category ids. |
parent_id | Products with the same parent id will be grouped as variants in your feed |
Category property description:
property | description |
---|---|
name | Name of the category |
description | Description of the category |
url | Url of the category |
category_id | SKU or your internal category id or reference. Mandatory Unique. |
Feed documentation
Looking for the old version of the feed? It's here!
With a feed you can easily keep your product data in sync.The feed should be formatted in either XML RSS 2.0 or ATOM 1.0 format. The Squeezely feed also supports Google Merchant Center Product Data feeds.
Supported properties
The following fields are supported in the feed.
property | description | |
---|---|---|
id | The unique product ID (SKU or EAN) | Mandatory |
title | Name of the product | Mandatory |
link | URL of the product | Mandatory |
description | Description of the product | |
price | The price and currency of the product (EUR/USD/GBP). Price in decimals (no thousand separator, dot for decimal separator). Example: 1345.50 EUR | |
availability | in stock (default), out of stock, available for order, preorder | |
image_link | URL of the main image of the product. Minimal 600x600 pixels, preferably square. | |
image_links |
Supply up to 20 images for your product. (Overwrites image_link field). List of <image_link> elements containing an url. |
|
condition | Condition of the product, new (default), used, refurbished. | |
inventory | Amount of products in stock | |
brand | Brand of the product | |
language | 2-letter language code. (EN,DE,ES,FR,NL,NO,PL,TR,JP), contact for more. Default: EN. | |
parent_id | Products with the same parent id will be grouped as variants in your catalog. | |
category_ids | Categories that have this product. List of <category_id> elements containing an id. | |
google_product_category |
Include either numerical category ID (preferred) or the full path of the Google category.
Please refer to the Google Product Taxonomy documentation. |
|
date_availability | Availablity for travel, see more. Array of all current product date availabilities (max 180 days), previously supplied availability will be erased.
|
Note on google_product_category
The Google Product Taxonomy Supports either numerical category identifiers, or a string containing the entire path of the category. Our platform needs to convert these to a consistent single format. For this we use the numerical category identifier.It is important when using the full textual category paths to select the correct category path naming language. This way our platform can convert those to numerical ones. Currently Google supports the following unique languages:
Categories and Languages
A feed contains products of 1 language.You can create your own categories, or you can use the google categories.
Supported properties for categories
property | description |
---|---|
title | Title of the category |
description | Description of the category |
url | Url of the category |
category_id | SKU or your internal category id or reference. Mandatory Unique |
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title>Example - Online Store</title>
<link rel="self" href="http://www.example.com"/>
<updated>2011-07-11T12:00:00Z</updated>
<item>
<g:id>TV_123456</g:id>
<g:title>LG 22LB4510 - 22" LED TV - 1080p (FullHD)</g:title>
<g:link>http://www.example.com/electronics/tv/22LB4510.html</g:link>
<g:image_link>http://images.example.com/TV_123456.png</g:image_link>
<g:google_category_id>404</g:google_category_id>
</item>
<item>
<g:id>TV_123456</g:id>
<g:title>LG 22LB4512 - 24" LED TV - 1080p (FullHD)</g:title>
<g:link>http://www.example.com/electronics/tv/22LB4512.html</g:link>
<g:image_links>
<g:image_link>http://images.example.com/CLO-1029384-1.jpg</g:image_link>
<g:image_link>http://images.example.com/CLO-1029384-2.jpg</g:image_link>
</g:image_links>
<g:category_ids>
<g:category_id>TV-1234</g:category_id>
<g:category_id>TV-4321</g:category_id>
</g:category_ids>
</item>
<category>
<g:id>TV-1234</g:id>
<g:title>TV's 22"</g:title>
<g:description>Only the best TV's 22"</g:description>
<g:link>http://www.example.com/tvs/22</g:link>
</category>
<category>
<g:id>TV-4321</g:id>
<g:title>TV's 24"</g:title>
</category>
</channel>
</rss>
Below an example of an RSS feed for travel including availability options
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title>Example - Online Hotel</title>
<link rel="self" href="http://www.example.com"/>
<updated>2011-07-11T12:00:00Z</updated>
<item>
<g:id>NL_ZH_DH_HOTEL_X</g:id>
<g:title>Hotel The Hague</g:title>
<g:link>http://www.example.com/nl/zh/hotel_the_hague.html</g:link>
<g:image_link>http://images.example.com/HOTEL_X.png</g:image_link>
<g:google_category_id>404</g:google_category_id>
<g:date_availability>
<g:availability>
<g:checkin>2019-09-11</g:checkin>
<g:nights>1</g:nights>
<g:price>1</g:price>
</g:availability>
</g:date_availability>
</item>
<category>
<g:id>404</g:id>
<g:title>Hotels</g:title>
</category>
</channel>
</rss>
Using Google categories
Language | Identifier | Google category list |
---|---|---|
Deutsch | de-DE | Open list |
English (United Kingdom) | en-GB | Open list |
English | en-US | Open list |
español (Latinoamérica) | es-ES | Open list |
français | fr-FR | Open list |
Nederlands | nl-NL | Open list |
norsk | no-NO | Open list |
polski | pl-PL | Open list |
Türkçe | tr-TR | Open list |
日本語 | ja-JP | Open list |
More information on Google feeds
Please refer to the Google Merchant Center Product data specification documentation for more details about the specific feed specifications, and example files.Validating feeds
The feed validator tool can help with creating and debugging compatible feeds. Please log in to make use of the feed validator.Product availability
You can match a visitor's search timeframe with the availability of your products, hotel rooms, etc.To do this we need to know which date(s) a visitor is searching for. Supply this info with the Search event (or any other event). See the documentation here:
Search event - documentation
We also need to know the availability of your products. You can supply dates and availability on those days for the upcoming 180 days.
You can find information on how to do this in the feed documentation:
Product feed - documentation
Now you can make a product set with the type Recommended for Travel. This dynamic product set will contain products that we recommend to the current visitor and that are available in the entire searched period.
DataLayer documentation
Squeezely can push data to the DataLayer for you.If you are not familiar with DataLayer, please read this article.
Product Sets
Below an example of Product Set data we can push.Note: You need to enable the "Expose to Datalayer" option in the Product Set.
{
'event': 'sqzl_productset',
'product_set_id': 123,
'product_set_data': [
{
'id': 'TV-123',
'name': 'Tv 22 inch',
'description': 'description',
'image': 'http:..',
'image_square': 'http:..',
'url': 'http:..',
'price': 1299.99
'currency_sign': '$',
'inventory': 24,
'condition': 'new',
'availability': 'in stock',
'language': 'EN',
'brand': 'Sony',
'parent_id': 'TV',
}
]
}
Audiences
To get the audiences a visitor is currently in, please see the following DataLayer event.
{
'event': 'sqzl_customer_audiences',
'audience': [
199123,
256623,
..
]
}
Website Personalization
To get information about Website Personalization views or clicks, we provide the next data in the DataLayer.Personalization view
This event is triggered when an variant (overlay/HTML insert) is triggered and displayed.
Note: The control_variant attribute is only provided when control group variant is triggered. Control groups don't see a variant, but this event is triggered for statistical purposes.
{
'event': 'sqzl_PersonalizationView',
'personalization_id': '123',
'personalization_variant_id': '10', // or 'control' when it's a control group
'control_variant': true // optional
}
Personalization click
This event is triggered when a visitor clicks on any link in the personalization variant.
{
'event': 'sqzl_PersonalizationClick',
'personalization_id': '123',
'personalization_variant_id': '10',
}
If someone clicks on a product and the product information is available, additional product fields are added to the event.
{
'event': 'sqzl_PersonalizationClick',
'personalization_id': '123',
'personalization_variant_id': '10',
'product_id': '123',
'product_title': 'Product title',
'product_price': '112.00', // price, without currency sign
'product_position': 3, // position of the product in the list,
}
Personalization documentation
The Squeezely Website Personalization will work immediately after installing the Frontend-tracking pixel.Anti-flicker snippet
Sometimes you notice a page flicker when configuring a HTML insert. The reason is, our frontend-pixel is loaded later in your HTML code, hence the delay before the HTML is inserted.We've built a small anti-flicker snippet which you must install as high as possible in the <head> of your website.
<script async type="text/javascript" src="https://squeezely.tech/p?hqs=1&m="></script>
It's advisable to not remove the async attribute, to avoid any page rendering issues in case of network problems.