Content Removal (DELETE)
Permanently delete one or more objects from your Luigi's Box search index using the DELETE /v1/content endpoint.
This endpoint requires HMAC authentication. Refer to the Authentication documentation for details.
Overview
This endpoint allows you to permanently delete one or more objects from your Luigi's Box search index. You specify which items to remove by providing their type
and identity
in the request body.
This is a permanent operation. Once an object is deleted, it will no longer appear in search results or autocomplete suggestions. This is the correct method for handling products that are sold out and will not be restocked.
https://live.luigisbox.com/v1/content
Request Parameters
The request body must be a JSON object containing a single root key, objects
, which holds an array of simple objects identifying what to delete.
Top-level Request Structure
Parameter | Type | Required | Description |
---|---|---|---|
objects |
Array | ✓ | An array of objects to be deleted from the index. |
Object structure
Each object in the objects
array requires only two keys to identify the content for removal.
Parameter | Type | Required | Description |
---|---|---|---|
identity |
String | ✓ | The unique identifier of the object you want to delete. |
type |
String | ✓ | The type of the object you want to delete (e.g., item , category , brand ). |
Example: Request Body (JSON)
{
"objects": [
{
"type": "item",
"identity": "B6B7CD9466295DCFDB62676CAE374289"
},
{
"type": "item",
"identity": "611526210E4585C7C8D5367F2CC42A57"
}
]
}
How to Send a Deletion Request
The examples show how to prepare and send a request to the API to delete content.
Authentication is required for all requests. The code demonstrates how to construct
the necessary headers, including Date
and Authorization
. The Authorization
header requires a
dynamically generated HMAC signature. For a detailed explanation of how to create this signature,
please refer to our main API Authentication guide.
Your Private Key is a secret and should never be exposed in client-side code (like frontend JavaScript). It should only be used on a secure server.
Your API Keys can be found in the Luigi's Box application under "General settings" > "Integration settings".
Code Examples
# --- Ruby Example for DELETE /v1/content ---
# Assumes 'faraday' gem is installed (gem install faraday)
require 'faraday'
require 'json'
require 'time'
require 'openssl'
require 'base64'
# Helper function for authentication
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}"
dg = OpenSSL::Digest.new('sha256')
Base64.strict_encode64(
OpenSSL::HMAC.digest(dg, private_key, data)
).strip
end
YOUR_PUBLIC_KEY = "your_public_api_key"
YOUR_PRIVATE_KEY = "your_private_api_key" # Keep secure!
LUIGISBOX_HOST = 'https://live.luigisbox.com'
ENDPOINT_PATH = '/v1/content'
product_data = [
{
"type": "item",
"identity": "B6B7CD9466295DCFDB62676CAE374289"
},
{
"type": "item",
"identity": "611526210E4585C7C8D5367F2CC42A57"
}
]
request_body_json = { objects: product_data }.to_json
http_method = 'DELETE'
content_type = 'application/json; charset=utf-8'
current_date = Time.now.httpdate
signature = generate_luigisbox_digest(
YOUR_PRIVATE_KEY, http_method, ENDPOINT_PATH,
current_date, content_type
)
authorization_header = "ApiAuth #{YOUR_PUBLIC_KEY}:#{signature}"
connection = Faraday.new(url: LUIGISBOX_HOST) do |conn|
conn.use FaradayMiddleware::Gzip
end
response = connection.delete(ENDPOINT_PATH) do |req|
req.headers['Content-Type'] = content_type
req.headers['Date'] = current_date
req.headers['Authorization'] = authorization_header
req.body = request_body_json
end
response_body = JSON.parse(response.body)
if response.success? && response_body['ok_count'] &&
response_body['ok_count'] > 0
puts "Product successfully deleted: " +
"#{JSON.pretty_generate(response_body)}"
else
puts "Error deleting product: HTTP Status " +
"#{response.status}, Response: #{response.body}"
end
<?php
// PHP Example for DELETE /v1/content
// Assumes Guzzle is installed:
// composer require guzzlehttp/guzzle
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));
}
$YOUR_PUBLIC_KEY = "your_public_api_key";
$YOUR_PRIVATE_KEY = "your_private_api_key"; // Keep secure!
$LUIGISBOX_HOST = 'https://live.luigisbox.com';
$ENDPOINT_PATH = '/v1/content';
$product_data = [
[
'identity' => 'B6B7CD9466295DCFDB62676CAE374289',
'type' => 'item',
],
[
'identity' => '611526210E4585C7C8D5367F2CC42A57',
'type' => 'item',
]
];
$request_body = ['objects' => $product_data];
$http_method = 'DELETE';
$content_type = 'application/json; charset=utf-8';
// Create HTTP-date string
// (e.g., "Tue, 22 May 2025 14:32:00 GMT")
$current_date = gmdate('D, d M Y H:i:s') . ' GMT';
$signature = generateLuigisboxDigest(
$YOUR_PRIVATE_KEY, $http_method,
$ENDPOINT_PATH, $current_date, $content_type
);
$authorization_header = "ApiAuth {$YOUR_PUBLIC_KEY}:{$signature}";
$client = new GuzzleHttp\Client();
$response = $client->request(
$http_method,
"{$LUIGISBOX_HOST}{$ENDPOINT_PATH}",
[
'headers' => [
'Accept-Encoding' => 'gzip, deflate',
'Content-Type' => $content_type,
'Date' => $current_date,
'Authorization' => $authorization_header,
],
'json' => $request_body
]
);
$response_body = json_decode($response->getBody(), true);
if($response->getStatusCode() == 200 &&
isset($response_body['ok_count']) &&
$response_body['ok_count'] > 0) {
echo "Product successfully deleted:" . PHP_EOL;
echo json_encode($response_body, JSON_PRETTY_PRINT);
} else {
echo "Error deleting product: HTTP Status " .
$response->getStatusCode() .
"\nResponse: " . $response->getBody();
}
const axios = require('axios');
const crypto = require('crypto');
function generateLuigisBoxDigest(privateKey, httpMethod,
endpointPath, dateHeader,
contentTypeHeader) {
const data = httpMethod + "\n" + contentTypeHeader + "\n" +
dateHeader + "\n" + endpointPath;
const hmac = crypto.createHmac('sha256', privateKey);
hmac.update(data);
return hmac.digest('base64').trim();
}
// Configuration
const YOUR_PUBLIC_KEY = "your_public_api_key";
const YOUR_PRIVATE_KEY = "your_private_api_key"; // Keep secure!
const LUIGISBOX_HOST = 'https://live.luigisbox.com';
const ENDPOINT_PATH = '/v1/content';
// Product data
const productData = [
{
"type": "item",
"identity": "B6B7CD9466295DCFDB62676CAE374289"
},
{
"type": "item",
"identity": "611526210E4585C7C8D5367F2CC42A57"
}
];
const requestBody = { objects: productData }
const httpMethod = 'DELETE';
const contentType = 'application/json; charset=utf-8';
// Create current date in HTTP date format
const currentDate = new Date().toUTCString();
const signature = generateLuigisBoxDigest(
YOUR_PRIVATE_KEY, httpMethod, ENDPOINT_PATH,
currentDate, contentType
);
const authorizationHeader =
"ApiAuth " + YOUR_PUBLIC_KEY + ":" + signature;
// Make the HTTP request with Axios
axios({
method: httpMethod,
url: LUIGISBOX_HOST + ENDPOINT_PATH,
headers: {
'Content-Type': contentType,
'Date': currentDate,
'Authorization': authorizationHeader
},
data: requestBody
})
.then(response => {
const responseBody = response.data;
if (response.status === 200 &&
responseBody.ok_count &&
responseBody.ok_count > 0) {
console.log("Product successfully deleted:",
JSON.stringify(responseBody, null, 2));
} else {
console.error("Error deleting product: " +
"HTTP Status " + response.status + ", " +
"Response: " + JSON.stringify(responseBody));
}
})
.catch(error => {
console.error("Exception:", error.message);
});
Error Handling
HTTP Status | Description |
---|---|
400 Bad Request | The request structure is invalid or the JSON is malformed. For example, an object in the array is missing the identity or type key. |
429 Too Many Requests | The API rate limit has been exceeded. Check the Retry-After header and see Throttling docs. |
Example: Error Response
{
"ok_count": 1,
"errors_count": 1,
"errors": {
"B6B7CD9466295DCFDB62676CAE374289": {
"type": "not_found",
"reason": "Identity not in catalog"
}
}
}
Related Endpoints
- Content Update - Create or replace objects
- Partial Content Update - Update specific fields only
- Update by Query - Bulk updates based on search criteria