Getting started

The first thing you need is your database at Recombee and the corresponding secret key. Create the free instant account at recombee.com, if you don’t have one yet.

We provide client libraries (SDKs) for javascript, Java, Ruby, Node.js, Python,.NET, and PHP, which makes the integration very easy. If you don’t use any of these languages, then you can use directly the REST API, but you need to implement authentication – the procedure is explained in the Authentication (HMAC) section along with examples in multiple programming languages.

How to integrate

Integration consist of three principal components:

It can be done in multiple ways:

  1. Server side integration

Server side integration
  1. Client (Widget/JavaScript) & Server side integration

Frontend (JavaScript) & Server side integration
  1. Client (Widget/JavaScript) side integration & Catalog feed

Client (JavaScript) side integration and Catalog feed

The recommendations are usually shown to a user at a website, in a mobile app or within an email campaign.

Send interactions

Interactions are the most valuable information for the algorithms in the recommender engine. There are multiple kinds of interactions in the system, but we will use just the following two for now:

  • detail-view - it will be sent to the system every time a user views a detail of an item

  • purchase - it will be sent every time a user completes the main desired goal (a conversion).

    Please note that while Recombee assigns the term purchase to those interactions, they can have various forms depending on your specific business case, e.g. replying to an advertisement in case of a job agency, viewing the whole video in case of IPTV platform, or buying a product from an online store can all be assigned as purchase.

A detail view of item xyz by user 2c169e575644d840838e is sent to the recommender with the following query:

// Import the library using npm or bower or using the script tag:
// <script src="https://cdn.jsdelivr.net/gh/recombee/js-api-client/dist/recombee-api-client.min.js"></script>

var client = new recombee.ApiClient('myDb', publicToken);
client.send(new recombee.AddDetailView('2c169e575644d840838e', 'xyz'),
    (err, response) => {
    //...
    }
);
from recombee_api_client.api_client import RecombeeClient
from recombee_api_client.api_requests import *

client = RecombeeClient('myDb', private_token)
client.send(AddDetailView("2c169e575644d840838e", "xyz", timestamp="2014-07-20T02:49:45+02:00", cascade_create=True))
require 'recombee_api_client'
include RecombeeApiClient

client = RecombeeClient.new('myDb', private_token)
client.send(AddDetailView.new('2c169e575644d840838e', 'xyz', {'timestamp' => '2014-07-20T02:49:45+02:00', 'cascadeCreate' => true}))
RecombeeClient client = new RecombeeClient("myDb", privateToken);
client.send(new AddDetailView("2c169e575644d840838e", "xyz")
    .setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-12-09 13:05:06") )
    .setCascadeCreate(true));
<?php
use Recombee\RecommApi\Client;
use Recombee\RecommApi\Requests as Reqs;

$client = new Client("myDb", private_token);
$client -> send(new Reqs\AddDetailView("2c169e575644d840838e", "xyz", ['timestamp' => "2014-07-20T02:49:45+02:00", 'cascadeCreate' => true]));
?>
using Recombee.ApiClient;
using Recombee.ApiClient.ApiRequests;
using Recombee.ApiClient.Bindings;

var client = new RecombeeClient("myDb", privateToken);
var datetime = DateTime.Parse("2014-07-20T02:49:45+02:00", null, System.Globalization.DateTimeStyles.RoundtripKind);
client.Send(new AddDetailView("2c169e575644d840838e", "xyz", timestamp: datetime, cascadeCreate: true));
var recombee = require('recombee-api-client');
var rqs = recombee.requests;

var client = new recombee.ApiClient('myDb', privateToken);
client.send(new rqs.AddDetailView('2c169e575644d840838e', 'xyz', {timestamp: '2014-07-20T02:49:45+02:00', cascadeCreate: true}),
    (err, response) => {
    //...
    }
);
POST /myDb/detailviews/ HTTP/1.0
Host: rapi.recombee.com
Content-type: application/json

Body:
{
  "itemId": "xyz",
  "userId": "2c169e575644d840838e",
  "timestamp": "2014-07-20T02:49:45+02:00",
  "cascadeCreate": true
}

Where

  • myDb is the name of your database :)

  • itemId is a unique identifier of the item.

  • userId is a unique identifier of the user. It might be for example a session ID for anonymous users.

Optional parameters:

  • timestamp is a UNIX timestamp or ISO 8601 date time of the view. If not specified, the current time is used.

  • cascadeCreate tells the system that it should create the item or the user if it doesn’t exist in the system yet. We don’t have to explicitly manage the user and item database in the system for now thanks to this parameter. It is set to true by default in the JavaScript client.

Sending a purchase is very similar:

client.send(new recombee.AddPurchase('2c169e575644d840838e', 'xyz'),
    (err, response) => {
    //...
    }
);
client.send(AddPurchase("2c169e575644d840838e", "xyz", timestamp="2015-09-10T04:29:55+02:00", cascade_create=True))
client.send(AddPurchase.new('2c169e575644d840838e', 'xyz', {'timestamp' => '2015-09-10T04:29:55+02:00', 'cascadeCreate' => true}))
client.send(new AddPurchase("2c169e575644d840838e", "xyz")
    .setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-12-09 14:15:17"))
    .setCascadeCreate(true));
<?php
$client -> send(new Reqs\AddPurchase("2c169e575644d840838e", "xyz", ['timestamp' => "2015-09-10T04:29:55+02:00", 'cascadeCreate' => true]));
?>
datetime = DateTime.Parse("2015-09-10T04:29:55+02:00", null, System.Globalization.DateTimeStyles.RoundtripKind);
client.Send(new AddPurchase("2c169e575644d840838e", "xyz", timestamp: datetime, cascadeCreate: true));
client.send(new rqs.AddPurchase('2c169e575644d840838e', 'xyz', {timestamp: '2015-09-10T04:29:55+02:00', cascadeCreate: true}),
    (err, response) => {
    //...
    }
);
POST /myDb/purchases/ HTTP/1.0
Host: rapi.recombee.com
Content-type: application/json

Body:
{
  "itemId": "xyz",
  "userId": "2c169e575644d840838e",
  "timestamp": 1348162550,
  "cascadeCreate": true
}

The quality of the recommendations heavily depends on the amount of the sent interactions so it may take some time before interactions are gathered and the best quality recommendations are produced. Submitting historical interactions should reduce this time.

Especially in e-commerce is very common that a user comes to the site as an anonymous user (identified by a session id) and logs into a regular account later. Then it’s useful to merge the anonymous user with the regular account, in order to enrich the regular account with interactions made before logging in. Use merge users request for this.

Manage item catalog

The second most important kind of data for the recommender system is information about the items (e.g., names, descriptions, categories).

Sent data about items can be used for filtering and boosting recommendation results with the ReQL and also for showing the recommended items to the users (see the next section). The items catalog is also used for computing the recommendations, especially in the case of items with a few interactions (for example newly added items).

For security reasons, it is possible to change the item catalog only from the server-side using the private token.

An alternative to using SDK for catalog synchronization is setting a catalog feed in the Recombee Admin UI. Skip to getting recommendations if you have already synchronized the properties using the catalog feed.

Adding item properties

Firstly you have to define the properties of items that you want to submit to the system. Setting an item property is somehow equivalent to adding a column to the table of items, so you can later assign some particular value of the property to each item. The properties may be of various types:

  • string

  • int - integer number

  • double - floating point number

  • boolean

  • timestamp - UTC timestamp

  • set - a set of strings

  • image - URL of an image

  • imageList - array with URLs of images

You can create the properties in the Admin UI.

Create *description* item property of type *string*

Alternatively, you can add them by calling the API:

client.send(AddItemProperty('description', 'string'))
client.send(AddItemProperty('title', 'string'))
client.send(AddItemProperty('price', 'double'))
client.send(AddItemProperty('categories', 'set'))
client.send(AddItemProperty('image', 'image'))
client.send(AddItemProperty('deleted', 'boolean'))
client.send(AddItemProperty.new('description', 'string'))
client.send(AddItemProperty.new('title', 'string'))
client.send(AddItemProperty.new('price', 'double'))
client.send(AddItemProperty.new('categories', 'set'))
client.send(AddItemProperty.new('image', 'image'))
client.send(AddItemProperty.new('deleted', 'boolean'))
client.send(new AddItemProperty("description", "string"));
client.send(new AddItemProperty("title", "string"));
client.send(new AddItemProperty("price", "double"));
client.send(new AddItemProperty("categories", "set"));
client.send(new AddItemProperty("image", "image"));
client.send(new AddItemProperty("deleted", "boolean"));
<?php
$client -> send(new Reqs\AddItemProperty("description", "string"));
$client -> send(new Reqs\AddItemProperty("title", "string"));
$client -> send(new Reqs\AddItemProperty("price", "double"));
$client -> send(new Reqs\AddItemProperty("categories", "set"));
$client -> send(new Reqs\AddItemProperty("image", "image"));
$client -> send(new Reqs\AddItemProperty("deleted", "boolean"));
?>
client.Send(new AddItemProperty("description", "string"));
client.Send(new AddItemProperty("title", "string"));
client.Send(new AddItemProperty("price", "double"));
client.Send(new AddItemProperty("categories", "set"));
client.Send(new AddItemProperty("image", "image"));
client.Send(new AddItemProperty("deleted", "boolean"));
client.send(new rqs.AddItemProperty('description', 'string'))
.then((response) => {
    return client.send(new rqs.AddItemProperty('title', 'string'));
})
.then((response) => {
    return client.send(new rqs.AddItemProperty('price', 'double'));
})
.then((response) => {
    return client.send(new rqs.AddItemProperty('categories', 'set'));
})
.then((response) => {
    return client.send(new rqs.AddItemProperty('image', 'image'));
})
.then((response) => {
    return client.send(new rqs.AddItemProperty('deleted', 'boolean'));
})
.catch((error) => {
    // ...
});
PUT /myDb/items/properties/description?type=string
PUT /myDb/items/properties/title?type=string
PUT /myDb/items/properties/price?type=double
PUT /myDb/items/properties/categories?type=set
PUT /myDb/items/properties/image?type=image
PUT /myDb/items/properties/deleted?type=boolean

The default value of the created properties is null.

Integration Tips section contains examples of properties that are useful for the recommender engine.

Send item values

Suppose we have created all the properties from the preceding example. Now we can set the values of these properties for a particular item xyz. It is done by the following request:

client.send(SetItemValues('xyz',
    {
      "title": "Television TV2305",
      "description": "HD resolution LED TV",
      "price": 200,
      "categories": ["Electronics", "Televisions"],
      "image": "http://examplesite.com/products/xyz.jpg",
      "deleted": False
    },
    cascade_create=True
))
client.send(SetItemValues.new('xyz',
  # values
  {
     'title' => 'Television TV2305',
     'description' => 'HD resolution LED TV',
     'price' => 200,
     'categories' => ['Electronics', 'Televisions'],
     'image' => 'http://examplesite.com/products/xyz.jpg',
     'deleted' => false
  },
  # optional parameters
  {
    'cascadeCreate' => true
  }
  ))
client.send(new SetItemValues("xyz",
            new HashMap<String, Object>() {{
                put("title", "Television TV2305");
                put("description","HD resolution LED TV");
                put("price", 200);
                put("categories", new String[]{"Electronics", "Televisions"});
                put("image", "http://examplesite.com/products/xyz.jpg");
                put("deleted", false);
            }}
        ).setCascadeCreate(true));
<?php
$client -> send(new Reqs\SetItemValues("xyz",
    // values
    [
      "title" => "Television TV2305",
      "description" => "HD resolution LED TV",
      "price" => 200,
      "categories" => ["Electronics", "Televisions"],
      "image" => "http://examplesite.com/products/xyz.jpg",
      "deleted" => false
    ],
    //optional parameters
    [
      "cascadeCreate" => true
    ]
));
?>
client.Send(new SetItemValues("xyz",
    new Dictionary<string, object>() {
        {"title", "Television TV2305"},
        {"description","HD resolution LED TV"},
        {"price", 200},
        {"categories", new string[] {"Electronics", "Televisions"}},
        {"image", "http://examplesite.com/products/xyz.jpg"},
        {"deleted", false}
    },
    cascadeCreate: true
));
client.send(new rqs.SetItemValues('xyz',
    // values
    {
     title: 'Television TV2305',
     description: 'HD resolution LED TV',
     price: 200,
     categories: ['Electronics', 'Televisions'],
     image: 'http://examplesite.com/products/xyz.jpg',
     deleted: false
    },
    // optional parameters
    {
    cascadeCreate: true
    }
    ),
    (err, response) => {
        //...
    }
);
POST /myDb/items/xyz HTTP/1.0
Host: rapi.recombee.com
Content-type: application/json

Body:
{
  "title": "Television TV2305",
  "description": "HD resolution LED TV",
  "price": 200,
  "categories": ["Electronics", "Televisions"],
  "deleted": false,
  "image": "http://examplesite.com/products/xyz.jpg",
  "!cascadeCreate": true
}

The cascadeCreate indicates that the item of the given itemId should be created if it does not exist in the database.

You can check that the values have been successfully set in the Admin UI.

Sending a whole large catalog via single requests may be quite slow – batch requests should be used for much faster execution.

Similar to item properties are user properties.

Now to sure yet how to implement sending of the items catalog? See the tutorial.

Get recommendations

Now it’s time to get the recommendations!

There are two possible ways how to get the recommendations:

  1. Create HTML Widget in the Admin UI

  • Use visual editor in the Admin UI and paste the produced embed code into your site

  1. Use SDK

  • Call the recommendation API endpoints and use your own code for showing the recommended items to your users

Using HTML Widget

Recombee Admin UI

Setting HTML Widget in the Admin UI

HTML Widgets are the easiest way how to get recommendations into your site.

Each Widget is linked to a Scenario - a place at your site where the recommendations are displayed. You can set various settings for each Scenario in the Admin UI (see this section) and the Scenario also defines the type (endpoint) of the recommendations:

  • Recommend items to user - The system recommends items to a given user depending on his/her personal taste. This case can be used for example at your homepage.

  • Recommend items to item - The system recommends items that are somehow related to a given item. The system can take into account also a target user, so this case is useful for example in a detail page of a product or article because item-based will give the user a list of related items that he/she might be also interested in.

To create a new Widget, log in to the Admin UI, navigate to your Database, and pick Widgets in the menu on the left and click Create Widget. If you don’t have a Scenario created yet, you will be prompted to create one.

You can set which item properties will be shown in the Widget and also all kinds of visual settings (e.g. font, colors, borders, and many more). You can also set how many items will be shown at different types of devices.

When you have the Scenario configured and you are satisfied with the design of the widget, you can display it at your site by pasting the generated javascript embed code into the source code of your website.

In the case of Recommend items to item you need to set the itemId embed code parameter to the ID of the currently displayed item.

Once you put the embed code into your website, you can modify the widget in Admin UI without any need to change the code of your website.

You can read more about the HTML Widget here.

Go to next section

Using SDK

We will use two endpoints:

  • recommend items to user - The system recommends items to a given user depending on his/her personal taste. This case can be used for example at your homepage.

  • recommend items to item - The system recommends items that are somehow related to a given item. The system can take into account also a target user, so this case is useful for example in a detail page of a product, or article because item-based will give the user a list of related items that he/she might be also interested in.

Getting 5 recommendations for user 2c169e575644d840838e is very easy:

client.send(new recombee.RecommendItemsToUser('2c169e575644d840838e', 5),
    (err, recommended) => {
    //...
    }
);
recommended = client.send(RecommendItemsToUser('2c169e575644d840838e', 5))
recommended = client.send(RecommendItemsToUser.new('2c169e575644d840838e', 5))
RecommendationResponse recommended = client.send(new RecommendItemsToUser("2c169e575644d840838e", 5));
//There are two easy ways for getting individual recommendations:
// 1. using getIds() method
String[] recomms = recommended.getIds();

// 2. iterating over recommendations
for(Recommendation r: recommended)
{
    r.getId();
}
<?php
$recommended = $client -> send(new Reqs\RecommendItemsToUser("2c169e575644d840838e", 5));
?>
RecommendationResponse recommended = client.Send(new RecommendItemsToUser("2c169e575644d840838e", 5));
// Iterating over recommendations:
foreach(Recommendation r in recommended.Recomms)
{
    Console.WriteLine(r.Id);
}
client.send(new rqs.RecommendItemsToUser('2c169e575644d840838e', 5),
    (err, recommended) => {
    //...
    }
);
GET /myDb/recomms/users/2c169e575644d840838e/items/?count=5

An object with recommended items in field recomms is returned. For example:

{
  "recommId": "968d7864-1d52-4525-a37f-d5b7dd86fe13",
  "recomms": [
    {
      "id": "item-146"
    },
    {
      "id": "item-462"
    },
    {
      "id": "item-463"
    },
    {
      "id": "item-1555"
    },
    {
      "id": "item-683"
    }
  ]
}

Getting recommendations based on item xyz which is viewed by user 2c169e575644d840838e is also easy:

client.send(new recombee.RecommendItemsToItem('xyz', '2c169e575644d840838e', 10,
      {
          'scenario': 'product_detail',
          'returnProperties': true,
          'cascadeCreate': true
      }
    ),
    (err, recommended) => {
    //...
    }
);
recommended = client.send(RecommendItemsToItem('xyz', '2c169e575644d840838e', 10,
                                               scenario='product_detail',
                                               return_properties=True,
                                               cascade_create=True))
recommended = client.send(RecommendItemsToItem.new('xyz', '2c169e575644d840838e', 10,
  {
    'scenario' => 'product_detail',
    'returnProperties' => true,
    'cascadeCreate' => true
  })
)
RecommendationResponse recommended = client.send(new RecommendItemsToItem("xyz", "2c169e575644d840838e", 10))
.setScenario("product_detail")
.setReturnProperties(true)
.setCascadeCreate(true);
<?php
$recommended = $client -> send(new Reqs\RecommendItemsToItem('xyz', '2c169e575644d840838e', 10,
                                                            [
                                                                'scenario' => 'product_detail',
                                                                'returnProperties' => true,
                                                                'cascadeCreate' => true
                                                            ])
                              );
?>
RecommendationResponse recommended = client.Send(new RecommendItemsToItem("xyz", "2c169e575644d840838e", 10,
scenario: "product_detail",
returnProperties: true,
cascadeCreate: true));
client.send(new rqs.RecommendItemsToItem('xyz', '2c169e575644d840838e', 10,
      {
          'scenario': 'product_detail',
          'returnProperties': true,
          'cascadeCreate': true
      }
    ),
    (err, recommended) => {
    //...
    }
);
GET /myDb/recomms/items/xyz/items/?count=10&targetUserId=2c169e575644d840838e&scenario=product_detail&returnProperties=true&cascadeCreate=true

In this case, three optional parameters were also set: scenario, returnProperties, and cascadeCreate.

A scenario defines a particular application of recommendations at your website, your mobile app or emailing campaign. Some examples can be homepage, watch-next, product-detail, cart, or emailing-after-purchase.

For each of the scenarios various parameters can be set in the Recombee Admin UI - you can set:

  • Logic, which specifies the desired behavior of the recommendation model.

  • Filters & Boosters, by which you specify your business rules (which items can be recommended and which items should be preferred).

See the Integration Tips for examples of typical scenarios in a particular domain (media, e-commerce, real estate, etc.) and suggested settings.

Setting Logic & Filter in GUI

Setting Logic & Filter in the Admin UI

If you prefer to set these parameters via API, see the details here.

By enabling returnProperties Recombee returns also properties (titles, links, image URLs, etc.) for the recommended items. You can use these data for showing the items to the users.

If the given user or item does not exist in the system yet (for example because the item catalog is updated periodically only once a day) the default behavior is to return an error (HTTP 404). Setting cascadeCreate=true tells the recommender to rather create the missing item/user instead. Some bestsellers/trending content will be recommended to these completely new (cold start) items/users without interactions and properties. cascadeCreate is set to true by default in the JavaScript client.

If the user scrolls down or goes to the next results page, you can show the user subsequent recommendation results by requesting Recommend next items endpoint. You can create an infinite scroll of recommendations by calling this endpoint repeatedly.

Recombee can also recommend users instead of items - check recommend users to item and recommend users to user requests.

Now to sure yet how to implement sending interactions & getting recommendations? See the tutorial.