Introduction
This documentation provides an overview on how to programmatically interact with Squeezely.
It describes how to get data in and out of Squeezely, and how to integrate Squeezely in your website.
If you havea any questions, don't hesitate to contact us!
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" : "john@website.com",
"firstname" : "John",
"lastname" : "Schmidt",
"gender" : "M",
"birthdate" : "1985-12-31",
"city" : "Amsterdam",
"country" : "NL",
"orderid" : "12345",
"currency" : "EUR",
"mobile_advertiser_id" : "123456789",
"products" : [{
"id": "ABC123",
"language": "nl-NL",
"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.
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 |
Logging revoked consent
Revoking cookie consent will, by default, not send a pixel event. Enrich your customer's 360° Profiles with the revoke event in the consent log by adding the `user_interaction` property to the event.
<script type="text/javascript">
_sqzl.push({
"consent": "revoke",
"user_interaction": true,
"permissions": [
"marketing"
]
});
</script>
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 |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "PageView"
});
</script>
|
Event: Purchase
Event should be fired when someone makes a purchase.
Available properties:
Name |
Description |
|
event |
Purchase |
Mandatory |
email |
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 |
mobile_advertiser_id |
Mobile device id or IDFA. |
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 newsletters? Send value yes. Leave blank in all other scenarios. Looking for a way to manage opt out? See EmailOptIn. |
Optional |
totalvalue |
Total value of the purchase, 2 decimals. If sent, this will override the total value calculated based on the products field. |
Optional |
checkin_date |
Travel. The check-in date of the customer. Send either checkout_date or amount_nights in combination with this field. Format: yyyy-mm-dd |
Optional |
checkout_date |
Travel. The check-out date of the customer. Send checkin_date together with this field. Format: yyyy-mm-dd |
Optional |
amount_nights |
Travel. The amount of nights the customer wants to stay. Send checkin_date together with this field. |
Optional |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
quantity |
Quantity bought. Defaults to 1. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99,
"quantity": 2
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"quantity": 1,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Mandatory |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "Purchase",
"email" : "john@website.com",
"firstname" : "John",
"lastname" : "Schmidt",
"gender" : "M",
"birthdate" : "1985-12-31",
"city" : "Amsterdam",
"country" : "NL",
"orderid" : "12345",
"currency" : "EUR",
"mobile_advertiser_id" : "123456789",
"products" : [{
"id": "ABC123",
"language": "nl-NL",
"name": "Product 1",
"price": 29.99,
"quantity": 2
}]
});
</script>
|
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 order attribution and more complete profile information.
Available properties:
Name |
Description |
|
event |
PrePurchase |
Mandatory |
email |
Customer email or SHA256 of the email |
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 |
userid |
User id or username of the customer. Your unique identifier for the customer. |
Optional |
firstname |
Customer first name |
Optional |
lastname |
Customer last name |
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 |
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:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
quantity |
Quantity bought. Defaults to 1. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99,
"quantity": 2
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"quantity": 1,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Optional |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "PrePurchase",
"email" : "john@website.com"
});
</script>
|
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 |
set_cart |
When set to true: product sets with AddToCart event will be set to contain the products passed along in this event. |
Optional |
checkin_date |
Travel. The check-in date of the customer. Send either checkout_date or amount_nights in combination with this field. Format: yyyy-mm-dd |
Optional |
checkout_date |
Travel. The check-out date of the customer. Send checkin_date together with this field. Format: yyyy-mm-dd |
Optional |
amount_nights |
Travel. The amount of nights the customer wants to stay. Send checkin_date together with this field. |
Optional |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
quantity |
Quantity bought. Defaults to 1. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99,
"quantity": 2
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"quantity": 1,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Mandatory |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "AddToCart",
"products" : [{
"id": "ABC123",
"language": "nl-NL",
"name": "Product 1",
"price": 29.99,
"quantity": 2
}]
});
</script>
|
Event: RemoveFromCart
Event can be fired when someone removes a product from their cart completely.
Using this event it is possible to remove products from personalized product sets that use the
AddToCart event.
Available properties:
Name |
Description |
|
event |
RemoveFromCart |
Mandatory |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
Example:
[{"id": "ABC123"}]
|
Mandatory |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "RemoveFromCart",
"products" : [{
"id": "ABC123"
}]
});
</script>
|
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 |
category_id |
Id of the viewed category (e.g. ABC123) |
Optional |
checkin_date |
Travel. The check-in date of the customer. Send either checkout_date or amount_nights in combination with this field. Format: yyyy-mm-dd |
Optional |
checkout_date |
Travel. The check-out date of the customer. Send checkin_date together with this field. Format: yyyy-mm-dd |
Optional |
amount_nights |
Travel. The amount of nights the customer wants to stay. Send checkin_date together with this field. |
Optional |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Mandatory |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "ViewContent",
"products" : [{
"id": "ABC123",
"language": "nl-NL",
"name": "Product 1",
"price": 29.99
}]
});
</script>
|
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 |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "ViewCategory",
"category_id" : "CAT-123"
});
</script>
|
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 of the customer. Send either checkout_date or amount_nights in combination with this field. Format: yyyy-mm-dd |
Optional |
checkout_date |
Travel. The check-out date of the customer. Send checkin_date together with this field. Format: yyyy-mm-dd |
Optional |
amount_nights |
Travel. The amount of nights the customer wants to stay. Send checkin_date together with this field. |
Optional |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Optional |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "Search",
"keyword" : "sneakers"
});
</script>
|
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 |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "MyCustomEvent",
"value" : 99
});
</script>
|
Event: Lead
You can add a lead event to target people who sign up.
Available properties:
Name |
Description |
|
event |
Lead |
Mandatory |
email |
Customer email or SHA256 of the email |
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 |
value |
Value of your lead event |
Optional |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "Lead",
"value" : 99
});
</script>
|
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 |
email |
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 |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "EmailOptIn",
"email" : "john@website.com",
"newsletter" : "yes",
"marketing" : "no",
"service" : "yes"
});
</script>
|
Event: CompleteRegistration
Event should be fired when someone completes a registration/signup form.
Available properties:
Name |
Description |
|
event |
CompleteRegistration |
Mandatory |
email |
Customer email or SHA256 of the email |
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 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 |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "CompleteRegistration",
"email" : "john@website.com"
});
</script>
|
Event: InitiateCheckout
Event should be fired when someone starts the checkout flow.
Available properties:
Name |
Description |
|
event |
InitiateCheckout |
Mandatory |
email |
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 |
checkin_date |
Travel. The check-in date of the customer. Send either checkout_date or amount_nights in combination with this field. Format: yyyy-mm-dd |
Optional |
checkout_date |
Travel. The check-out date of the customer. Send checkin_date together with this field. Format: yyyy-mm-dd |
Optional |
amount_nights |
Travel. The amount of nights the customer wants to stay. Send checkin_date together with this field. |
Optional |
products |
JSON array of product(s). Supported properties:
id |
Unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
Name of the product. |
price |
Price of the single product, 2 decimals. |
quantity |
Quantity bought. Defaults to 1. |
category_ids |
JSON array of categories. |
Example 1:
[{"id": "ABC123"}]
Example 2:
[
{
"id": "ABC123",
"language": "de-DE",
"name": "Produkt 1",
"price": 29.99,
"quantity": 2
},
{
"id": "XYZ_789",
"language": "en-US",
"name": "Product 2",
"price": 39.99,
"quantity": 1,
"category_ids": ["ZYX", "ABC1"]
}
]
|
Optional |
Example
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "InitiateCheckout",
"products" : [{
"id": "ABC123",
"language": "nl-NL",
"name": "Product 1",
"price": 29.99,
"quantity": 2
}]
});
</script>
|
Collections
Collections are a type of archive on a customer level.
It allows you to save data on a customer without the need of creating custom fields.
You can make collections available in personalization and export them to supporting platforms.
Pass collections as JSON with any event. An example:
window._sqzl.push({
"event" : "PageView",
"collections" : {
"customer_settings": {
"customer_colors": {
"customer_color_1": "red",
"customer_color_2": "blue",
},
"customer_favorite_colors": ["red", "blue", "yellow"],
"current_color": "red"
}
}
});
The default behavior is to merge the collections from the event with those already known for the customer.
For example you can add a value to a known collection main key (
customer_settings) and sub key (
customer_favorite_colors) like this:
window._sqzl.push({
"event" : "PageView",
"collections" : {
"customer_settings": {
"customer_favorite_colors": ["violet"]
}
}
});
The collection with sub key
customer_favorite_colors now has the values
red,
blue,
yellow and
violet.
If you want to set the favorite colors to only violet, you can set it like this:
window._sqzl.push({
"event" : "PageView",
"collections" : {
"customer_settings": {
"customer_favorite_colors": ["violet"]
}
},
"collections_action" : "set"
});
You can completely remove a collection sub key by setting the value to
null:
window._sqzl.push({
"event" : "PageView",
"collections" : {
"customer_settings": {
"customer_colors": null,
"current_color" : null
}
}
});
The collection for this user now only has 1 entry with the key
customer_favorite_colors.
Note:
- A collection entry needs to have a toplevel key (not a number)
- Collections can be multiple levels deep.
- A collection can be max 1MB in size.
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.tech
Example requests
PHP
$url = "https://api.squeezely.tech/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.
Rate limiting
API requests are limited to 250 request per minute, the limit is lifted every minute at 00 seconds.
When the limit is hit a message with error code RATE_LIMIT will be returned, your request will not be processed.
In every API request a response header:
sq-requests-remaining will be included with the remaining requests for that minute.
Response codes
HTTP status code |
Description |
Error codes |
403 |
Invalid credentials |
MISSING_API_KEY_OR_ACCOUNT INVALID_CREDENTIALS MISSING_ACCOUNT_ACTIVE_USER |
429 |
Too many requests |
RATE_LIMIT |
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://api.squeezely.tech/v1/track";
$fields = [
"events" => [
[
"event" => "Purchase",
"email" => $email,
"firstname" => $firstname,
"lastname" => $lastname,
"mobile_advertiser_id" => $mobileAdvertiserId,
"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",
"marketing" => $marketingOptin ? "yes" : "no",
"service" => $serviceOptin ? "yes" : "no",
"products" => [
[
"id" => "ABC123",
"name" => "Product 1",
"category_ids" => ["CAT_1", "CAT_2"],
"price" => 29.99,
"quantity" => 2
],
[
"id" => "XYZ_789",
"name" => "Product 2",
"category_ids" => ["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:
/v1/trackPOST
Event should be fired when someone makes a purchase.
Available properties:
Name |
Description |
|
event |
Purchase |
Mandatory |
email |
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 |
totalvalue |
Total value of the purchase, 2 decimals. If sent, this will override the total value calculated based on the products field. |
Optional |
products |
Array of product(s). Supported properties:
id |
unique id or SKU. Mandatory |
language |
Language of the page that the product was viewed in. Recommended
E.g. en-US (ISO-639 + ISO-3166) |
name |
name of the product |
price |
Price of the single product, 2 decimals. Mandatory |
quantity |
Quantity bought. Defaults to 1. |
category_ids |
JSON array of categories. |
Example 1:
["id" => "ABC123", "price" => 29.99]
Example 2:
[
[
"id" => "ABC123",
"language": "nl-NL",
"name" => "Product 1",
"price" => 29.99,
"quantity" => 2
],
[
"id" => "XYZ_789",
"language": "es-ES",
"name" => "Product 2",
"price" => 39.99,
"quantity" => 1
]
]
|
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 |
Example
$url = "https://api.squeezely.tech/v1/track";
$fields = [
"events" => [
[
"event" => "Purchase",
"email" => $email,
"firstname" => $firstname,
"lastname" => $lastname,
"orderid" => $orderId,
"newsletter" => $newsletterOptin ? "yes" : "no",
"products" => [
[
"id" => "ABC123",
"name" => "Product 1",
"category_ids" => ["CAT_1", "CAT_2"],
"price" => 29.99,
"quantity" => 2
],
[
"id" => "XYZ_789",
"name" => "Product 2",
"category_ids" => ["CAT_2"],
"price" => 39.99,
"quantity" => 1
]
]
]
]
];
$json = json_encode($fields);
$ch = curl_init();
...
$result = curl_exec($ch);
curl_close($ch);
|
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:
/v1/productsPOST
Name |
Description |
products |
Array of product(s) you want to add/update. Supported properties:
id |
unique id or SKU Mandatory |
title |
title of the product Mandatory for new products |
link |
URL of the product Mandatory for new products |
description |
Product description |
language |
Default: en-US ISO-639 + ISO-3166 |
price |
2 decimals, no thousands-separator. Optionally add currency. examples: 1099.99 or EUR 99.01 or 99 EUR |
sale_price |
2 decimals, no thousands-separator. Optionally add currency. examples: 1099.99 or EUR 99.01 or 99 EUR |
currency |
Currency e.g. GBP, EUR, USD |
image_link |
URL of the image |
image_links |
Array of image URLs. Supply up to 20 images. (Overwrites image_link field) |
availability |
in stock (default), out of stock, available for order, preorder |
condition |
new (default), used, refurbished |
inventory |
Amount of products in stock |
brand |
Brand of the product |
parent_id |
Products with the same parent id / parent SKU will be grouped as variants in your catalog |
category_ids |
Array of category ids / SKUs. Categories that contain this product. |
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.
[
{
"checkin" : "2019-09-23",
"nights" : 7
},
{
"checkin" : "2019-09-23",
"nights" : 6
},
]
|
Example request:
{
"products": [
{
"id" : "ABC123",
"title" : "Product 1",
"link" : "https://yourshop.com/product-1"
},
{
"id" : "XYZ_789",
"title" : "Product 2",
"link" : "https://yourshop.com/product-2",
"description" : "Product 2 description",
"price" : "GBP 19.95",
"image_link" : "https://yourshop.com/product-2.jpg",
"condition" : "new",
"inventory" : 80,
"brand" : "Your brand",
"parent_id" : "XYZ",
"category_ids": ["CAT-123", "CAT-321"]
}
]
}
Example success response:
{
"success": true,
"created": 1,
"updated": 1,
"errors": []
}
Example error response (2 products with missing title):
{
"success": false,
"errors": [
"#0: no title",
"#1: no title"
]
}
Example error response (2 products, 1 with incorrect condition):
{
"success":true,
"created": 1,
"updated": 0,
"errors": [
"#1: condition not correct"
]
}
|
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:
/v1/categoriesPOST
Name |
Description |
|
categories |
Array of categories you want to add/update. Supported properties:
category_id |
unique id or SKU Mandatory |
title |
title of the category Mandatory |
description |
Description of the category |
link |
URL of the category |
Example request:
{
"categories": [
{
"category_id" : "CAT_1",
"title" : "Category 1"
},
{
"category_id" : "CAT_2",
"title" : "Category 2",
"link" : "https://yourshop.com/category-2",
"description" : "Category 2 description"
}
]
}
Example success response:
{
"success": true,
"created": 1,
"updated": 1,
"errors": []
}
Example error response (2 categories with missing title):
{
"success": false,
"errors": [
"#0: no title",
"#1: no 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",
"export_format" => "csv" //csv or json
];
$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:
/v1/reporting/eventsPOST
You 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 |
|
email |
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 |
|
Download an export
Endpoint:
/v1/reporting/download/XXX.csvGET
Use 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 customer
Endpoint:
/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>"
}
NOTE: Use the callback hash received in the API response to identify the callback that matches this privacy request in the next step.
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: Please always use the profile hashes received in the callback payload to delete or modify profiles.
NOTE: The callback & profile hashes are always 64 character strings.
Deleting a profile
Endpoint:
/v1/privacy/request/{PROFILE_HASH}DELETE
{}
API
Response:
{
"success": true
}
Modifying a profile
Endpoint:
/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 |
- No identifier was included
- More than one identifier included (email, cookie)
- Callback URL missing
- Callback URL does not use HTTPS SSL encryption
- No entities in request found to modify
- Modified data in entities did not validate (in this case the error property will contain an object with all found validation errors)
|
MISSING_IDENTIFIER IDENTIFIER_AMBIGUOUS MISSING_CALLBACK_URL CALLBACK_URL_NOT_SECURE NO_PROFILES_TO_MODIFY |
404 |
- Profile hash not included in the request
- Profile hash invalid
|
MISSING_PROFILE_HASH INVALID_PROFILE_HASH |
Consent
Set the consent level of a customer through our API:
Endpoint:
/v1/trackPOST
Name |
Description |
|
event |
EmailOptIn
|
Mandatory |
email |
Customer email or SHA256 of the email
|
Mandatory |
newsletter |
Enables email address to be exported to email platforms to receive marketing updates. Allowed values: yes - no.
|
Recommended |
marketing |
Enables email upload to external channels that offer email matching, f.e. Facebook & Adwords. Allowed values: yes - no.
|
Recommended |
service |
Adds a field to the user profile that only service emails are allowed, not marketing. Find this field in your user profile on your external email platform. Allowed values: yes - no.
|
Recommended |
Example
$url = "https://api.squeezely.tech/v1/track";
$fields = [
"events" => [
[
"event" => "EmailOptIn",
"email" => $email,
"newsletter" => $newsletterOptin ? "yes" : "no",
"marketing" => $marketingOptin ? "yes" : "no",
"service" => "yes",
]
]
];
$json = json_encode($fields);
$ch = curl_init();
...
$result = curl_exec($ch);
curl_close($ch);
|
Response codes
HTTP status code |
Description |
Error codes |
201 |
Resource created |
|
400 |
No resource created |
WRONG_CONTENTTYPE |
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 the receiving side.
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'];
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.
-
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.
Please note: It is advised to use method like hash_equals (php), secure_compare (ruby) or the equivalent solution available in your programming language of choice. These perform a `constant time` string comparison, which renders it safe from certain timing attacks.
Regular plain equality operators do not prevent timing attacks.
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(!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", $rawData, $signature)) {
// The message has not been validated
exit;
}
// You can now use the contents of the callback
$data = json_decode($rawData, true);
Feed documentation
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 for new products
|
link
|
URL of the product
|
Mandatory for new products |
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
|
|
sale_price
|
The current sale price and currency of the product (EUR/USD/GBP). In decimals (no thousand separator, dot for decimal separator). Example: 1245.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
|
E.g. en-US (ISO-639 + ISO-3166)
|
|
parent_id
|
Products with the same parent id will be grouped as variants in your catalog.
|
|
category_ids
|
Categories that have this product. 2 supported types:
<category_ids>
<category_id>TV-1234</category_id>
<category_id>TV-4321</category_id>
</category_ids>
or
<category_ids>TV-1234</category_ids>
<category_ids>TV-4321</category_ids> .
|
|
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.
[
{
"checkin" : "2019-09-23",
"nights" : 7
},
{
"checkin" : "2019-09-23",
"nights" : 6
},
]
|
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
|
link
|
Url of the category
|
id
|
SKU or your internal category id or reference. Mandatory Unique
|
Below an example of an RSS feed enriched with custom categories
<?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>
<id>TV_123456</id>
<title>LG 22LB4510 - 22" LED TV - 1080p (FullHD)</title>
<link>http://www.example.com/electronics/tv/22LB4510.html</link>
<language>en-US</language>
<image_link>http://images.example.com/TV_123456.png</image_link>
<google_product_category>404</google_product_category>
</item>
<item>
<id>TV_654321</id>
<title>LG 22LB4512 - 24" LED TV - 1080p (FullHD)</title>
<link>http://www.example.com/electronics/tv/22LB4512.html</link>
<language>en-US</language>
<image_links>
<image_link>http://images.example.com/CLO-1029384-1.jpg</image_link>
<image_link>http://images.example.com/CLO-1029384-2.jpg</image_link>
</image_links>
<category_ids>
<category_id>TV-1234</category_id>
<category_id>TV-4321</category_id>
</category_ids>
</item>
<category>
<id>TV-1234</id>
<title>TV's 22"</title>
<description>Only the best TV's 22"</description>
<link>http://www.example.com/tvs/22</link>
</category>
<category>
<id>TV-4321</id>
<title>TV's 24"</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>
<id>NL_ZH_DH_HOTEL_X</id>
<title>Hotel The Hague</title>
<link>http://www.example.com/nl/zh/hotel_the_hague.html</link>
<image_link>http://images.example.com/HOTEL_X.png</image_link>
<google_product_category>404</google_product_category>
<date_availability>
<availability>
<checkin>2019-09-11</checkin>
<nights>1</nights>
<price>1</price>
</availability>
</date_availability>
</item>
<category>
<id>404</id>
<title>Hotels</title>
</category>
</channel>
</rss>
Using Google categories
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.
Caveats
Character encoding
Feed character encoding is auto-detected using the encoding specified in the XML declaration's encoding attribute.
<?xml version="1.0" encoding="UTF-8"?>
Character encoding in UTF-8 will be assumed automatically if not specified in the encoding attribute.
This might cause unexpected results if your encoding is not UTF-8. Side effects can range from improperly displayed characters in your texts, to some (or all) products not being imported.
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 add the Product Set in the "Datalayer productsets" setting in your merchant settings.
{
'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-US',
'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
The Squeezely Website Personalization will work immediately after installing the
Frontend-tracking pixel.
Templates
Our templates support plain HTML and
Nunjucks. Nunjucks will allow you to
create more complex personalizations, that are more tailored to the visitor. Squeezely adds some basic
variables and
filters to Nunjucks to power your personalizations.
Using variables in Custom Templates
In Custom Templates, you can loop through products of the personalization yourself. Below an example of how you can do that:
Check out our bestsellers:
{% for item in items %}
{{ item.title }} now on sale for only {{ item.currency_sign }} {{ item.price }}!
{% endfor %}
Note: The above example works both for custom HTML insert and custom overlay.
Even though an overlay can contain one product, it's always placed in the array variable items.
Personalization variables
Default profile fields
The following profile variables are available in your templates and input fields:
Variable name |
Type |
Description |
{{ firstname }} |
string |
Customer first name |
{{ gender }} |
string |
Customer gender. Possible values: m = male, f = female, u = unknown (default value) |
{{ city }} |
string |
Customer city |
Default product fields
If you choose a product set or product, the following variables are available in your templates and input fields:
Variable name |
Type |
Description |
{{ title }} |
string |
Product title. |
{{ id }} |
string |
The unique product ID (SKU or EAN). |
{{ description }} |
string |
Product description. |
{{ brand }} |
string |
Product brand. |
{{ image }} |
string |
Original product image url. |
{{ image_square }} |
string |
Product image url of the square image variant. |
{{ currency_sign }} |
string |
Displays the currency sign. |
{{ price }} |
decimal number |
Product price. |
{{ sale_price }} |
decimal number |
Product sale price. |
{{ url }} |
string |
Url of the product. |
{{ language }} |
string |
Language code of the product. |
{{ inventory }} |
string |
Amount in stock. |
{{ availability }} |
string |
Availability: in stock, out of stock or available for order. |
{{ condition }} |
string |
Condition: new, used or refurbished. |
{{ pageview_url_amount }} |
number |
Filter variable. Shows the pageviews of the current page url. |
{{ pageview_global_amount }} |
number |
Filter variable. Shows the pageviews of the current website. |
{{ pageview_product_amount }} |
number |
Filter variable. Shows the pageviews of the current product.
Note: This variable only works if personalization is triggered on product view
|
{{ visitor_url_amount }} |
number |
Filter variable. Shows the unique visitors of the current page url. |
{{ visitor_global_amount }} |
number |
Filter variable. Shows the unique visitors of the current website. |
{{ visitor_product_amount }} |
number |
Filter variable. Shows the unique visitors of the current product.
Note: This variable only works if personalization is triggered on product view
|
{{ product_conversion_amount }} |
number |
Filter variable. Amount of conversions of the current product. |
{{ last_conversion_global.X }} |
array |
Filter variable. Contains information about the last conversion on this website.
Note: We don't trigger personalizations if no conversion information is found.
{{ last_conversion_global.time_ago }} |
Eg: 3 hours. Language from event is used by default. |
{{ last_conversion_global.city }} |
City extracted from the last conversion event. Default: empty |
{{ last_conversion_global.country }} |
Country extracted from the last conversion event. Default: empty |
|
{{ last_conversion_product.X }} |
array |
Filter variable. Contains information about the last conversion of the current product.
Note: This variable only works if personalization is triggered on product view
We don't trigger personalizations if no conversion information is found.
{{ last_conversion_product.time_ago }} |
Eg: 1 hour and 15 minutes. Language from event is used by default. |
{{ last_conversion_product.city }} |
City extracted from the last conversion event. Default: empty |
{{ last_conversion_product.country }} |
Country extracted from the last conversion event. Default: empty |
|
Personalization filters
Product filters
You can use filters to change variable output, or to prevent a personalization for showing:
Filter |
Description |
{{ .. | minimum(X) }} |
Filter filter. Only show this variant if there is a minimum of X events in the specified time window. |
{{ .. | time_window('today') }} |
Event filter. Specify the time window for this filter.
Possible values: lasthour, today, last24hours (default), lastweek
|
{{ .. | date_format('EN') }} |
Filter filter. Show variable in this language. Supported languages: EN (default), NL.
If your event contains a language field, we will use this as fallback, if date_format() isn't provided
Eg. used for last_conversion_product.time_ago.
|
{{ .. | target_url('https://squeezely.tech/dashboard') }} |
Event filter. Specify the full url for this filter. This is only possible for {{ visitor_url_amount }} AND {{ pageview_url_amount }} |
{{ .. | image_resize }} |
Resize the image of a product. See below for more instructions. |
Example: show how many times a product is viewed, but dont show the personalization variant if there are less than 1000 views.
This page is viewed {{ pageviews_url_amount | time_window('lastweek') | minimum(1000) }} times in the last week.
Example: show when a product is last sold in english (this will return
This product is sold 1 hour and 23 minutes ago, but dont show the personalization variant if it is not sold today.
This product is sold {{ last_conversion_product.time_ago | time_window('today') | date_format("EN") }} times in the last week.
Image resize functionality
Using the image_resize function in conjunction with the {{ image_square }} variables it's possible to alter the way product images are displayed:
Method |
Description |
Example |
1 |
Embed within both provided dimensions, adds whitespace |
{{ image_square | image_resize('600x600x1') }}
|
2 |
Crop to cover both provided dimensions |
{{ image_square | image_resize('600x600x2') }}
|
3 |
Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified |
{{ image_square | image_resize('600x600x3') }}
|
4 |
Ignore the aspect ratio of the input and stretch to both provided dimensions |
{{ image_square | image_resize('600x600x4') }}
|
Built-in filters
Besides the filters above, there are
Nunjuck built-in filters
Filter: default
This filter gives you the ability to fallback to a default value, if the given variable is empty and/or doesn't exist.
You can apply this filter on any of the above template variables.
Below an example of city fallback to 'Amsterdam' if the field is empty:
Do you live in {{ city|default('Amsterdam') }}?
Advanced
Tracking clicks in Custom Templates
It's important to track your views and link clicks. Views are automatically tracked.
All links are tracked automatically and follow the new window behaviour of your variant settings.
Every click on any link in the personalization will be tracked with the the default
_sqzl.push() function and open's the link.
If you want to add additional data in the event call, you can use the HTML attribute
data-sqzly-attributes in your link.
Below an example of how you can use it:
<a href="**Your URL**" data-sqzly-attributes='{"custom_interested_lead" : true});'>Click here for our proposal</a>
Date fields in the Feedback template
The custom fields with datatype
Date will show as a datepicker in your feedback form.
Flatpickr is used for this:
see Flatpickr documentation.
You can overwrite the configuration by using the Javascript variable
. An example:
datePickerSettings = {
altInput: true,
altFormat: 'Y-m-d'
}
Custom overlay close button
If you create your own close button, please add the class
sqzly-modal-close. This makes sure the overlay doesn't show again in the next 7 days.
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.
Product lister personalization
It's possible to provide personalization on product specific level to persuade customers. This works for one product and multiple products on one page.
To make this work, you need to trigger the personalization on an event (for example ViewContent or ViewCategory) and provide the property
products.
The personalization needs to find the location of product on your page and the corresponding product SKU. You can use the HTML data-attributes
data-product-sku or
data-product-id to provide the SKU for that HTML element. Below an example how this works:
<div class="container" data-product-sku="product-sku-1">
<div class="product-image"></div>
<div class="product-item-details">
<div class="product-item-form"></div>
<!-- .... -->
</div>
</div>
<div class="container" data-product-sku="product-sku-2">
<div class="product-image"></div>
<div class="product-item-details">
<div class="product-item-form"></div>
<!-- .... -->
</div>
</div>