Smart Sorting & Reranking

Instead of relying solely on Froomle’s algorithms to generate recommendations from scratch, you can supply your own candidate items and let Froomle rank them using its personalization engine. This is useful when you already have a set of items (e.g. a curated editorial list or search results) and want to present them in the most relevant order for each user.

For full field specifications and examples, see the Recommendations API Reference.

How it works

Smart sorting uses the list_content field within one recommendation request list. The exact behavior depends on whether the items in list_content have a fixed rank.

Shape list_content What Froomle can return Use when

Smart sorting request

Candidate items without rank.

The supplied candidates, sorted by predicted relevance. Froomle does not fill missing positions with unrelated items.

You already have the candidate set, for example search results or an editorial list, and only want Froomle to reorder it.

Request with fixed-rank items

Pinned items where every supplied item has rank.

The pinned items at their requested positions, plus normal Froomle recommendations for the remaining positions up to the requested list size.

You need to guarantee specific sponsored/editorial items while letting Froomle fill the rest.

Combined request

A mix of pinned items with rank and free candidates without rank in the same list.

Pinned items stay fixed. Free candidates are reranked into the open positions. Because free candidates are present, do not rely on unrelated items to fill gaps.

You need both constraints: a few guaranteed positions and a customer-owned candidate set for the remaining positions.

"Combined request" here means combined inside one recommendation list: ranked and unranked list_content entries together. It is not the same as sending multiple independent lists in one API request. You may batch multiple lists under lists, but each list keeps its own behavior.

Request format

Each item in the list_content array accepts the following fields:

  • id (required, string): the client item ID.

  • item_type (required, string): the item type, if not the default.

Smart sorting request
{
  "page_type": "home",
  "channel": "www",
  "device_id": "device-123",
  "user_id": "user-123",
  "lists": [
    {
      "list_name": "reranked",
      "list_size": 10,
      "list_content": [
        {"id": "item-1", "item_type": "article"},
        {"id": "item-2", "item_type": "article"},
        {"id": "item-3", "item_type": "article"},
        {"id": "item-4", "item_type": "article"}
      ]
    }
  ]
}

The response follows the standard recommendation response format. Items are returned in order of predicted relevance. If fewer supplied candidates are eligible than the requested list_size or limit, the response can be shorter; plain smart sorting does not backfill with unrelated recommendations.

Fixed-rank placement

You can also pin specific items to fixed positions by providing a rank field (1-indexed). When all supplied list_content items are fixed-rank items, the remaining positions are filled with other recommendations from the engine rather than from your candidate list.

  • rank (optional, integer): the position at which the item must appear.

Request with fixed-rank items
{
  "page_type": "home",
  "channel": "www",
  "device_id": "device-123",
  "lists": [
    {
      "list_name": "curated_feed",
      "list_size": 6,
      "list_content": [
        {"id": "promo-article", "item_type": "article", "rank": 1},
        {"id": "sponsored-item", "item_type": "article", "rank": 4}
      ]
    }
  ]
}

In this example, promo-article is locked at position 1 and sponsored-item at position 4. Positions 2, 3, 5, and 6 are filled by the recommendation engine.

Use fixed-rank placement to guarantee visibility for sponsored or editorial content while still personalizing the rest of the list.

Combining both modes

You can mix free and fixed-rank items in the same list. Items with a rank are pinned; items without a rank are reranked by the engine among the remaining positions. This is still one list, not two separate recommendation placements.

Combined request
{
  "page_type": "article_detail",
  "channel": "www",
  "device_id": "device-123",
  "context_item": "article_789",
  "context_item_type": "article",
  "lists": [
    {
      "list_name": "related",
      "list_size": 8,
      "list_content": [
        {"id": "item-1", "item_type": "article", "rank": 1},
        {"id": "item-2", "item_type": "article"},
        {"id": "item-3", "item_type": "article"},
        {"id": "item-4", "item_type": "article"}
      ]
    }
  ]
}

In this example, item-1 is fixed at position 1. item-2, item-3, and item-4 are the free candidate pool for the remaining positions. If those free candidates are not enough to fill list_size: 8, do not treat the empty positions as an error unless your integration expected more candidates to be eligible.

SDK support

The frontend SDK supports smart sorting on top of the same list_content request shape:

  • Programmatic JS: call smartSort({ list_name, candidates, getId, getItemType, getRank }) to send candidates and receive matched/sorted candidates.

  • Raw recommendation calls: getRecommendations(…​) can still send an explicit list_content field when the integration wants to own response mapping.

  • React: use useSmartSort(…​) and render returned entries through FroomleReco entry={entry} to keep automatic recommendation attribution.

  • Declarative DOM: mark a container with data-froomle-smart-sort and direct children with data-froomle-smart-sort-item plus data-froomle-id; the SDK reorders the children and stamps matched recommendation metadata.

For complete SDK syntax, see Smart Sorting and Reranking with the SDK.