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.

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.


    <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.

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 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, ISO-639-1-ISO-3166 alpha 2) 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
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99,
        "quantity": 2
    },
    {
        "id": "XYZ_789",
        "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",
          "language"             : "nl-NL",
          "products"             : [{
              "id": "ABC123",
              "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 (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, ISO-639-1-ISO-3166 alpha 2) 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
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99,
        "quantity": 2
    },
    {
        "id": "XYZ_789",
        "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: 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
email 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:

id Unique id or SKU. Mandatory
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99,
        "quantity": 2
    },
    {
        "id": "XYZ_789",
        "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"                : "Return",
          "email"                : "john@website.com",
          "currency"             : "EUR",
          "products"             : [{
              "id": "ABC123",
              "language": "nl-NL",
              "name": "Product 1",
              "price": 29.99,
              "quantity": 1
            }]
        });

    </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
language Customer language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2) 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
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99,
        "quantity": 2
    },
    {
        "id": "XYZ_789",
        "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
language Customer language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2) 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
name Name of the product.
price Price of the single product, 2 decimals.
category_ids JSON array of categories.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99
    },
    {
        "id": "XYZ_789",
        "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
language Customer language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2) Optional

Example


    <script type="text/javascript">

        window._sqzl = window._sqzl || [];

        window._sqzl.push({
          "event"       : "ViewCategory",
          "category_id" : "CAT-123"
        });

    </script>
                            


Event: Custom

You can add a custom event to target people with certain website behavior.

Available properties:
Name Description
event Your custom event name

  • Whitespace at the start and/or end of the event name will be removed.
  • Must contain at least one character.
  • May contain the following special characters: ( ) . / : + - _.
NOTE: Events will be ignored if the name does not match these requirements.
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 (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, ISO-639-1-ISO-3166 alpha 2) 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
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  [{"id": "ABC123"}]
Example 2:
[
    {
        "id": "ABC123",
        "name": "Produkt 1",
        "price": 29.99,
        "quantity": 2
    },
    {
        "id": "XYZ_789",
        "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>
                            


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
email 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
Example response:
{
    "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>
                            

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.

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.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);



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": [
        // ...
    ]
}

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);
                                    

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 (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, ISO-639-1-ISO-3166 alpha 2) 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:

id unique id or SKU. Mandatory
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.
language Product language (e.g. en-US, ISO-639-1-ISO-3166 alpha 2)
Example 1:
  ["id" => "ABC123", "price" => 29.99]
Example 2:
[
    [
        "id" => "ABC123",
        "name" => "Product 1",
        "price" => 29.99,
        "quantity" => 2
    ],
    [
        "id" => "XYZ_789",
        "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


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:

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
The current value will be removed if price is present and empty, 0 or null. The current value will not be changed when this field is not present.
sale_price 2 decimals, no thousands-separator. Optionally add currency. examples: 1099.99 or EUR 99.01 or 99 EUR
The current value will be removed if sale_price is present and empty, 0 or null. The current value will not be changed when this field is not present.
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
size Size of the product
color Color of the product
rating 1 decimal, no thousands-separator. examples: 2 or 2.6 or 9.9
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.
disabled Set to true if you want to disable the product. False to enable again. Note: Product in feed without this property will enable the product.
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",
            "size" : "M",
            "color" : "Red",
            "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,


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:

id unique id or SKU   Mandatory
language Default: en-US
ISO-639 + ISO-3166

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:

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 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/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
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
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
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/contactsPOST

You 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

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

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)
email 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}GET

Use 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 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>"
}


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
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
  • 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

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
email 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
Example response:
{
    "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"
                }
            ]
        }
    },
    ...
}
Name Description
Setting values Predefined field values:

URL location include type everywhere, equals, contains, starts_with, ends_with, regexp
URL location exclude type none, equals, contains, starts_with, ends_with, regexp
Countries ISO 3166-1 alpha-2 country codes
Cities Objects containing information from the geonames.org database

Response codes

HTTP status code Description HTTP codes
200 OK OK

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:
  1. 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.
  2. Create a binary representation of a HMAC hash by using the data from step 1, the `Webhook Key` using the SHA256 algorithm.
  3. Base64 encode the bytes obtained in the previous step.
  4. 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 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:

  1. Create a file containing the following code:
    importScripts('https://squeezely.tech/tracker/serviceworker.js');
  2. Name this file squeezely-worker.js
  3. 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:
<image_links>
    <image_link>http://images.example.com/TV_123456.png</image_link>
    <image_link>http://images.example.com/TV_654321.png</image_link>
</image_links>
or
<image_links>http://images.example.com/TV_123456.png</image_links>
<image_links>http://images.example.com/TV_654321.png</image_links>
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 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 containing 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.
categories Categories containing this product:
<categories>
    <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>
</categories>

Supported properties
property description
id SKU or your internal category id or reference. Mandatory
title Title of the category
description Description of the category
link Url of the category
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="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.

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
{{ 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.
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 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>

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>