Recombee Docs
Visit recombee.comStart Free
docs20User Documentation
adminuiAdmin UI
reql32ReQL
codeAPI Clients & Integrations
cookhatScenario Recipes
suitcaseMisc

Getting Started

The first thing you need is to set up a database at Recombee. Sign up for a free instant account at recombee.com if you haven't already.

Getting Started Schema

We provide client libraries (SDKs) for languages such as JavaScript, Java, Ruby, Python, .NET, PHP and more, which makes the integration very easy.

If you don't use any of the supported languages, you also have the ability to use the REST API directly. See the authentication page for more details.

How to integrate

Integration consists of four main parts:

Each of these parts can be achieved in multiple ways.

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

Sending Interactions

Interactions are the most valuable information for the algorithms in the recommender engine.

The interactions that you send are used by the recommender engine in finding out which items are popular, as well as which recommendations perform the best. There are multiple kinds of interactions that are supported.

For example, a Detail View is sent every time a user views the detail of an item, while a Purchase is sent every time a user completes the main desired goal (a conversion). In most cases, you will want to send multiple kinds of interactions as part of your integration.

Keep in mind that the names of interaction types may not have the same meaning in your business compared to how they are used in Recombee. For example, an event that is called a Purchase in Recombee may not necessarily mean that the user has bought something, but could also mean that the user replied to an advertisement or watched a video until the end.

You can send interactions using one of the following methods:

Using the API SDK

Sending interactions using the API SDK is very easy. Let's say we want to send a Detail View interaction for item xyz by user 2c169e:

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

const client = new recombee.ApiClient('myDb', publicToken, {region: 'us-west'});
client.send(new recombee.AddDetailView('2c169e', 'xyz'))
.then(function(res) {
	...
})
.catch(function(error) {
	...
});
Copy
import com.recombee.apiclientkotlin.RecombeeClient
import com.recombee.apiclientkotlin.util.Region
import com.recombee.apiclientkotlin.requests.*
import com.recombee.apiclientkotlin.exceptions.ApiException

val client = RecombeeClient(
    databaseId = "your-db-id",
    publicToken = "your-public-token",
    region = Region.UsWest
)

val request = AddDetailView(userId = "2c169e", itemId = "xyz")

client.send(request,
    { response ->
        ...
    },
    { exception ->
        ...
    }
)
// Alternatively, you can use sendAsync for coroutines instead of callbacks
Copy
let client = RecombeeClient(
    databaseId: "your-db-id",
    publicToken: "your-public-token",
    region: .usWest
)

let request = AddDetailView(userId: "2c169e", itemId: "xyz")

do {
    let response = try await client.send(request)
    // Handle the successful response
    print("Success: \(response)")
} catch {
    // Handle the error (e.g. ClientError or any other error)
    print("Error: \(error)")
}
Copy
from recombee_api_client.api_client import RecombeeClient, Region
from recombee_api_client.api_requests import *

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

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

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

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

var client = new recombee.ApiClient('myDb', privateToken, {region: 'us-west'});
client.send(new rqs.AddDetailView('2c169e', 'xyz', {timestamp: '2014-07-20T02:49:45+02:00', cascadeCreate: true}),
	(err, response) => {
	//...
	}
);
Copy
import (
    "github.com/recombee/go-api-client/v4/recombee"
    "time"
)

client, err := recombee.NewRecombeeClient("myDb", privateToken, "us-west")
if err != nil {
    panic(err)
}

_, err = client.NewAddDetailView("2c169e", "xyz").SetCascadeCreate(true).SetTimestamp(time.Unix(1712042581, 0)).Send()
Copy
POST /myDb/detailviews/ HTTP/1.0
Host: Based on the region of your DB, see https://docs.recombee.com/regions
Content-type: application/json

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

There are a few important parameters in the above code:

  • myDb is the name of the database you are sending data to (required),
  • publicToken or privateToken is the access token for the given database (required),
  • region is the region where your DB is located (recommended),
  • itemId is a unique identifier of the item (required),
  • userId is a unique identifier of the user (required). For anonymous users, you can use a session ID.

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 yet.
    If not specified, it is set to true in client-side SDKs and false in server-side SDKs.
    We recommend that you use this parameter to prevent errors in case the item or user doesn't exist yet.

Interactions also have optional parameters unique to each type, such as duration for Detail View or profit for Purchase. You can find the full list of parameters in the API documentation.

Handling Anonymous Users

You may encounter a situation where a user comes to the site as an anonymous user and logs into a regular account later. This is especially the case in e-commerce.

However, ideally, you want to track the interactions of the anonymous user before they log in and then use that data to provide better recommendations after they log in.

To achieve this, you can use the userId parameter of the interactions.

If the user is anonymous, you can use a session ID (or another ID that is unique to the given user or session) as the userId.

When the user logs in, you can send a Merge Users request to merge the anonymous user with the regular account. This way, all interactions of the anonymous user will be transferred to their account.

Reporting Successful Recommendations

Once you have integrated recommendations into your site or application, it is very important to report the success of these recommendations, as without it, the system will not be able to get precise feedback and improve the quality of future recommendations.

You can report a successful recommendation by adding a parameter called recommId to all interactions which are based on that recommendation. For example, if a user views an item that was recommended to them, you should send the recommId of that recommendation with the Detail View. If they then purchase the item, you should also send the recommId with the Purchase.

You can find the recommId in the Recommendation object that you receive from the API:

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

You can then use this value in an optional parameter in all interaction requests in all Recombee API SDKs, as well as in the Segment integration. For the API SDK, you can find a code example in the API Reference.

As a result of sending the recommId with your interactions, the models will be able to return better recommendations and you will also get precise success metrics in the Admin UI.

There need to be enough interactions in the system for it to produce quality recommendations, so it may take some time before the best recommendations are produced.

If you're looking to improve the performance of the models beforehand, we recommend that you submit a historical log of past interactions. To achieve this, you can use the Batch API endpoint to send multiple interactions in a single request.

Updating the Item Catalog

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

The data that you send about the items is used in multiple ways:

  • It can be used for filtering and boosting recommendation results with ReQL, allowing you to influence the recommender engine.
  • It can be returned when getting recommendations to show to the users, so that you don't have to make additional requests to your database to get the item details.
  • It is also used to compute the recommendations, especially when the items have very few interactions (e.g., newly added items).

There are two possible methods of updating the item catalog:

Using the API SDK

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

Defining Item Properties

Before sending the data, you first have to define the properties of the items that you want to submit to the system.

Creating an Item Property is in a way similar to adding a column to the table of items, while submitting an item is like adding a row to the table.

The following Item Property types are available:

  • string
  • int - integer number
  • double - floating point number
  • boolean - true / false
  • timestamp - UTC timestamp
  • set - a set of strings
  • image - URL of an image
  • imageList - array of image URLs

The default value for all created properties is null.

To create or remove Item Properties, you can use the appropriate API calls, or do it manually in the Admin UI.

For examples of properties that can be useful for the recommender engine, see Integration Tips.

Creating an Item Property

Sending Item Values

Let's say we've added some item properties to our database, and now want to set their values for a particular item xyz.

This can be done by using the Set Item Values request:

Copy
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
))
Copy
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
    }
))
Copy
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));
Copy
<?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
        ]
    ));
?>
Copy
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
));
Copy
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) => {
        //...
    }
);
Copy
_, err = client.NewSetItemValues("xyz", map[string]interface{}{
    "title":       "Television TV2305",
    "description": "HD resolution LED TV",
    "price":       200,
    "categories":  []string{"Electronics", "Televisions"},
    "deleted":     false,
    "image":       "http://examplesite.com/products/xyz.jpg",
}).SetCascadeCreate(true).Send()
Copy
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 parameter indicates that the item of the given itemId should be created if it does not exist in the database.

After sending the above request, you can check that the values have been successfully set in the Admin UI.

If you wish to send an entire catalog, sending a request for each item separately may be quite slow. To speed up the process, we recommend using Batch requests.

In addition to Item Properties, the system also supports User Properties. These work in a similar way, but are used to describe the users instead of the items. Learn more in the User Properties API section.

tip20
Tip

Still not sure on how to implement sending of the Item Catalog? See the Tutorial for more details.

Getting Recommendations

Now it's time to get some recommendations!

There are three possible ways to get recommendations onto your site:

Using the API SDK

We will use two endpoints:

  • Recommend Items to User - The system recommends items to a given user depending on the user's personal taste. This case can be used for example on your homepage.
  • Recommend Items to Item - The system recommends items that are related to a given item. The system can also take into account the target user, which can be useful on the page of a product or article, since the endpoint will give the user a list of related items that they might also be interested in.

Recommend Items to User

Getting 5 recommendations for user 2c169e is very easy:

Copy
client.send(new recombee.RecommendItemsToUser('2c169e', 5))
.then(function(res) {
    ...
})
.catch(function(error) {
    ...
});
Copy
val result = client.sendAsync(RecommendItemsToUser("2c169e", 5))

result.onSuccess { response: RecommendationResponse ->
    for (recommendedItem in response.recomms) {
        println("ID: ${recommendedItem.id}")
    }
}.onFailure { exception -> // ApiException
    println("Exception: $exception")
    // use fallback ...
}
Copy
let request = RecommendItemsToUser(
    userId: "2c169e",
    count: 5
)

do {
    let response = try await client.send(request)
    for recommendedItem in response.recomms {
        print("ID: \(recommendedItem.id)")
    }
} catch {
    print("Exception: \(error)")
    // use fallback ...
}
Copy
recommended = client.send(RecommendItemsToUser('2c169e', 5))
Copy
recommended = client.send(RecommendItemsToUser.new('2c169e', 5))
Copy
RecommendationResponse recommended = client.send(new RecommendItemsToUser("2c169e", 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();
}
Copy
<?php
    $recommended = $client -> send(new Reqs\RecommendItemsToUser("2c169e", 5));
?>
Copy
RecommendationResponse recommended = client.Send(new RecommendItemsToUser("2c169e", 5));
// Iterating over recommendations:
foreach(Recommendation r in recommended.Recomms)
{
    Console.WriteLine(r.Id);
}
Copy
client.send(new rqs.RecommendItemsToUser('2c169e', 5),
    (err, response) => {
    //...
    }
);
Copy

recommendReq := client.NewRecommendItemsToUser("2c169e", 5)

recommendRes, err := recommendReq.Send()
if err != nil {
    panic(err)
}

for _, rec := range recommendRes.Recomms {
    fmt.Println(rec.Id)
}

Copy
GET /myDb/recomms/users/2c169e/items/?count=5

An object with recommended items in field recomms is returned. It can look like this:

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

Besides the IDs of the recommended items, a unique recommId is returned.

If the user interacts with a recommended item (e.g. views, purchases, etc.), it is very important to set this recommId for that interaction.

As a result, you will get precise success metrics in the Admin UI metrics and the models will also be able to return better recommendations.

Recommend Items to Item

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

Copy
client.send(new recombee.RecommendItemsToItem('xyz', '2c169e', 10,
        {
            'scenario': 'product_detail',
            'returnProperties': true,
            'cascadeCreate': true
        }
))
.then(function(res) {
    ...
})
.catch(function(error) {
    ...
});
Copy
val request = RecommendItemsToItem(
    itemId = "xyz",
    targetUserId = "2c169e",
    count = 10,
    scenario = "product_detail",
    returnProperties = true,
    cascadeCreate = true
)

val result = sendAsync(request)
result.onSuccess { response: RecommendationResponse ->
    for (recommendedItem in response.recomms) {
        println("ID: ${recommendedItem.id}")
    }
}.onFailure { exception -> // ApiException
    println("Exception: $exception")
    // use fallback ...
}
Copy
let request = RecommendItemsToItem(
    itemId: "xyz",
    targetUserId: "2c169e",
    count: 10,
    scenario: "product_detail",
    cascadeCreate: true,
    returnProperties: true
)


do {
    let response = try await client.send(request)
    for recommendedItem in response.recomms {
        print("ID: \(recommendedItem.id)")
    }
} catch {
    print("Exception: \(error)")
    // use fallback ...
}
Copy
recommended = client.send(RecommendItemsToItem('xyz', '2c169e', 10,
                                                scenario='product_detail',
                                                return_properties=True,
                                                cascade_create=True))
Copy
recommended = client.send(RecommendItemsToItem.new('xyz', '2c169e', 10,
    {
    'scenario' => 'product_detail',
    'returnProperties' => true,
    'cascadeCreate' => true
    })
)
Copy
RecommendationResponse recommended = client.send(new RecommendItemsToItem("xyz", "2c169e", 10))
.setScenario("product_detail")
.setReturnProperties(true)
.setCascadeCreate(true);
Copy
<?php
    $recommended = $client -> send(new Reqs\RecommendItemsToItem('xyz', '2c169e', 10,
                                                            [
                                                                'scenario' => 'product_detail',
                                                                'returnProperties' => true,
                                                                'cascadeCreate' => true
                                                            ])
                                );
?>
Copy
RecommendationResponse recommended = client.Send(new RecommendItemsToItem("xyz", "2c169e", 10,
scenario: "product_detail",
returnProperties: true,
cascadeCreate: true));
Copy
client.send(new rqs.RecommendItemsToItem('xyz', '2c169e', 10,
        {
            'scenario': 'product_detail',
            'returnProperties': true,
            'cascadeCreate': true
        }
),
    (err, response) => {
    //...
    }
);
Copy

recommendReq := client.NewRecommendItemsToItem("xyz", "2c169e", 10).
    SetScenario("product_detail").
    SetReturnProperties(true).
    SetCascadeCreate(true)

recommendRes, err := recommendReq.Send()
Copy
GET /myDb/recomms/items/xyz/items/?count=10&targetUserId=2c169e&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 on 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:

  • 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).
  • Constraints, by which you can specify the number of allowed items in the recommendation response per category, brand, or other criteria.

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

You can also customize the above parameters via the API. For more details see the Recommendations API section.

Setting Logic & Filter in Admin UI
Setting Logic & Filter in the Admin UI

Recommend Item Segments

Recombee can also recommend Item Segments such as categories, genres, or brands. See Segmentations for more information, including how to set them up and use them for recommendations.

Tips and Tricks

Handling non-existent Users or Items
Infinite Scroll & Pagination
Recommending Users instead of Items
tip20
Tip

Still not sure on how to implement sending interactions & getting recommendations? See the Tutorial for more details.

Our personalized full-text search enhances the search experience on your site.

Besides recommendations, Recombee can also provide personalized search results. This means that the search results take into account the user's preferences and behavior, not just the search query.

There are three possible ways to implement search on your site:

Using the API SDK

Search can be implemented using the Search Items and Search Item Segments API endpoints.

Copy
client.send(new recombee.SearchItems('user-13434', 'search query', 5,
    {
        'scenario': 'search_top',
        'returnProperties': true,
        'cascadeCreate': true
    }
))
.then(function(res) {
    ...
})
.catch(function(error) {
    ...
});
Copy
val request = SearchItems(
    userId = "user-13434",
    searchQuery = "search query",
    count = 5,
    scenario = "search_top",
    returnProperties = true,
    cascadeCreate = true
)

client.send(request,
    { response: SearchResponse ->
        // Handle successful response here...
    },
    { exception: ApiException ->
        // Handle exception here...
    }
)
Copy
let request = SearchItems(
    userId: "user-13434",
    searchQuery: "search query",
    count: 5,
    scenario: "search_top",
    cascadeCreate: true,
    returnProperties: true
)

do {
    let response: SearchResponse = try await client.send(request)
    // Handle successful response here...
    print("Search response: \(response)")
} catch {
    // Handle error here...
}
Copy
matches = client.send(SearchItems('user-13434', 'search query', 5,
                                scenario='search_top',
                                return_properties=True,
                                cascade_create=True))
Copy
matches = client.send(SearchItems.new('user-13434', 'search query', 5,
    {
    'scenario' => 'search_top',
    'returnProperties' => true,
    'cascadeCreate' => true
    })
)
Copy
SearchResponse matches = client.send(new SearchItems("user-13434", "search query", 5))
.setScenario("search_top")
.setReturnProperties(true)
.setCascadeCreate(true);
Copy
<?php
    $matches = $client -> send(new Reqs\SearchItems('user-13434', 'search query', 5,
                                                        [
                                                            'scenario' => 'search_top',
                                                            'returnProperties' => true,
                                                            'cascadeCreate' => true
                                                        ])
                                  );
?>
Copy
SearchResponse matches = client.Send(new SearchItems("user-13434", "search query", 5,
scenario: "search_top",
returnProperties: true,
cascadeCreate: true));
Copy
client.send(new rqs.SearchItems('user-13434', 'search query', 5,
        {
            'scenario': 'search_top',
            'returnProperties': true,
            'cascadeCreate': true
        }
    ),
    (err, matches) => {
    //...
    }
);
Copy
searchReq := client.NewSearchItems("user-13434", "search query", 5).
    SetScenario("search_top").
    SetReturnProperties(true).
    SetCascadeCreate(true)

searchRes, err := searchReq.Send()
Copy
GET /myDb/search/users/user-13434/items/?searchQuery=query&scenario=search_top&returnProperties=true&cascadeCreate=true
© Copyright 2025, Recombee s.r.o
docs.recombee.com