Introduction
This documentation provides an overview on how to programmatically interact with Spotler Activate.
It describes how to get data in and out of Spotler Activate, and how to integrate Spotler Activate 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.
Date and timezone handling
The default timezone we use is CET (Central European Time).
Timestamps
We support timestamps in seconds which will be converted and saved as a datetime in CET timezone.Sending datetimes
When sending a datetime to us instead of a timestamp, for example when sending a purchase event, you need to send the datetime in the CET timezone or specify the timezone with the ISO8601, ATOM or W3C format.Only formats starting with YYYY-mm-dd are supported. The API will return a TIMESTAMP_ERROR when an unsupported date format is sent.
Returned dates
All date time values are returned in the CET timezone in the format: YYYY-MM-DD HH:mm:ss unless otherwise specified.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/<YOUR_IDENTIFIER>/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.
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 |
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
|
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 | Optional | ||||||||||||
lastname | Customer last name | Optional | ||||||||||||
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 (e.g. +31612345678, E164 format) | 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 | ||||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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:
Example 2:
|
Mandatory | ||||||||||||
Example
|
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 | ||||||||||||
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 (e.g. +31612345678, E164 format) | 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 | ||||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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 | ||||||||||||
Example
|
Event: Return
Event should be fired when someone returns product(s). When event is fired, a customer's total value will be updated.Available properties:
Name | Description | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
event | Return | Mandatory | ||||||||||||
Customer email or SHA256 of the email | Mandatory | |||||||||||||
currency | Currency of the purchase (e.g. GBP/EUR/USD, ISO 4217) | Optional | ||||||||||||
totalvalue | Total value of the return, 2 decimals positive number. If sent, this will override the total value calculated based on the products field. | Optional | ||||||||||||
products |
JSON array of product(s). Supported properties:
Example 2:
|
Mandatory | ||||||||||||
Example
|
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 | ||||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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:
Example 2:
|
Mandatory | ||||||||||||
Example
|
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:
|
Mandatory | ||
Example
|
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 | ||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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:
Example 2:
|
Mandatory | ||||||||||
Example
|
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 |
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
Optional |
Example
|
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 | ||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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 | ||||||||||
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:
Example 2:
|
Optional | ||||||||||
Example
|
Event: Custom
You can add a custom event to target people with certain website behavior.Available properties:
Name | Description | |
---|---|---|
event |
Your custom event name
|
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
|
Event: Lead
You can add a lead event to target people who sign up.Available properties:
Name | Description | |
---|---|---|
event | Lead | Mandatory |
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
|
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. | 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
|
Event: CompleteRegistration
Event should be fired when someone completes a registration/signup form.Available properties:
Name | Description | |
---|---|---|
event | CompleteRegistration | Mandatory |
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
|
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 (e.g. +31612345678, E164 format) | 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 | ||||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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:
Example 2:
|
Optional | ||||||||||||
Example
|
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 Spotler Activate, but there is no user activity like a PageView, send a CRMUpdate event through our backend(!) API.
Retrieving contact information
Endpoint: /v1/contactGET
Parameters:
Field name | Description | |
---|---|---|
Contact email | optional | |
email_hash | Contact email sha 256 | optional |
userid | Your unique user identifier | optional |
cookie | Contact cookie | optional |
phone | Contact phone. Note: when using '+' signs, make sure to properly encode them (%2B) | optional |
expandCategories | Option to expand the category data so they have an id and name (true|false) | optional, default false |
{
"success": true,
"errors": [],
"customer": {
"customer_phase": "No phase",
"audiences": [1, 2, 3],
"customfields": {
"last_order_checkin_date": "2023-06-15",
},
"firstname": "John",
"lastname": "Schmidt",
"gender": "m",
"birthdate": "1985-12-31",
"phone": "+31612345678",
"postcode": null,
"city": "Den Haag",
"country": "nl",
"currency": "EUR",
"totalvalue": null,
"lastpurchase": "2023-03-15",
"firstpurchase": "2023-03-15",
"totalorders": 5,
"cartvalue": null,
"newsletter": "no",
"marketing": "no",
"service": "no"
},
"customers": []
}
When multiple customers are found (i.e. when using phone as identifier), "customers" property will contain all customers.
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
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.
Using collections in Personalizations
You can use collections to display data in personalizations.Only the exposed collections are available in the form of an array, with the function exposedCollections().
Example: Show a customers favorite colors:
{{ exposedCollections(["*.*.customer_favorite_colors", "customer_settings.current_color"] }}
{% if collections.customer_settings is defined
and collections.customer_settings.customer_favorite_colors is defined %}
<ul>
{% for color in collections.customer_settings.customer_favorite_colors %}
<li>{{ color }}</li>
{% endfor %}
</ul>
{% else %}
No favorite colors known
{% endif %}
Your current color is: {{ collections.customer_settings.current_color }}
Using collections in Journeys
You can use a collection in a visitor split node.The visitor split will look at the (first) collection that is passed in the journey entry event. compare the main key (in this case customer_settings) and/or a sub key (for example current_color) values to send people in the right direction.
The value you are comparing must be a string (in this case red), not an array.
Note:
- A collection entry needs to have a toplevel key (cannot be 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 is hidden, but you can generate a new key in the settings panel.
NOTE: Examples in the documentation will contain the Account-identifier 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://api.squeezely.techExample 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 or failed to authenticate too many times | MISSING_API_KEY_OR_ACCOUNT INVALID_CREDENTIALS AUTHENTICATION_RATE_LIMIT ENDPOINT_DEPRECATED |
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 allows 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_ERROR DUPLICATE_EVENT |
400 | No resource created | NO_EVENTS TOO_MANY_EVENTS NO_EMAIL_OR_USERID NO_MERCHANT UNKNOWN_ERROR INVALID_EVENTS |
Event: Purchase
Endpoint: /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: see date time handling | 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 (e.g. +31612345678, E164 format) | 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 | ||||||||||||
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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 | ||||||||||||
sqzly_cookie | The Spotler Activate cookie we use in the frontend (cookie name sqzllocal) to support Server-to-Server events. Only update profiles if cookie is recognized, no new profiles are created. We do advise to you use this in combination with frontend events to collect all the needed (browser) data. |
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 | ||||||||||||
Example
|
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: Custom
Endpoint: /v1/trackPOSTYou can add a custom event to target people with certain website behavior.
Available properties:
Name | Description | |
---|---|---|
event |
Your custom event name
|
Mandatory |
Customer email or SHA256 of the email | Mandatory | |
value | Value of your custom event | Optional |
firstname | Customer first name | Optional |
lastname | Customer last name | Optional |
timestamp | Timestamp of the event, only needed for events in the past. Formats allowed: see date time handling | 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 (e.g. +31612345678, E164 format) | Optional |
postcode | Customer postcode | Optional |
city | Customer city | Optional |
country | Customer 2-letter country code (e.g. NL, ISO 3166-1 alpha-2) | Optional |
language | Customer
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
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 |
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
|
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
Get product data for up to 25 products.
Getting product data
Endpoint: /productsGET
Name | Description |
---|---|
sku |
Comma separated list of skus |
language | Language of the product Optional |
Creating or updating products
Create, update or delete up to 250 products at a time through our API:
Endpoint: /productsPOST
Name | Description | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
products |
Array of product(s) you want to add/update. Supported properties:
NOTE: Make sure the product values created or updated via our API match the values in any linked product source that might enabled to prevent values from changing back and forth.
Example request:
Example success response:
Example error response (2 products with missing title):
Example error response (2 products, 1 with incorrect condition):
|
Response codes
HTTP status code | Description | Error codes |
---|---|---|
201 | Resource created | |
400 | No resource created | WRONG_CONTENTTYPE, NO_PRODUCTS, TOO_MANY_PRODUCTS, |
Deleting products
Endpoint: /productsDELETE
Mark products for deletion. Products will be disabled and removed after 1 week
Name | Description | ||||
---|---|---|---|---|---|
products |
Array of product(s) you want to delete. Supported properties:
|
Example request:
{
"products": [
{
"id" : "ABC123",
"language": "nl-NL",
},
{
"id" : "XYZ_789",
"language": "en-US",
},
{
"id" : "XYZ_844",
"language": "en-US",
}
]
}
Example success response:
{
"success": true,
"productsDisabled": 3,
"errors": [],
"errorDetails": []
}
Example partial error response partial success (2 products with missing sku / not found):
{
"success": true,
"productsDisabled": 1,
"errors": ["PARTIAL_FAILURE"],
"errorDetails": [
"PARTIAL_FAILURE" => [
"#1: condition not correct",
"#2: product not found",
]
]
}
Example error response no deletion:
{
"success": false,
"productsDisabled": 0,
"errors": ["FAILED_TO_DELETE"],
"errorDetails": [
"FAILED_TO_DELETE" => [
"#1: condition not correct",
"#2: product not found",
"#3: product not found",
]
]
}
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | Resource(s) deleted | PARTIAL_FAILURE, FAILED_TO_DELETE |
415 | Unsupported Content Type | UNSUPPORTED_CONTENT_TYPE |
503 | Merchant is in maintenance | MERCHANT_IN_MAINTENANCE |
Productsets
Get the productsets in your account:Endpoint: /v1/productsetsGET
Example response:
{
"success": true,
"total": 2,
"data": [
{
"id" : 1,
"name" : "Most sold products",
"products" : 10,
"personalized" : false,
"feed_url" : "https://app.squeezely.tech/products?account=VnBzeVhzV3dKQVduQkFDNll2V2VrUT09&productset=0N5RDBF7P3KS"
},
{
"id" : 2,
"name" : "Recommended for you",
"products" : 0,
"personalized" : true,
"feed_url" : "https://app.squeezely.tech/products?account=VnBzeVhzV3dKQVduQkFDNll2V2VrUT09&productset=0N5RDBF7P3KS&email=|*EMAIL*|"
}
]
}
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
Audiences
Get the audiences in your account:
Endpoint: /v1/audiencesGET
Example response:
{
"success": true,
"total": 2,
"data": [
{
"id" : 1,
"name" : "Visitors last month"
},
{
"id" : 2,
"name" : "Loyal customers"
}
]
}
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
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:
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 Spotler Activate.Call the resource endpoint and we will generate an export file.
Optionally you can supply a callback url which we call when the file generation is completed.
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, json or jsonl. Please use jsonl for large exports.
];
$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"
}
Optionally the extension .gz can be added to the filename in the download URL to download a gzipped file.
Available reports
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, UNKNOWN_ERROR |
Events export
Endpoint: /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 |
events | Only include these events in the report. Format: JSON array | Optional |
callback_url | URL we call once when the file is available for download. | Optional |
audiences | Comma separated list of audience ids in which the events must exist. | Optional |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, NO_JSON_PARAMETER_SUPPORT, NO_DATE_RANGE_PROVIDED, INVALID_DATE_RANGE_PROVIDED, INVALID_FROM_DATE, INVALID_TO_DATE, UNKNOWN_ERROR |
Download Url
A download url will be supplied in the callback URL as a GET parameter.
"https://yourwebsite.com/callback?download_url=..."
Optionally the extension .gz can be added to the filename in the download URL to download a gzipped file.
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 | |
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 Spotler Activate campaign | |
sqzl_source | The event Spotler Activate 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: /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 |
userid_not_empty | Pass this variable true if you only want to select contacts that have a userid. | Optional |
audiences | Comma separated list of audience ids in which the contacts must exist. | Optional |
fields | Comma separated list of fields you want to include in the export. | Optional |
export_format | Format the download should be available in, csv, json or jsonl, defaults to csv. | Optional |
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
201 | Resource created | |
400 | No resource created | REPORTING_NOT_ENABLED, NO_JSON_PARAMETER_SUPPORT, UNKNOWN_ERROR |
422 | Could not generate report | INACTIVE_AUDIENCES |
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 (earliest created) | |
all_cookies | All contact cookies (ordered by earliest created date first) | |
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. | |
audiences | Semicolon-separated list of audience ids that the contact is a part of. | |
audience_names | Semicolon-separated list of audience names (same order as audiences). |
Download an export
Endpoint: /v1/reporting/download/{FILENAME}GETUse this endpoint to download a previously created report.
Files are in the chosen format are available in both uncompressed and gzipped formats:
- {HASH}.csv
- {HASH}.csv.gz
- {HASH}.jsonl
- {HASH}.jsonl.gz
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK | |
404 | Resource not available | RESOURCE_NOT_FOUND, RESOURCE_NOT_READY, RESOURCE_EXPIRED |
Stats
RFM Stats
Endpoint: /rfm/statsGET
Example response:
{
"success": true,
"data": {
"last_updated": {
"timestamp_unix": 1678976997,
"timestamp_formatted": "2023-03-16 15:29"
},
"segments": [
{
"name": "Champions",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 17954.99,
"customer_value_percentage": 71.92,
"customer_value_average": 17954.99
},
{
"name": "Loyal",
"customer_count": 0,
"customer_count_percentage": 0,
"customer_value": 0,
"customer_value_percentage": 0,
"customer_value_average": 0
},
{
"name": "Potential loyalist",
"customer_count": 0,
"customer_count_percentage": 0,
"customer_value": 0,
"customer_value_percentage": 0,
"customer_value_average": 0
},
{
"name": "New customers",
"customer_count": 8,
"customer_count_percentage": 50,
"customer_value": 475.86,
"customer_value_percentage": 1.91,
"customer_value_average": 59.48
},
{
"name": "Promising",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 60,
"customer_value_percentage": 0.24,
"customer_value_average": 60
},
{
"name": "Need attention",
"customer_count": 0,
"customer_count_percentage": 0,
"customer_value": 0,
"customer_value_percentage": 0,
"customer_value_average": 0
},
{
"name": "About to sleep",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 81.06,
"customer_value_percentage": 0.32,
"customer_value_average": 81.06
},
{
"name": "At risk",
"customer_count": 2,
"customer_count_percentage": 12.5,
"customer_value": 2918.96,
"customer_value_percentage": 11.69,
"customer_value_average": 1459.48
},
{
"name": "About to lose",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 2901.98,
"customer_value_percentage": 11.62,
"customer_value_average": 2901.98
},
{
"name": "Hibernating",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 172.18,
"customer_value_percentage": 0.69,
"customer_value_average": 172.18
},
{
"name": "Lost customers",
"customer_count": 1,
"customer_count_percentage": 6.25,
"customer_value": 399.87,
"customer_value_percentage": 1.6,
"customer_value_average": 399.87
}
],
"boundaries": {
"1": {
"recency": {
"min": "2022-05-12 16:48:59",
"max": "2022-09-19 12:46:09",
"volume": 8
},
"frequency": {
"min": 1,
"max": 1,
"volume": 4
},
"monetaryvalue": {
"min": 3.33,
"max": 57.12,
"volume": 4
}
},
"2": {
"recency": {
"min": "2022-11-02 15:35:59",
"max": "2022-11-30 09:54:04",
"volume": 7
},
"frequency": {
"min": 2,
"max": 2,
"volume": 5
},
"monetaryvalue": {
"min": 59.98,
"max": 59.98,
"volume": 4
}
},
"3": {
"recency": {
"min": "2022-11-30 09:59:06",
"max": "2022-11-30 14:33:03",
"volume": 8
},
"frequency": {
"min": 3,
"max": 3,
"volume": 4
},
"monetaryvalue": {
"min": 60,
"max": 86.09,
"volume": 3
}
},
"4": {
"recency": {
"min": "2022-11-30 14:36:53",
"max": "2023-01-23 15:59:48",
"volume": 7
},
"frequency": {
"min": 4,
"max": 7,
"volume": 3
},
"monetaryvalue": {
"min": 91.12,
"max": 414.56,
"volume": 4
}
},
"5": {
"recency": {
"min": "2023-03-01 20:02:07",
"max": "2023-03-06 14:55:04",
"volume": 7
},
"frequency": {
"min": 13,
"max": 13,
"volume": 1
},
"monetaryvalue": {
"min": 1000.99,
"max": 1784.99,
"volume": 4
}
}
}
}
}
Response codes
HTTP status code | Description | Error codes |
---|---|---|
200 | OK |
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: /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.
Anonymize 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 |
|
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 Spotler Activate, but there is no user activity like a PageView, send a CRMUpdate event through our backend(!) API.
Retrieving contact information
Endpoint: /v1/contactGET
Parameters:
Field name | Description | |
---|---|---|
Contact email | optional | |
email_hash | Contact email sha 256 | optional |
userid | Your unique user identifier | optional |
cookie | Contact cookie | optional |
phone | Contact phone. Note: when using '+' signs, make sure to properly encode them (%2B) | optional |
expandCategories | Option to expand the category data so they have an id and name (true|false) | optional, default false |
{
"success": true,
"errors": [],
"customer": {
"customer_phase": "No phase",
"audiences": [1, 2, 3],
"customfields": {
"last_order_checkin_date": "2023-06-15",
},
"firstname": "John",
"lastname": "Schmidt",
"gender": "m",
"birthdate": "1985-12-31",
"phone": "+31612345678",
"postcode": null,
"city": "Den Haag",
"country": "nl",
"currency": "EUR",
"totalvalue": null,
"lastpurchase": "2023-03-15",
"firstpurchase": "2023-03-15",
"totalorders": 5,
"cartvalue": null,
"newsletter": "no",
"marketing": "no",
"service": "no"
},
"customers": []
}
When multiple customers are found (i.e. when using phone as identifier), "customers" property will contain all customers.
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
Journeys
Get the journeys in your account:
Endpoint: /v1/journeysGET
Example response:
{
"success": true,
"total": 2,
"data": [
{
"id": 7,
"name": "Newsletter",
"created_at": "2021-08-25 15:46:05",
"updated_at": "2021-08-25 15:48:34",
"status": "published"
},
{
"id": 6,
"name": "Abandoned cart",
"created_at": "2021-08-25 15:42:19",
"updated_at": "2021-08-25 15:45:12",
"status": "draft"
}
]
}
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
Personalizations
Get the personalizations in your account:
Endpoint: /v1/personalizationsGET
Example response:
{
"success": true,
"total": 3,
"data": [
{
"id": 21,
"name": "Back in stock",
"created_at": "2021-08-25 11:03:09",
"updated_at": "2021-08-25 15:54:44",
"status": "paused",
"email": false,
"variants": [
{
"id": 34,
"name": "New custom variant",
"created_at": "2021-08-25 11:03:09",
"updated_at": "2021-08-25 11:06:10"
}
]
},
{
"id": 10,
"name": "Homepage - Recommended for you",
"created_at": "2021-08-17 10:49:00",
"updated_at": "2021-08-25 15:53:48",
"status": "published",
"email": false,
"variants": [
{
"id": 45,
"name": "New Overlay",
"created_at": "2021-08-17 10:49:00",
"updated_at": "2021-08-25 15:53:48"
}
]
},
{
"id": 9,
"name": "Abandoned cart email",
"created_at": "2021-08-17 10:48:22",
"updated_at": "2021-08-25 15:54:07",
"status": "published",
"email": true,
"template": "<table>...</table>",
"max_products": 3,
"url_template": "https://squeezely.tech/mailing/abc123/9/product-{ index }.jpg?email={email}",
"image_template": "https://d.squeezely.tech/mailing/abc123/9/product-{ index }.jpg?email={email}",
"image_preview": "https://d.squeezely.tech/mailing/abc123/9/product-1.jpg?email=preview"
"variants": [
{
"id": 56,
"name": "New feedback form",
"created_at": "2021-08-17 10:48:22",
"updated_at": "2021-08-25 15:54:07",
}
]
},
{
"id": 8,
"name": "Personalization with targeting and attribution settings",
...
"settings": {
... See below
}
}
]
}
Example settings within the response:
...,
"settings": {
"targeting":{
"include_audiences": => [
{
"id": 123,
"name": "Audience 1"
},
],
"exclude_audiences": [
{
"id": 456,
"name": 'Audience 2'
},
],
"location": {
"include": {
"type": "everywhere",
},
"exclude": {
"type": "none",
},
},
},
"attribution": {
"events": [
'Purchase'
],
}
}
...,
"settings": {
"targeting":{
...,
"location": {
"include": {
"type": "starts_with',
"ignore_query_parameters": false,
"urls": [
'https://www.example.com'
]
},
"exclude": {
'type' => "contains",
'urls' => [
'example',
],
},
},
},
...
}
...,
"settings": {
"targeting": {
...,
"countries": [
'NL',
'DE'
]
},
...
}
...,
"settings": {
"targeting":{
...,
"city": {
"radius": 12,
"cities": [
{
"id": 2747373,
"name": "The Hague",
"coordinates": {
"latitude": "52.076670000",
"longitude": "4.298610000"
}
},
{
"id": 123,
"name": "Some City"
}
]
}
},
...
}
NOTE: Please test for specific setting properties before using them. Some of the properties might not always be set.
Name | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|
Setting values |
Predefined field values:
|
Response codes
HTTP status code | Description | HTTP codes |
---|---|---|
200 | OK | OK |
Consent
Set the consent level of a customer through our API:Endpoint: /v1/trackPOST
Name | Description | |
---|---|---|
event |
EmailOptIn |
Mandatory |
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
|
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 Spotler Activate to somewhere else.For example, a webhook can be fired whenever someone unsubscribes from a newsletter list.
You can configure webhooks in the Spotler Activate 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.
-
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 Spotler Activate 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);
Setup Push Notifications
For browser security purposes, you need to host our script yourself. To ensure our script is updated, you can import it every time. Please follow below instructions:
-
Create a file containing the following code:
importScripts('https://squeezely.tech/tracker/serviceworker.js');
- Name this file squeezely-worker.js
- Upload the file to your root folder. For instance, if your site is https://mywebsite.com, it should be accessible at https://mywebsite.com/squeezely-worker.js.
You should now have working push notifications. If not please check the console for error messages. If there are no error messages, please verify your local browser notification settings. Otherwise you can contact support@squeezely.tech for further assistance.
For more information on how to set up push nofications within Spotler Activate, please refer to this article.
Products
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 Spotler Activate 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
The current value will be removed if price is present and empty. The current value will not be changed when this field is not present. |
|||||||||||
sale_price |
The sale price of the product. In decimals (no thousand separator, dot for decimal separator). Example: 1245.50
The current value will be removed if sale_price is present and empty or 0. The current value will not be changed when this field is not present. |
|||||||||||
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. 2 supported types:
or
|
|||||||||||
condition | Condition of the product, new (default), used, refurbished. | |||||||||||
inventory | Amount of products in stock | |||||||||||
brand | Brand of the product | |||||||||||
size | The size of the product | |||||||||||
color | The color of the product | |||||||||||
language | Product
language (e.g. en-US, en-GB) Format: a combination of ISO 639-1 and ISO 3166-1 alpha-2 respectively separated by a hyphen(-). |
|||||||||||
parent_id | Products with the same parent id will be grouped as variants in your catalog. | |||||||||||
category_ids |
Categories containing this product. 2 supported types:
or
.
|
|||||||||||
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. |
|||||||||||
categories |
Categories containing this product:
Supported properties
|
|||||||||||
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 |
link | Url of the 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="https://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>https://www.example.com/electronics/tv/22LB4510.html</link>
<language>en-US</language>
<image_link>https://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>https://www.example.com/electronics/tv/22LB4512.html</link>
<language>en-US</language>
<image_links>
<image_link>https://images.example.com/CLO-1029384-1.jpg</image_link>
<image_link>https://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>https://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="https://www.example.com"/>
<updated>2011-07-11T12:00:00Z</updated>
<item>
<id>NL_ZH_DH_HOTEL_X</id>
<title>Hotel The Hague</title>
<link>https://www.example.com/nl/zh/hotel_the_hague.html</link>
<image_link>https://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
Language | Identifier | Google category list |
---|---|---|
Deutsch | de-DE | Open list |
English | en-US | Open list |
Français | fr-FR | Open list |
Nederlands‎ | nl-NL | 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.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
Spotler Activate 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',
'size': 'M',
'color': 'Red',
'parent_id': 'TV'
'rating': 9.9
}
]
}
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
}
If product information is available, products are added to the event.
{
'event': 'sqzl_PersonalizationView',
'personalization_id': '123',
'personalization_variant_id': '10', // or 'control' when it's a control group
'control_variant': true, // optional
'products': [
{
'id': '123',
'title': 'Product title',
'price': '112.00', // price, without currency sign
'position': 1 // position of the product in the list,
}
] // 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. Spotler Activate 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.
Even though an overlay can contain one product, it's always placed in the array variable items.
Personalization variables
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 {{ pageview_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 |
|
2 | Crop to cover both provided dimensions |
|
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 |
|
4 | Ignore the aspect ratio of the input and stretch to both provided dimensions |
|
Built-in filters
Besides the filters above, there are Nunjuck built-in filtersFilter: 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.
When you want this to work when a value is empty a second parameter true is required.
Below an example of city fallback to 'Amsterdam' if the field is empty:
Do you live in {{ city|default('Amsterdam', true) }}?
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_text":"true", "custom_number":123}'>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 (or the amount of days provided in the closing modal settings of the variant).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 type="text/javascript">
var javascript = document.createElement('javascript');
javascript.type = 'text/javascript';
javascript.id = '_sqzl_antiFlicker';
javascript.src = 'https://squeezely.tech/p?hqs=1&m=&u=' + encodeURIComponent(window.location.href);
javascript.async = true
document.head.appendChild(javascript);
</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>
Single-page Application
Some websites use the single-page application architecture. The traditional pageload browser event is not automatically triggered while navigating applications of this type.That's why we introduced the internal event PageReload which you can trigger whenever a page is dynamically rewritten without a hard refresh.
Triggering this event will reset the personalization as if the page was reloaded completely, causing all criteria to be re-evaluated.
<script type="text/javascript">
window._sqzl = window._sqzl || [];
window._sqzl.push({
"event" : "PageReload"
});
</script>
If you want to clear only certain personalizations or do not want to clear anything, you can use the removePersonalizations parameter:<script type="text/javascript">
window._sqzl.push({
"event" : "PageReload",
"removePersonalizations": [1, 4, 9] //will clear personalizations with id 1, 4 and 9
});
window._sqzl.push({
"event" : "PageReload",
"removePersonalizations": false //will clear no personalizations
});
</script>