---
title: Get Customizations
description: Retrieve a list of existing customizations using complex criteria filtering.
slug: recommendations/customization/get-customizations
docKind: endpoint
hub: recommendations
tableOfContents: true
---
import ApiSection from "../../../../components/ApiSection.astro";
import ApiEndpoint from "../../../../components/ApiEndpoint.astro";
import ApiCodeTabs from "../../../../components/ApiCodeTabs.astro";
import { Aside } from "@astrojs/starlight/components";

<ApiSection>
  <div slot="code">
    <ApiEndpoint method="POST" url="https://live.luigisbox.com/v1/recommender/pin/{TRACKER_ID}/scopes" />
  </div>
## Overview

Retrieve a list of existing recommendation customizations. This endpoint supports pagination through query parameters and additional filtering through query parameters or a `criteria` object in the request body.

<Aside type="caution">
  This endpoint requires HMAC authentication. See [Authentication](/platform-foundations/api-principles/#authentication) for the signing rules.
</Aside>
</ApiSection>

<ApiSection>
## Request parameters

Send a `POST` request with the `tracker_id` in the path. Pagination and simple filters go in the query string.

### Path parameters

| Parameter | Type | Required | Description |
| :-- | :-- | :-- | :-- |
| `TRACKER_ID` | string | ✓ | Your unique tracker identifier. |

### Query parameters

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `limit` | integer | Number of customizations to return. |
| `offset` | integer | Number of results to skip. |
| `model` | array[string] | Filter by recommender model, for example `model=basket&model=home`. |
| `tag` | array[string] | Filter by tags. |
| `target_type` | array[string] | Filter by scope type: `item`, `criteria`, or `all`. |
| `target_identity` | array[string] | Filter by specific target item IDs. |
| `sort` | array[string] | Sort by attribute, for example `created_at:desc`. |

### Request headers

| Header | Value | Description |
| :-- | :-- | :-- |
| `Content-Type` | `application/json; charset=utf-8` | Required. |
| `Date` | HTTP date | Required for HMAC. |
| `Authorization` | `ApiAuth {TRACKER_ID}:{SIGNATURE}` | Required for HMAC. |

### Request body

The body accepts a JSON object with a `criteria` array for advanced filtering. The criteria structure follows the same rules described in [Recommendations Customization](/recommendations/customization/).

  <div slot="code">
    <h4 class="code-section-title">Example Request</h4>

```shell
tracker_id="1234-5678"
private_key="your_private_api_key"
host="https://live.luigisbox.com"

base_path="/v1/recommender/pin/${tracker_id}/scopes"
query_params="?model=basket&limit=10&sort=created_at:desc"
full_path="${base_path}${query_params}"

method="POST"
content_type="application/json; charset=utf-8"
date=$(date -u "+%a, %d %b %Y %H:%M:%S GMT")

string_to_sign="$(printf "${method}\n${content_type}\n${date}\n${base_path}")"
signature=$(echo -n "${string_to_sign}" | openssl dgst -sha256 -hmac "${private_key}" -binary | base64)

curl -X ${method} "${host}${full_path}" \
  -H "Content-Type: ${content_type}" \
  -H "Date: ${date}" \
  -H "Authorization: ApiAuth ${tracker_id}:${signature}" \
  -d ""
```
  </div>
</ApiSection>

<ApiSection>
## How to Make a Request

All requests to this endpoint must be authenticated with HMAC SHA-256.

1. Build the string to sign from the HTTP method, content type, current date, and the resource path.
2. Exclude query parameters from the signed path for this endpoint.
3. Generate the Base64-encoded signature with your private key.
4. Send the request with `Date`, `Content-Type`, and `Authorization` headers.

<div slot="code">
  <h4 class="code-section-title">Code Examples</h4>
  <ApiCodeTabs syncKey="recommendations-customizations-list">
    <div slot="ruby">

```ruby
require 'faraday'
require 'base64'
require 'openssl'
require 'time'

def generate_luigisbox_digest(private_key, http_method, endpoint_path, date_header, content_type_header)
  data = "#{http_method}\n#{content_type_header}\n#{date_header}\n#{endpoint_path}"
  hash = OpenSSL::HMAC.digest('sha256', private_key, data)
  Base64.strict_encode64(hash).strip
end

tracker_id = 'YOUR_TRACKER_ID'
private_key = 'your_private_api_key'
host = 'https://live.luigisbox.com'
base_path = "/v1/recommender/pin/#{tracker_id}/scopes"
request_path = "/v1/recommender/pin/#{tracker_id}/scopes?limit=10&offset=0&model=basket"

date_header = Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
content_type = 'application/json; charset=utf-8'
signature = generate_luigisbox_digest(private_key, 'POST', base_path, date_header, content_type)

response = Faraday.new(url: host).post(request_path) do |req|
  req.headers['Date'] = date_header
  req.headers['Content-Type'] = content_type
  req.headers['Authorization'] = "ApiAuth #{tracker_id}:#{signature}"
end

puts response.body
```
    </div>
    <div slot="php">

```php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

function generateLuigisboxDigest($privateKey, $httpMethod, $endpointPath, $dateHeader, $contentTypeHeader) {
    $data = "{$httpMethod}\n{$contentTypeHeader}\n{$dateHeader}\n{$endpointPath}";
    return trim(base64_encode(hash_hmac('sha256', $data, $privateKey, true)));
}

$trackerId = 'YOUR_TRACKER_ID';
$privateKey = 'your_private_api_key';
$host = 'https://live.luigisbox.com';
$basePath = "/v1/recommender/pin/{$trackerId}/scopes";
$requestPath = "/v1/recommender/pin/{$trackerId}/scopes?limit=10&offset=0&model=basket";
$contentType = 'application/json; charset=utf-8';
$date = gmdate('D, d M Y H:i:s') . ' GMT';
$signature = generateLuigisboxDigest($privateKey, 'POST', $basePath, $date, $contentType);

$client = new Client();
$response = $client->request('POST', "{$host}{$requestPath}", [
    'headers' => [
        'Content-Type' => $contentType,
        'Date' => $date,
        'Authorization' => "ApiAuth {$trackerId}:{$signature}",
    ],
]);

echo $response->getBody();
```
    </div>
    <div slot="javascript">

```javascript
const axios = require('axios');
const crypto = require('crypto');

function generateLuigisBoxDigest(privateKey, httpMethod, endpointPath, dateHeader, contentTypeHeader) {
  const data = `${httpMethod}\n${contentTypeHeader}\n${dateHeader}\n${endpointPath}`;
  return crypto.createHmac('sha256', privateKey).update(data).digest('base64').trim();
}

const trackerId = 'YOUR_TRACKER_ID';
const privateKey = 'your_private_api_key';
const host = 'https://live.luigisbox.com';
const basePath = `/v1/recommender/pin/${trackerId}/scopes`;
const requestPath = `/v1/recommender/pin/${trackerId}/scopes?limit=10&offset=0&model=basket`;
const contentType = 'application/json; charset=utf-8';
const dateHeader = new Date().toUTCString();
const signature = generateLuigisBoxDigest(privateKey, 'POST', basePath, dateHeader, contentType);

axios({
  method: 'POST',
  url: `${host}${requestPath}`,
  headers: {
    'Content-Type': contentType,
    Date: dateHeader,
    Authorization: `ApiAuth ${trackerId}:${signature}`,
  },
}).then((response) => console.log(response.data));
```
    </div>
  </ApiCodeTabs>
</div>
</ApiSection>

<ApiSection>
## Response structure

The response contains pagination metadata and the list of matching customization objects.

### Response attributes

| Field | Type | Description |
| :-- | :-- | :-- |
| `pagination` | object | Metadata about the result set. |
| `pagination.total` | integer | Total number of items matching the filter. |
| `results` | array | List of customization objects. |

  <div slot="code">
    <h4 class="code-section-title">Example Response</h4>

```json
{
  "pagination": {
    "offset": 0,
    "limit": 10
  },
  "results": [
    {
      "id": "199620b4-df1a-46e8-ab59-9e9ed9af7106",
      "model": "basket",
      "target_type": "item",
      "pin_definitions": []
    }
  ]
}
```
  </div>
</ApiSection>

<ApiSection>
## Error handling

| HTTP Status | Description |
| :-- | :-- |
| `200 OK` | Success. |
| `401 Unauthorized` | Missing or invalid authentication. |
| `404 Not Found` | Tracker not found. |
| `422 Unprocessable Entity` | Validation error, for example an invalid sort field. |

  <div slot="code">
    <h4 class="code-section-title">Example Error</h4>

```json
{
  "reason": "Validation error",
  "exception_details": {
    "sort": ["Invalid sort attribute: 'unknown_field'"]
  }
}
```
  </div>
</ApiSection>
