---
title: Export Customizations
description: Export all existing customizations for a tracker.
slug: recommendations/customization/export
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/export" />
  </div>
## Overview

Export matching customizations for a tracker. This is useful for backup, audit, or synchronization workflows.

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

<ApiSection>
## Request parameters

### Path parameters

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

### Query parameters

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `model` | string | Filter export by recommender model. |
| `tag` | string | Filter by a specific tag. |
| `target_type` | string | Filter by scope type: `item`, `criteria`, or `all`. |
| `target_identity` | string | Filter by a specific target item ID. |
| `remove_expired_pins` | boolean | Exclude pins that are already expired. |
| `remove_nonexisting_item_pins` | boolean | Exclude item pins that no longer exist in the catalog. |

### 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. |

  <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/export"
full_path="${base_path}?model=basket&target_type=item"
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}"
```
  </div>
</ApiSection>

<ApiSection>
## How to Make a Request

1. Build the HMAC string from the method, content type, date, and base resource path.
2. Exclude query parameters from the signed path for this endpoint.
3. Send the request with the filtering query parameters in the URL and the HMAC headers attached.

<div slot="code">
  <h4 class="code-section-title">Code Examples</h4>
  <ApiCodeTabs syncKey="recommendations-customization-export">
    <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}"
  Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', private_key, data)).strip
end

tracker_id = 'YOUR_TRACKER_ID'
base_path = "/v1/recommender/pin/#{tracker_id}/scopes/export"
request_full_path = "/v1/recommender/pin/#{tracker_id}/scopes/export?model=basket&target_type=item"
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('your_private_api_key', 'POST', base_path, date_header, content_type)

response = Faraday.new(url: 'https://live.luigisbox.com').post(request_full_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';
$basePath = "/v1/recommender/pin/{$trackerId}/scopes/export";
$requestPath = "/v1/recommender/pin/{$trackerId}/scopes/export?model=basket&target_type=item";
$contentType = 'application/json; charset=utf-8';
$date = gmdate('D, d M Y H:i:s') . ' GMT';
$signature = generateLuigisboxDigest('your_private_api_key', 'POST', $basePath, $date, $contentType);

$client = new Client();
$response = $client->request('POST', "https://live.luigisbox.com{$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 basePath = `/v1/recommender/pin/${trackerId}/scopes/export`;
const requestPath = `/v1/recommender/pin/${trackerId}/scopes/export?model=basket&target_type=item`;
const contentType = 'application/json; charset=utf-8';
const dateHeader = new Date().toUTCString();
const signature = generateLuigisBoxDigest('your_private_api_key', 'POST', basePath, dateHeader, contentType);

axios({
  method: 'POST',
  url: `https://live.luigisbox.com${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 the list of all matching customizations.

### Response attributes

| Field | Type | Description |
| :-- | :-- | :-- |
| `results` | array | List of customization objects. |

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

```json
{
  "results": [
    {
      "id": "199620b4-df1a-46e8-ab59-9e9ed9af7106",
      "model": "basket",
      "target_type": "item"
    },
    {
      "id": "b3e6e3c1-1a3b-4c2d-8e4f-2a3b4c5d6e7f",
      "model": "basket",
      "target_type": "all"
    }
  ]
}
```
  </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 `target_type`. |

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

```json
{
  "reason": "Validation error",
  "exception_details": {
    "target_type": ["Must be one of: item, criteria, all"]
  }
}
```
  </div>
</ApiSection>
