> ## Documentation Index
> Fetch the complete documentation index at: https://client-integrations-api-dev.sequen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Module Recommendations API

Rank and score modules (such as shelves, carousels, or banners) along with their contained items in a single request. This endpoint unifies content placement decisions by treating modules as first-class entities that can be personalized based on user context.

<Info>
  Use this endpoint when you need to determine both which modules to display and how to order the items within each module.
</Info>

## Terminology

| Term       | Description                                                                       | Examples                            |
| ---------- | --------------------------------------------------------------------------------- | ----------------------------------- |
| **Item**   | A single, discrete entity that can be recommended or ranked                       | Product, offer, experience, article |
| **Module** | A container or grouping that holds/displays multiple items and can also be ranked | Shelf, carousel, banner             |

## Endpoint

```
POST /v1/recommend/module
```

### Request Body

<ParamField body="user_id" type="string" required>
  Unique identifier for the user.
</ParamField>

<ParamField body="item_model_id" type="string" required>
  The ID of the item ranking model to use for scoring and ordering items within modules.

  Example: `model_item-20250315_342VLPajymMOYwv9YqIzWjNUTv8`
</ParamField>

<ParamField body="module_model_id" type="string" required>
  The ID of the module ranking model to use for scoring and ordering modules.

  Example: `model_module-20250315_8kR2nQxT5vPjL9wYmBcDfH4sX7`
</ParamField>

<ParamField body="modules" type="array" required>
  An array of module objects to rank. Each module object contains:

  **Module Fields:**

  * `id` (string, required): Unique identifier for the module.
  * `items` (array, required): An array of item objects. Can be empty for modules that don't contain items.
  * `is_pre_ranked` (boolean, optional): If `true`, items within this module will not be re-ranked. Defaults to `false`.
  * `fixed_position` (number, optional): If provided, this module will be placed at the specified position (0-indexed) in the response, regardless of its score.
  * `limit` (number, optional): Maximum number of items to return for this module. If not specified, all ranked items are returned.

  **Item Fields (within `items` array):**

  * `id` (string, required): Unique identifier for the item.
  * `fixed_position` (number, optional): If provided, this item will be placed at the specified position (0-indexed) within the module, regardless of its score.
</ParamField>

```json Example Request theme={null}
{
    "user_id": "user_abc123",
    "item_model_id": "model_item-20250315_342VLPajymMOYwv9YqIzWjNUTv8",
    "module_model_id": "model_module-20250315_8kR2nQxT5vPjL9wYmBcDfH4sX7",
    "modules": [
      {
        "id": "carousel_featured",
        "fixed_position": 0,
        "is_pre_ranked": true,
        "items": [
          { "id": "item_12345" },
          { "id": "item_67890" },
          { "id": "item_abc123" }
        ]
      },
      {
        "id": "shelf_trending",
        "limit": 5,
        "items": [
          { "id": "item_def456" },
          { "id": "item_mno321" },
          { "id": "item_xyz789", "fixed_position": 2 },
          { "id": "item_pqr654" },
          { "id": "item_stu987" },
          { "id": "item_vwx246" }
        ]
      },
      {
        "id": "banner_promo",
        "items": []
      }
    ]
  }
```

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.sequen.com/v1/recommend/module \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "user_id": "user_abc123",
      "item_model_id": "model_item-20250315_342VLPajymMOYwv9YqIzWjNUTv8",
      "module_model_id": "model_module-20250315_8kR2nQxT5vPjL9wYmBcDfH4sX7",
      "modules": [
        {
          "id": "carousel_featured",
          "fixed_position": 0,
          "is_pre_ranked": true,
          "items": [
            { "id": "item_12345" },
            { "id": "item_67890" },
            { "id": "item_abc123" }
          ]
        },
        {
          "id": "shelf_trending",
          "limit": 5,
          "items": [
            { "id": "item_def456" },
            { "id": "item_mno321" },
            { "id": "item_xyz789", "fixed_position": 2 },
            { "id": "item_pqr654" },
            { "id": "item_stu987" },
            { "id": "item_vwx246" }
          ]
        },
        {
          "id": "banner_promo",
          "items": []
        }
      ]
    }'
  ```

  ```json JSON Body theme={null}
  {
    "user_id": "user_abc123",
    "item_model_id": "model_item-20250315_342VLPajymMOYwv9YqIzWjNUTv8",
    "module_model_id": "model_module-20250315_8kR2nQxT5vPjL9wYmBcDfH4sX7",
    "modules": [
      {
        "id": "carousel_featured",
        "fixed_position": 0,
        "is_pre_ranked": true,
        "items": [
          { "id": "item_12345" },
          { "id": "item_67890" },
          { "id": "item_abc123" }
        ]
      },
      {
        "id": "shelf_trending",
        "limit": 5,
        "items": [
          { "id": "item_def456" },
          { "id": "item_mno321" },
          { "id": "item_xyz789", "fixed_position": 2 },
          { "id": "item_pqr654" },
          { "id": "item_stu987" },
          { "id": "item_vwx246" }
        ]
      },
      {
        "id": "banner_promo",
        "items": []
      }
    ]
  }
  ```
</RequestExample>

## Response

<ResponseExample>
  ```json Example Response theme={null}
  {
    "rec_id": "rec_0ujsswThIGTUYm2K8FjOOfXtY1K",
    "modules": [
      {
        "id": "carousel_featured",
        "fixed_position": 0,
        "is_pre_ranked": true,
        "items": [
          { "id": "item_12345" },
          { "id": "item_67890" },
          { "id": "item_abc123" }
        ]
      },
      {
        "id": "shelf_trending",
        "score": 0.85432,
        "items": [
          { "id": "item_pqr654", "score": 0.92 },
          { "id": "item_def456", "score": 0.88 },
          { "id": "item_xyz789", "fixed_position": 2 },
          { "id": "item_stu987", "score": 0.85 },
          { "id": "item_mno321", "score": 0.75 }
        ]
      },
      {
        "id": "banner_promo",
        "score": 0.72341,
        "items": []
      }
    ]
  }
  ```
</ResponseExample>

<ResponseField name="rec_id" type="string">
  A unique identifier for this specific set of recommendations.

  Example: `rec_0ujsswThIGTUYm2K8FjOOfXtY1K`
</ResponseField>

<ResponseField name="modules" type="array" required>
  An array of ranked module objects with scores.

  **Module Object Fields:**

  * `id` (string, required): The unique identifier of the module
  * `score` (number): The ranking score assigned to this module by the model. Omitted if `fixed_position` is set for this module
  * `fixed_position` (number, optional): Present if the module was assigned a fixed position in the request
  * `is_pre_ranked` (boolean, optional): Present if the module was marked as pre-ranked in the request
  * `items` (array, optional): Array of item objects. For pre-ranked modules, items are returned in their original order without scores. For ranked modules, items include scores and are ordered by relevance (with fixed positions respected). Limited to the number specified by `limit` if provided. May be empty or omitted if the module has no items

  **Item Object Fields (within `items` array):**

  * `id` (string, required): The unique identifier of the item
  * `score` (number): The ranking score assigned to this item by the model. Omitted if `fixed_position` is set for this item or if the module is pre-ranked
  * `fixed_position` (number, optional): Present if the item was assigned a fixed position in the request
</ResponseField>

```json Example Response theme={null}
{
  "rec_id": "rec_0ujsswThIGTUYm2K8FjOOfXtY1K",
  "modules": [
    {
      "id": "carousel_featured",
      "fixed_position": 0,
      "is_pre_ranked": true,
      "items": [
        { "id": "item_12345" },
        { "id": "item_67890" },
        { "id": "item_abc123" }
      ]
    },
    {
      "id": "shelf_trending",
      "score": 0.85432,
      "items": [
        { "id": "item_pqr654", "score": 0.92 },
        { "id": "item_def456", "score": 0.88 },
        { "id": "item_xyz789", "fixed_position": 2 },
        { "id": "item_stu987", "score": 0.85 },
        { "id": "item_mno321", "score": 0.75 }
      ]
    },
    {
      "id": "banner_promo",
      "score": 0.72341,
      "items": []
    }
  ]
}
```

## Behavior Notes

* **Module Ranking**: All modules receive a score and are returned in ranked order, unless a `fixed_position` is specified.
* **Fixed Module Position**: When a module has `fixed_position` set, it will be placed at that specific position (0-indexed) in the response array and will not include a score. Other modules are ranked normally and fill remaining positions.
* **Modules Without Items**: Modules can be included without any items and will still be ranked against other modules. This is useful for ranking placement slots or banners independently.
* **Item Ranking**: Items within modules are ranked by relevance unless `is_pre_ranked: true` is set. Items include scores and are ordered by their ranking scores in the response.
* **Fixed Item Position**: When an item has `fixed_position` set, it will be placed at that specific position (0-indexed) within its module and will not include a score. Other items are ranked normally, include scores, and fill remaining positions.
* **Pre-ranked Modules**: When `is_pre_ranked: true`, the module's items are not re-ranked. The `items` array is returned in the original order without scores.
* **Item Limit**: When `limit` is specified for a module, the response will include at most that many items for that module, even if more items were provided in the request.
* **Unified Scoring**: Both module placement and item ordering are optimized in a single API call based on the user context.

## Use Cases

This endpoint is ideal for scenarios where you need to:

* Determine which content modules (carousels, shelves) to display on a page
* Personalize the order of items within each module
* Optimize homepage layouts with multiple recommendation sections
* A/B test different module configurations while maintaining item-level personalization
* Pin specific modules or items to fixed positions (e.g., always show a promotional banner first)
* Limit the number of recommendations per module to fit UI constraints
* Rank placement slots or banners independently, even without specific items

## Response Codes

<Accordion title="200 - OK">
  Successful response with ranked modules and items.
</Accordion>

<Accordion title="400 - Bad Request">
  Malformed JSON or invalid parameters in the request body.

  ```json Example Error Response theme={null}
  {
    "code": "validation_error",
    "message": "Invalid module configuration: modules array cannot be empty."
  }
  ```
</Accordion>

<Accordion title="401 - Unauthorized">
  Missing or invalid `Authorization` header in request headers.
</Accordion>

<Accordion title="422 - Validation Error">
  Input failed validation. Check that required fields are present and correctly formatted.
</Accordion>

<Accordion title="429 - Too Many Requests">
  Rate limit exceeded. Check the `Retry-After` header for when to retry.
</Accordion>

<Accordion title="5xx - Server Error">
  Temporary server issue. Please retry with exponential backoff.
</Accordion>
