Search API
Use the search endpoint to get a fulltext search functionality with advanced filtering options.
Overview
Use the search endpoint to get a fulltext search functionality with advanced filtering options.
To use this feature, we need to synchronize your product database with our search index. See Indexing the data for more details.
Luigi's Box Search can learn the best results ordering. In order to enable learning, you need to integrate Luigi's Box Search Analytics service with your website by following the instructions.
https://live.luigisbox.com/search
Request Parameters
Required parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
tracker_id |
string | ✓ | Your unique site identifier within Luigi's Box. |
q |
string | The user's search query. Optional if f[] (filters) are provided. |
Optional parameters
| Parameter | Type | Description |
|---|---|---|
f[] |
string |
Filter results using key:value syntax (e.g., category:Shoes).
Logic:
| for numeric/date ranges.
Example: price:10|100 (between), price:10| (min), price:|100 (max).
Special Values:
|
f_must[] |
string | Filters applied with strict AND logic. Use this when you need to combine multiple filters on the same field (e.g., "Must have tag A AND tag B"). |
size |
integer |
Number of hits to return.
Default: 10
Maximum: 200
|
sort |
string |
Sort order using field:direction syntax (e.g., price:asc, created_at:desc).
Warning: explicit sorting overrides the default AI relevance ranking. Note: Sorting by geo_location requires the context[geo_location] parameter.
|
sort_type |
string |
Sort order for specific result types. The syntax is sort_TYPE=field:direction.
Example: sort_item=price:asc
|
quicksearch_types |
string |
A comma-separated list of secondary content types to include in the search (e.g., category,brand). Results for these types are returned in the quicksearch_hits field.
|
facets |
string |
A comma-separated list of facets to retrieve. You can limit the number of values per facet using :count syntax (e.g., brand,color:5).
Default limit: 30 values per facet. |
dynamic_facets_size |
integer |
The maximum number of additional facets to return, automatically selected by AI based on relevance to the query.
Default: 0 (disabled).
|
page |
integer |
Which page of results to return.
Default: 1
|
from |
integer |
Result offset. Alternative to page.
Example: from=0 is equivalent to page=1.
|
use_fixits |
boolean |
Controls automatic typo correction and redirects.
Default: true (enabled). Set to false to disable.
|
prefer[] |
string |
Soft filters used for query-time boosting. Syntax is identical to f[] but these boost matching items rather than excluding non-matching ones.
|
hit_fields |
string |
A comma-separated list of fields to include in the response attributes object. Use this to reduce payload size.
|
remove_fields |
string | A comma-separated list of fields to exclude from the response. |
user_id |
string | The unique identifier of the user. Required for personalization and accurate analytics. |
client_id |
string |
The Analytics Client ID. Required only if the user_id parameter contains a custom logged-in ID (e.g., customer email or database ID).
|
ctx[] |
string |
Arbitrary context tags used for model selection (e.g., warehouse:berlin). These must match the contexts reported in your analytics.
|
qu |
boolean |
Enable Query Understanding (intent detection). If true, the system may return a suggested_url for redirects.
Requirement: You must also provide user_id.
|
non_collapsed_variants |
boolean |
If true, variants are returned as individual hits instead of being nested under a parent product.
Default: false
|
Context Parameters
| Parameter | Type | Description |
|---|---|---|
context[geo_location] |
string |
User coordinates in lat,lon format (e.g., 49.0448,18.5530). Required for distance filtering and sorting.
|
context[geo_location_field] |
string |
Specifies the custom field name in your catalog that contains item coordinates.
Default: geo_location
|
context[availability_field] |
string |
Specifies a custom field to use for availability ranking (must contain 0 or 1).
|
context[availability_rank_field] |
string | Specifies a custom field for detailed availability ranking (integer 1-15, where 1 is most available). |
context[boost_field] |
string | Specifies a custom field for numeric boosting (integer 0-3). |
context[freshness_field] |
string | Specifies a custom date field (ISO 8601) to use for freshness ranking. |
Request Headers
Consider sending request header of Accept-Encoding as well with values for supported encoding methods of your HTTP client, e.g. gzip or br, gzip, deflate for multiple supported methods. Encodings make the response from the JSON API considerably smaller and thus faster to transfer.
Example Request
curl "https://live.luigisbox.com/search?tracker_id=YOUR_TRACKER_ID&q=harry+potter&f[]=type:item" \
-H "Accept-Encoding: gzip, deflate"
How to make a request
To make a request to this endpoint, you need to send a GET request to the URL. The tracker_id parameter is required to identify your Luigi's Box account. You can typically find this in the Luigi's Box app. Ensure you handle the response and any errors as shown in the example code.
For a comprehensive, step-by-step tutorial on integrating this endpoint into your application, please refer to our Quickstart: Search guide.
Example Code
# --- Ruby Example for GET /search ---
# Assumes 'faraday' gem is installed (gem install faraday)
require 'faraday'
require 'json'
LUIGISBOX_HOST = 'https://live.luigisbox.com'
ENDPOINT_PATH = '/search'
TRACKER_ID = 'your_tracker_id'
connection = Faraday.new(url: LUIGISBOX_HOST) do |conn|
conn.use FaradayMiddleware::Gzip
end
response = connection.get(ENDPOINT_PATH) do |req|
req.params['tracker_id'] = TRACKER_ID
req.params['q'] = 'harry potter'
req.params['f[]'] = 'type:item'
req.headers['Accept-Encoding'] = 'gzip, deflate'
end
if response.success?
puts "Search results: " +
"#{JSON.pretty_generate(JSON.parse(response.body))}"
else
puts "Error: HTTP Status " +
"#{response.status}, Response: #{response.body}"
end
<?php
// PHP Example for GET /search
// Assumes Guzzle is installed:
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$LUIGISBOX_HOST = 'https://live.luigisbox.com';
$ENDPOINT_PATH = '/search';
$TRACKER_ID = 'your_tracker_id';
$client = new GuzzleHttp\Client();
$response = $client->request(
'GET',
"{$LUIGISBOX_HOST}{$ENDPOINT_PATH}",
[
'query' => [
'tracker_id' => $TRACKER_ID,
'q' => 'harry potter',
'f[]' => 'type:item'
],
'headers' => [
'Accept-Encoding' => 'gzip, deflate'
]
]
);
if($response->getStatusCode() == 200) {
echo "Search results:" . PHP_EOL;
echo json_encode(json_decode($response->getBody()), JSON_PRETTY_PRINT);
} else {
echo "Error: HTTP Status " .
$response->getStatusCode() .
"\nResponse: " . $response->getBody();
}
?>
const axios = require('axios');
// Search Request
const LUIGISBOX_HOST = 'https://live.luigisbox.com';
const ENDPOINT_PATH = '/search';
const TRACKER_ID = 'your_tracker_id';
axios.get(LUIGISBOX_HOST + ENDPOINT_PATH, {
params: {
tracker_id: TRACKER_ID,
q: 'harry potter',
'f[]': 'type:item'
},
headers: {
'Accept-Encoding': 'gzip, deflate'
}
})
.then(response => {
console.log("Search results:",
JSON.stringify(response.data, null, 2));
})
.catch(error => {
if (error.response) {
console.error("Error: HTTP Status " + error.response.status +
", Response: " + JSON.stringify(error.response.data));
} else {
console.error("Exception:", error.message);
}
});
HTTP Response
The response is a structured JSON object containing two top-level fields: results and next_page.
Results fields
| Field | Description |
|---|---|
query |
The requested query string. |
corrected_query |
Optional. Contains the HTML string of the query with typos fixed (e.g., <strike>sheos</strike> shoes).
Note: Returned only if the query was altered. |
total_hits |
Total number of hits found for the requested type. |
hits |
A list of result objects for the requested type. |
facets |
A list of facets and their counts.
Behavior: Facets that are currently being filtered will return all available options (to allow multi-select), while other facets will return only values relevant to the current search results. |
filters |
A list of filters that were applied to the results. |
quicksearch_hits |
A list of results for secondary types requested via quicksearch_types (e.g., matching categories or brands).
|
suggested_facet |
Optional. Indicates one facet evaluated as most useful for narrowing down the current result set. |
suggested_url |
Optional. A redirect URL if the system detects a direct match (e.g., a "Fixit" rule or strict intent). |
campaigns |
A list of banner campaigns associated with the query. |
Hit fields
| Field | Description |
|---|---|
url |
Unique identifier of the result object. |
attributes |
Object containing all stored fields from the catalog (e.g., title, price, brand). |
attributes.title.untouched |
The raw title string without any highlighting tags. Useful if you want to display the title cleanly without <em> tags.
|
type |
Type of the result (e.g., "item"). |
nested |
Array of nested objects (e.g., variants) associated with the hit. |
Example Response
{
"results": {
"query": "putter",
"corrected_query": "<strike>harry</strike><strike>potter</strike> <b>putter</b>",
"filters": [
"type:product"
],
"total_hits": 223,
"hits": [
{
"url": "/jucad-putter-right-hand/?variantId=2448462",
"attributes": {
"title": "Jucad <em>Putter</em> Right Hand",
"title.untouched": "Jucad Putter Right Hand",
"price_eur": "149 €",
"brand": [
"Jucad"
],
"categories": [
"Golfers",
"Clubs",
"Putters"
],
"image_link": "https://cdn.myshoptet.com/usr/demoshop.luigisbox.com/user/shop/detail/1817277.jpg",
"availability_rank_text": "In Stock"
},
"type": "item",
"nested": []
}
],
"facets": [
{
"name": "price_amount",
"type": "float",
"values": [
{
"value": "0.69|30.0",
"hits_count": 56,
"normalized_hits_count": 0.18
},
{
"value": "30.0|60.0",
"hits_count": 34,
"normalized_hits_count": 0.11
}
]
}
],
"offset": "20",
"campaigns": []
},
"next_page": "https://live.luigisbox.com/search?q=putter&tracker_id=179075-204259&page=2"
}
Error Handling
The API uses standard HTTP status codes to indicate success or failure.
| HTTP Status | Description |
|---|---|
| 200 OK | The request was successful and results are returned. |
| 400 Bad Request | The request was malformed (e.g., missing tracker_id). |
| 504 Gateway Timeout | The request took too long to process. Retrying might succeed. |
Example Error
{
"type": "malformed_input",
"reason": "incorrect parameters provided"
}