Get Customizations
Retrieve a list of existing customizations using complex criteria filtering.
Overview
Important This endpoint requires HMAC authentication.
Retrieve a list of existing customizations. This endpoint supports advanced filtering via a criteria object in the request body, and pagination via query parameters.
Authentication
This endpoint requires HMAC authentication. You must include the Date and Authorization headers. See Authentication for details.
https://live.luigisbox.tech/v1/recommender/pin/{TRACKER_ID}/scopes
Request Parameters
To list customizations, send a POST request to the endpoint with the tracker_id in the path. You can use query parameters for pagination and the request body for filtering.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
TRACKER_ID |
String | ✓ | Your unique tracker identifier. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
Integer | Number of customizations to return (Pagination). | |
offset |
Integer | Number of results to skip (Pagination). | |
model |
Array[String] | Filter by recommender model. Supports multiple values (e.g., model=basket&model=home). |
|
tag |
Array[String] | Filter by tags. Supports multiple values. | |
target_type |
Array[String] | Filter by scope type (item, criteria, all). |
|
target_identity |
Array[String] | Filter by specific item IDs. | |
sort |
Array[String] | Sort by attribute (e.g., created_at:desc). |
Request Headers
| Header | Value | Description |
|---|---|---|
Content-Type |
application/json |
Required. |
Date |
HTTP Date | Required for HMAC. |
Authorization |
Signature | Required for HMAC. |
Request Body (Filtering)
The request body accepts a JSON object with a criteria array for complex filtering.
Note See Criteria Structure for details.
Example Request
tracker_id="1234-5678"
private_key="your_private_api_key"
host="https://live.luigisbox.tech"
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}" </span>
-H "Authorization: ApiAuth ${tracker_id}:${signature}" \
-d ""
How to make a request
All requests to this endpoint must be authenticated using HMAC SHA-256. The examples on the right demonstrate the implementation in various languages, but the core logic follows these steps:
1. Construct the String to Sign
Create a string using the following components, separated by newlines (\n):
- HTTP Method:
POST - Content-Type:
application/json; charset=utf-8 - Date: The current timestamp in RFC 1123 format (e.g.,
Mon, 20 Jan 2025 12:00:00 GMT). - Request Path: The resource path excluding query parameters.
2. Generate the HMAC Signature
- Create an HMAC SHA-256 hash of the string above using your Private API Key.
- Encode the result in Base64 and trim whitespace.
3. Send the Headers
Include Date, Content-Type, and Authorization: ApiAuth {TRACKER_ID}:{SIGNATURE} in your request.
Example Code
require 'faraday'
require 'base64'
require 'openssl'
require 'json'
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.tech'
# Base path for signing (Must NOT include query parameters)
base_path = "/v1/recommender/pin/#{tracker_id}/scopes"
# Full path for request (Must include ALL filters here)
# Note: Filters like 'model' or 'tag' go in the URL, not the body.
request_path = "/v1/recommender/pin/#{tracker_id}/scopes?limit=10&offset=0&model=basket"
conn = Faraday.new(url: host)
http_method = 'POST'
content_type = 'application/json; charset=utf-8'
date_header = Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
signature = generate_luigisbox_digest(private_key, http_method, base_path, date_header, content_type)
authorization_header = "ApiAuth #{tracker_id}:#{signature}"
# Send POST request with empty body
response = conn.post(request_path) do |req|
req.headers['Date'] = date_header
req.headers['Content-Type'] = content_type
req.headers['Authorization'] = authorization_header
# No body is sent
end
puts response.body
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
function generateLuigisboxDigest($privateKey, $httpMethod, $endpointPath, $dateHeader, $contentTypeHeader) {
$data = "{$httpMethod}\n{$contentTypeHeader}\n{$dateHeader}\n{$endpointPath}";
$hash = hash_hmac('sha256', $data, $privateKey, true);
return trim(base64_encode($hash));
}
$TRACKER_ID = "YOUR_TRACKER_ID";
$YOUR_PRIVATE_KEY = "your_private_api_key";
$LUIGISBOX_HOST = 'https://live.luigisbox.tech';
$BASE_PATH = "/v1/recommender/pin/{$TRACKER_ID}/scopes";
// Filters like 'model' must be in the URL query string
$REQUEST_PATH = "/v1/recommender/pin/{$TRACKER_ID}/scopes?limit=10&offset=0&model=basket";
$http_method = 'POST';
$content_type = 'application/json; charset=utf-8';
$current_date = gmdate('D, d M Y H:i:s') . ' GMT';
$signature = generateLuigisboxDigest($YOUR_PRIVATE_KEY, $http_method, $BASE_PATH, $current_date, $content_type);
$authorization_header = "ApiAuth {$TRACKER_ID}:{$signature}";
$client = new GuzzleHttp\Client();
$response = $client->request($http_method, "{$LUIGISBOX_HOST}{$REQUEST_PATH}", [
'headers' => [
'Content-Type' => $content_type,
'Date' => $current_date,
'Authorization' => $authorization_header,
],
// No 'json' body is sent
]);
echo $response->getBody();
?>
const axios = require('axios');
const crypto = require('crypto');
function generateLuigisBoxDigest(privateKey, httpMethod, endpointPath, dateHeader, contentTypeHeader) {
const data = </span><span class="p">${</span><span class="nx">httpMethod</span><span class="p">}</span><span class="s2">\n</span><span class="p">${</span><span class="nx">contentTypeHeader</span><span class="p">}</span><span class="s2">\n</span><span class="p">${</span><span class="nx">dateHeader</span><span class="p">}</span><span class="s2">\n</span><span class="p">${</span><span class="nx">endpointPath</span><span class="p">}</span><span class="s2">;
const hmac = crypto.createHmac('sha256', privateKey);
hmac.update(data);
return hmac.digest('base64').trim();
}
const TRACKER_ID = "YOUR_TRACKER_ID";
const YOUR_PRIVATE_KEY = "your_private_api_key";
const LUIGISBOX_HOST = 'https://live.luigisbox.tech';
const BASE_PATH = /v1/recommender/pin/</span><span class="p">${</span><span class="nx">TRACKER_ID</span><span class="p">}</span><span class="s2">/scopes;
// Filters like 'model' must be in the URL query string
const REQUEST_PATH = /v1/recommender/pin/</span><span class="p">${</span><span class="nx">TRACKER_ID</span><span class="p">}</span><span class="s2">/scopes?limit=10&offset=0&model=basket;
const httpMethod = 'POST';
const contentType = 'application/json; charset=utf-8';
const dateHeader = new Date().toUTCString();
const signature = generateLuigisBoxDigest(YOUR_PRIVATE_KEY, httpMethod, BASE_PATH, dateHeader, contentType);
const authorizationHeader = ApiAuth </span><span class="p">${</span><span class="nx">TRACKER_ID</span><span class="p">}</span><span class="s2">:</span><span class="p">${</span><span class="nx">signature</span><span class="p">}</span><span class="s2">;
axios({
method: httpMethod,
url: </span><span class="p">${</span><span class="nx">LUIGISBOX_HOST</span><span class="p">}${</span><span class="nx">REQUEST_PATH</span><span class="p">}</span><span class="s2">,
headers: {
'Content-Type': contentType,
'Date': dateHeader,
'Authorization': authorizationHeader
}
// No 'data' property is sent
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
Response Structure
The response contains pagination metadata and a list of 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. |
The Response Object
{
"pagination": {
"offset": 0,
"limit": 10
},
"results": [
{
"id": "199620b4-df1a-46e8-ab59-9e9ed9af7106",
"model": "basket",
"target_type": "item",
"pin_definitions": []
}
]
}
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 (e.g., invalid sort or filter attribute). |
Error Responses
{
"reason": "Validation error",
"exception_details": {
"sort": ["Invalid sort attribute: 'unknown_field'"]
}
}