ℹ️ This guide is intended to be used by developers.
Metrilo helps you track the events that the people visiting your shop do - viewing specific pages or products, adding products to the cart, making orders, etc. The provided data is transformed into different reports and analytics metrics you could benefit from.
For more information about Metrilo and its features please visit the official website.
- Quickstart guide
- API reference
- Importing resources
- Managing resources
- Tracking library installation
- Tracking events
- Form integration
ℹ️ If you decide to follow along, you'll end up with some resources that you (most probably) won't use in the future. However, that's perfectly fine - after you're done testing, you can just ping us and we'll reset your project to a pristine state.
Once you've signed up for a Metrilo account, navigate to the Settings -> Installation
page in your Metrilo project and keep your API Token
and API Secret
handy - you'll need them for the rest of this tutorial:
Now you need to import your shop's resources into Metrilo - categories, products, customers, orders. Then you can start registering actions on them - views, adds to cart, new orders.
Let's create a category, a product and a customer. We'll assume that:
- the current time (in milliseconds since 1970) is
1518004715732
- the API token of your Metrilo project is
sh0p-t0k3n
- the API secret of your Metrilo project is
m3trilo-secr3t
ℹ️ Metrilo API uses a custom X-Digest
header, which is an HMAC-SHA256 digest generated by using the request body string as the message and your Metrilo API secret as the key. You have to generate a separate digest for every resource call you make.
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "1", "name": "Awesome clothing", "url": "https://my-awesome-shop.com/awesome-clothing"} }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
1ecd57653821936c3f5aceb1c20f49a815efdd70ef1f15e5902397aa83187550
$ curl -X POST "https://trk.mtrl.me/v2/category" -i -H "Content-Type: text/plain" -H "X-Digest: 1ecd57653821936c3f5aceb1c20f49a815efdd70ef1f15e5902397aa83187550" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "1", "name": "Awesome clothing", "url": "https://my-awesome-shop.com/awesome-clothing"} }'
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "2", "categories": ["1"], "price": 10.42, "name": "Awesome T-Shirt", "url": "https://my-awesome-shop.com/awesome-clothing/awesome-t-shirt"} }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
ee51936b99eb682989a9b89a50be0d50653b304af33c9ef03208c9e03d0d0745
$ curl -X POST "https://trk.mtrl.me/v2/product" -i -H "Content-Type: text/plain" -H "X-Digest: ee51936b99eb682989a9b89a50be0d50653b304af33c9ef03208c9e03d0d0745" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "2", "categories": ["1"], "price": 10.42, "name": "Awesome T-Shirt", "url": "https://my-awesome-shop.com/awesome-clothing/awesome-t-shirt"} }'
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "johnybravo@gmail.com", "createdAt": 1518004715732 } }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
621f776ad036ffb7c52caa053c75bc97d3024aeb85acc1c431b807a76b61d62f
$ curl -X POST "https://trk.mtrl.me/v2/customer" -i -H "Content-Type: text/plain" -H "X-Digest: 621f776ad036ffb7c52caa053c75bc97d3024aeb85acc1c431b807a76b61d62f" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "johnybravo@gmail.com", "createdAt": 1518004715732 } }'
(We include the -i
param so that you can verify a 200 status code for all these requests)
(For all available properties for those resources, see the managing resources section and the full API documentation)
The next step is to install the frontend library. Add the following snippet to your website (preferably the <head>
tag):
<script type="text/javascript" src="https://trk.mtrl.me/tracking.js?token=sh0p-t0k3n"></script>
When you load that script, you should have access to a window.metrilo
object. That's what you're going to use to create tracking events on behalf of your customers.
Now let's create a user journey, calling the necessary frontend functions each step of the way:
- The customer
johnybravo@gmail.com
opens your homepage (but they are not logged in your website yet)
window.metrilo.viewPage('http://my-awesome-shop.com/', { name: 'Awesome homepage' }) // This would be called on your homepage
- They navigate to the 'Awesome clothing' category (category ID and all other IDs are from the shop's database and should be passed as strings)
window.metrilo.viewCategory('1') // This would be called on the 'Awesome clothing' category page
- They navigate to the 'Awesome T-shirt' product
window.metrilo.viewProduct('2') // This would be called on the 'Awesome T-Shirt' product page
- They add one 'Awesome T-Shirt' to the cart
window.metrilo.addToCart('2', 1) // This would be called when a user clicks an add to cart button
- They start checkout
window.metrilo.checkout() // This would be called whenever the customer starts the checkout process
At that point, all of the actions are done by an anonymous user. In order to associate them with a customer in Metrilo you will need to obtain their email - by asking them to login, from your order details form, or any other form. When you do - call the identify function with their email. After the idenfity call, all past and future actions will be attributed to this customer.
window.metrilo.identify('johnybravo@gmail.com') // This would be called whenever the customer provides their email address
- They submit the order
When they submit the order, you'll need to send the order event from your backend:
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "314", "createdAt": "1518004715732", "email": "johnybravo@gmail.com", "amount": "10.42", "status": "completed", "products": [{"productId": "2", "quantity": 1 } ] } }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
4401f8a26f2d2bf86df5354a8f7213464dd3da8368cf381af5494d518ba291c1
$ curl -X POST https://trk.mtrl.me/v2/order" -i -H "Content-Type: text/plain" -H "X-Digest: 4401f8a26f2d2bf86df5354a8f7213464dd3da8368cf381af5494d518ba291c1" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"id": "314", "createdAt": "1518004715732", "email": "johnybravo@gmail.com", "amount": "10.42", "status": "completed", "products": [{"productId": "2", "quantity": 1 } ] } }'
And that's it! Now when all events are processed by Metrilo, they will be attributed to the johnybravo@gmail.com
user. You can check that out in the Customer Database
tab in your Metrilo project.
ℹ️ Please allow for up to several minutes for all events to be processed.
ℹ️ If all backend calls return 200 and you're missing events - double check your input data.
Our API documentation is written according to the OpenAPI Specification. You can find all of the endpoints the Metrilo API serves and what parameters they require here.
ℹ️ The base url for each request is https://trk.mtrl.me/v2
. Don't forget that you need to add your Metrilo API token
as a token
parameter in the request body.
If you have integrated with the previous version of our API, the guide has been moved here.
A resource is a category, product, customer or order. Any time one of these changes on your backend, you should call the respective endpoint to create or update the resource in Metrilo. You can find more details for each endpoint in the documentation.
Endpoint | Usage |
---|---|
/customer | Create or update a single customer |
/category | Create or update a single category |
/product | Create or update a single product |
/order | Create or update a single order |
All calls to these endpoints have to be done from your backend - therefore, we don't provide any specific code examples as the implementation is bound to your backend logic and programming language.
ℹ️ Each backend call except /customer
must be sent with an additional custom header called X-Digest
, which is an HMAC-SHA256 digest generated by using the request body string as the message and your Metrilo API secret as the key. This list provides great examples in different programming languages, which can help you with the implementation.
ℹ️ Each Metrilo project has its own API Token
and multiple stores cannot point to the same Metrilo project.
ℹ️ Most of the time the data you send will override any existing data. For example, if you make a call about product A with categories C1 and C2 and then you make another call only with category C3, then the first two categories will be removed from the product. However, sometimes the data will be merged (e.g. adding a product's options). If the data is merged, it will be explicitly mentioned in the documentation.
ℹ️ Note that each request you send to Metrilo is limited to 5MB in size.
You can tag or untag existing Metrilo customers by calling the following endpoints from your backend.
Endpoint | Usage |
---|---|
/customer/tag | Adds tags to an existing customer (tags are merged, not overwritten) |
/customer/untag | Removes tags from an existing customer (missing tags are omitted) |
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "test@metrilo.com", "tags": ["foo"]} }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
ac9600a205af6aea7be1a4a3f8044d80fb9f4fb84ce9b550265650beefb12e4a
curl -X POST "https://trk.mtrl.me/v2/customer/tag" -i -H "Content-Type: text/plain" -H "X-Digest: ac9600a205af6aea7be1a4a3f8044d80fb9f4fb84ce9b550265650beefb12e4a" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "test@metrilo.com", "tags": ["foo"]} }'
$ echo -n '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "test@metrilo.com", "tags": ["foo"]} }' | openssl dgst sha256 -hmac 'm3trilo-secr3t'
a2fc3d7dbe351311b433a1cf54edf59ef96885f0dcd1ede6e508a5ceb4c98a89
curl -X POST "https://trk.mtrl.me/v2/customer/untag" -i -H "Content-Type: text/plain" -H "X-Digest: a2fc3d7dbe351311b433a1cf54edf59ef96885f0dcd1ede6e508a5ceb4c98a89" -d '{"time": 1518004715732, "token": "sh0p-t0k3n", "params": {"email": "test@metrilo.com", "tags": ["foo"]} }'
ℹ️ The X-Digest
header must be used here as well.
Before sending any tracking events to Metrilo, you need to import your data using the endpoints provided for each resource. Note that importing must be done in the order provided. You can find more details for each endpoint in the documentation.
# | Resource | Endpoint | Required |
---|---|---|---|
1. | Customers | /customer/batch |
Yes |
2. | Categories | /category/batch |
Yes |
3. | Deleted products | /product/batch |
Only if you want to import orders for products that no longer exist in your database |
4. | Products | /product/batch |
Yes |
5. | Orders | /order/batch |
Only if you want to sync any historical data with Metrilo |
ℹ️ The X-Digest
header must be used here as well.
Insert the following script tag in the page you want to track (we recommend inserting it in the <head>
tag):
<script type="text/javascript" src="https://trk.mtrl.me/tracking.js?token=<YOUR_PROJECT_TOKEN>"></script>
Replace <YOUR_PROJECT_TOKEN>
with the API token from within the Settings -> Installation
page in your Metrilo project.
ℹ️ Make sure to remove the <
and >
symbols. So, for instance, if your token was 1234asdf
, you would need to put in this snippet:
<script type="text/javascript" src="https://trk.mtrl.me/tracking.js?token=1234asdf"></script>
When you have successfully loaded the tracking library, you will have access to a window.metrilo
object on your page.
ℹ️ You should add the script tag on every page that you want to track!
A tracking event is an action that a customer of yours does on your website - such as viewing a page, adding an item to their cart, ordering a product, etc. These actions are saved in the customer's current session and are the base of which Metrilo does its magic.
These are the functions you need to call on the window.metrilo
object based on what a customer does on your website.
Whenever a customer | you need to call |
---|---|
enters their email on your website | identify |
enters their details on your website | customerDetails |
visits a page | viewPage |
visits an article page | viewArticle |
visits a category page | viewCategory |
visits a product page | viewProduct |
types something in the search bar | search |
adds a product to their cart | addToCart |
removes a product from their cart | removeFromCart |
visits the checkout page | checkout |
does anything you'd like to tag | applyTags |
does anything | customEvent |
ℹ️ Processing the calls to our API does not happen instantly - please allow for about a minute for them to be processed.
ℹ️ Keep in mind that if you try to send any tracking event for a resource that doesn't exist in Metrilo, your request won't be processed.
When a customer comes to the store and they are not logged in, Metrilo treats them as an anonymous customer by adding a unique identifier to their session (a cookie named cbuid), so that it could attribute their actions to this identifier. Once they provide an email (by logging in, signing up, filling in a subscription form, making an order, etc.) you need to call the identify function. This will associate the unique identifier with the email and all events that the customer had while being anonymous will be merged with the events they have as identified (if any).
It is enough to call identify
only once - the first time the customer enters their email. If you are unsure whether you have already called it - just check the value of the cbuid cookie. If there is an email - no need to call it. Otherwise it will contain the unique identifier mentioned above.
ℹ️ Sometimes customers will log out, use different devices, browsers or delete their cookies. Every time that happens Metrilo will create a new anonymous customer with a new unique identifier. However, once the customer identifies themselves (enters their email and you call metrilo.identify) Metrilo will check for the existence of a customer with the entered email and if there is one, it will merge them with the anonymous customer.
const email = 'johnnybravo@gmail.com' // Customer's email address
window.metrilo.identify(email)
Customer has entered their details on a web form. This call updates the first name, last name and subscribed status of an existing customer.
const params = {
firstName: 'Johny', // Customer's first name (optional)
lastName: 'Bravo', // Customer's last name (optional)
phoneNumber: '+46 100 200', // Phone number (optional)
subscribed: false // Subscribed status - true or false (optional)
}
window.metrilo.customerDetails(params)
Customer has visited a page on your website. It can be the homepage, or any other page.
const url = 'http://myshop.com/amazing-page' // Absolute URL to the visited page
const params = {
name: 'My Amazing page' // The name of the page in the shop
}
window.metrilo.viewPage(url, params)
Customer has visited an article page.
const articleId = '42' // Unique ID of article resource in the shop's database
const params = {
name: 'How to increase sales' // Article display name in the shop
url: 'http://myshop.com/how-to-increase-sales' // Landing page for the article resource
}
window.metrilo.viewArticle(articleId, params)
Customer has visited a category page.
const categoryId = '9912' // Unique ID of category resource in the shop's database
window.metrilo.viewCategory(categoryId)
Customer has visited a product page.
const productId = '312' // The ID of the product in the shop's database
window.metrilo.viewProduct(productId)
Customer has searched in the shop (this supports only a plain query string without further filtering).
const query = 'a plant' // Search query string that the visitor entered in the search form
const url = 'http://myshop.com/search/?s=a+plant' // The URL that the visitor landed on when submitting the search form
window.metrilo.search(query, url)
Customer has added a product to the cart.
const productId = '312' // The ID of the added product
const quantity = 2 // The quantity of added items
window.metrilo.addToCart(productId, quantity)
Customer has removed a product from the cart.
const productId = '312' // The ID of the removed product
const quantity = 1 // The quantity of removed items
window.metrilo.removeFromCart(productId, quantity)
Customer has started the checkout process.
window.metrilo.checkout()
Adds tags to a customer.
const tags = ['regular', 'big_spender'] // Tag labels that are assigned to the customer in the Metrilo application
window.metrilo.applyTags(tags)
Sends a custom event (anything you want to track).
const customEventName = 'paypal_payment' // The name of the custom event
window.metrilo.customEvent(customEventName)
You can integrate a form (such as a newsletter subscription form) with Metrilo using the function below, that will also create all necessary Metrilo events for you when the form is submitted:
window.metrilo.integrateForm({
formSelector: '#newsletter-form', // required - a regular css selector for the form
email: 'newsletter[fields][1]', // required - the name attribute of the "email" input field
firstName: 'newsletter[fields][0][first]', // optional - the name attribute of the "first name" input field
lastName: 'newsletter[fields][0][last]', // optional - the name attribute of the "last name" input field
phoneNumber: 'newsletter[fields][3]', // optional - the name attribute of the "phone number" field
subscribed: 'newsletter[fields][2][]', // optional - the name attribute of the "subscribed" checkbox
tags: ['newsletter-subscriber'], // optional - an array of tags to be applied
customEvent: 'newsletter-subscribed' // optional - a custom event to be sent
});
ℹ️ If you're loading the main Metrilo script asynchronously, you can use the window.metriloQueue
object to defer functions until Metrilo is loaded. For example:
(function() {
const f = function () {
window.metrilo.integrateForm({
formSelector: '#newsletter-form',
email: 'newsletter[fields][1]'
});
};
if ((typeof window.metrilo !== 'undefined') && (typeof window.metrilo.integrateForm !== 'undefined')) {
f();
} else {
window.metriloQueue = window.metriloQueue || [];
window.metriloQueue.push(f);
}
})();
The following error codes are valid for all endpoints:
Code | Message |
---|---|
200 | Success response. |
400 | Bad request from client. |
401 | Project token is invalid. |
402 | Project requires payment. |
403 | The IP that the request came from is ignored. |
500 | Error from server while processing request. |
502 | Error from server accepting request. |
For the backend endpoints, we have a couple of additional error codes:
Code | Message |
---|---|
401 | X-Digest header is not provided. |
403 | The provided X-Digest signature is invalid. |