---
title: Search API (POST)
description: Use the POST search endpoint for complex queries and filtering.
slug: search/api/v1/search-post
docKind: endpoint
hub: search
tableOfContents: true
---
import ApiSection from "../../../../../components/ApiSection.astro";
import ApiEndpoint from "../../../../../components/ApiEndpoint.astro";
import ApiCodeTabs from "../../../../../components/ApiCodeTabs.astro";
import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";

<ApiSection>
  <div slot="code">
    <ApiEndpoint method="POST" url="https://live.luigisbox.com/search" />
  </div>
## Overview

The POST search endpoint is designed for advanced use cases where filters need complex nested boolean logic or where the request body would become too large for URL parameters alone.

<Aside type="note">
  This endpoint is public and requires no authentication.
</Aside>
</ApiSection>

<ApiSection>
## Request parameters

The POST endpoint uses a hybrid approach: standard identification parameters stay in the URL, while the complex boolean logic is sent in the JSON body.

### URL parameters

| Parameter | Type | Required | Description |
| :-- | :-- | :-- | :-- |
| `tracker_id` | string | ✓ | Your unique Luigi's Box tracker identifier. |
| `q` | string |  | The user's search query. |
| `size` | integer |  | Number of hits to return. Default: `10`. |
| `page` | integer |  | Result page number. Default: `1`. |

<Aside type="tip">
  Refer to [Search API](/search/api/v1/search/) for the full list of supported URL parameters.
</Aside>

### Request body

| Parameter | Type | Required | Description |
| :-- | :-- | :-- | :-- |
| `filters` | object | ✓ | Structured boolean filter definition. Each top-level key is a content type such as `item`, and the value can contain nested `and`, `or`, and `not` arrays made of `filter` objects. |

### Request headers

| Header | Value | Required | Description |
| :-- | :-- | :-- | :-- |
| `Accept-Encoding` | `gzip, deflate` | Recommended | Enables compressed responses. |
| `Content-Type` | `application/json` | ✓ | Indicates that the request body is JSON. |

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

```shell
curl -X POST "https://live.luigisbox.com/search?tracker_id=179075-204259&q=guitar&f[]=type:product" \
     -H "Content-Type: application/json" \
     -d '{
       "filters": {
         "product": {
           "and": [
             {
               "or": [
                 { "filter": "brand:Fender" },
                 { "filter": "brand:Gibson" }
               ]
             },
             { "filter": "all_categories:Electric Guitars" },
             { "filter": "price_amount:200|1000" },
             {
               "not": [
                 { "filter": "brand:Fender Squier" }
               ]
             }
           ]
         }
       }
     }'
```
  </div>
</ApiSection>

<ApiSection>
## Request construction

Execute a `POST` request with `Content-Type: application/json`.

- Keep `tracker_id`, `q`, pagination, and other standard request parameters in the query string.
- Put only the complex `filters` object into the JSON payload.
- Use nested `and`, `or`, and `not` arrays when you need logic that cannot be expressed comfortably with repeated `f[]` values.

<div slot="code">
  <h4 class="code-section-title">Code Examples</h4>
  <ApiCodeTabs syncKey="search-post-api-request">
    <div slot="ruby">

```ruby
require 'faraday'
require 'json'

connection = Faraday.new(url: 'https://live.luigisbox.com')

response = connection.post('/search') do |req|
  req.params['tracker_id'] = '179075-204259'
  req.params['q'] = 'guitar'
  req.params['f[]'] = 'type:product'
  req.headers['Content-Type'] = 'application/json'
  req.body = {
    filters: {
      product: {
        and: [
          { or: [
            { filter: 'brand:Fender' },
            { filter: 'brand:Gibson' }
          ] },
          { filter: 'all_categories:Electric Guitars' },
          { filter: 'price_amount:200|1000' },
          { not: [{ filter: 'brand:Fender Squier' }] }
        ]
      }
    }
  }.to_json
end

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

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

use GuzzleHttp\Client;

$client = new Client();
$response = $client->post('https://live.luigisbox.com/search', [
    'query' => [
        'tracker_id' => '179075-204259',
        'q' => 'guitar',
        'f' => ['type:product'],
    ],
    'json' => [
        'filters' => [
            'product' => [
                'and' => [
                    ['or' => [
                        ['filter' => 'brand:Fender'],
                        ['filter' => 'brand:Gibson'],
                    ]],
                    ['filter' => 'all_categories:Electric Guitars'],
                    ['filter' => 'price_amount:200|1000'],
                    ['not' => [['filter' => 'brand:Fender Squier']]],
                ],
            ],
        ],
    ],
]);

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

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

axios
  .post(
    'https://live.luigisbox.com/search',
    {
      filters: {
        product: {
          and: [
            {
              or: [
                { filter: 'brand:Fender' },
                { filter: 'brand:Gibson' },
              ],
            },
            { filter: 'all_categories:Electric Guitars' },
            { filter: 'price_amount:200|1000' },
            { not: [{ filter: 'brand:Fender Squier' }] },
          ],
        },
      },
    },
    {
      params: {
        tracker_id: '179075-204259',
        q: 'guitar',
        'f[]': 'type:product',
      },
    }
  )
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    console.error(error);
  });
```
    </div>
  </ApiCodeTabs>
</div>
</ApiSection>

<ApiSection>
## HTTP Response

The response structure matches the `GET /search` endpoint and contains top-level `results` and `next_page` fields.

### Results fields

| Field | Description |
| :-- | :-- |
| `query` | Requested query string. |
| `corrected_query` | Query correction markup when the query was altered. |
| `total_hits` | Total number of hits for the requested type. |
| `hits` | Result objects for the requested type. |
| `facets` | Facets and their counts. |
| `filters` | Filters applied to the results. |
| `quicksearch_hits` | Results for secondary types requested via `quicksearch_types`. |
| `suggested_facet` | Optional facet suggested for narrowing the result set. |
| `suggested_url` | Optional redirect URL for direct-match or fixit behavior. |
| `campaigns` | Banner campaigns associated with the query. |

### Hit fields

| Field | Description |
| :-- | :-- |
| `url` | Unique identifier of the result object. |
| `attributes` | Catalog fields stored for the hit, such as title, brand, or price. |
| `pinned` | Present when the result was added by customization. |
| `type` | Result type, for example `item`. |
| `nested` | Nested objects associated with the hit, such as variants. |

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

```json
{
  "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",
          "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"
}
```
  </div>
</ApiSection>

<ApiSection>
## Error handling

The API uses standard HTTP status codes to indicate success or failure. The POST search endpoint accepts the same query parameters as the GET endpoint, so all parameter validation errors from the [Search API (GET)](/search/api/v1/) apply here as well.

| HTTP Status | Description |
| :-- | :-- |
| `200 OK` | The request succeeded and results are returned. |
| `400 Bad Request` | The request was malformed — missing parameters or invalid JSON body. |
| `404 Not Found` | The `tracker_id` does not match any known catalog. |
| `500 Server Error` | Internal error. If persistent, contact support. |
| `504 Gateway Timeout` | The request took too long to process. Retrying may succeed. |

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

<Tabs>
  <TabItem label="400 Bad Request">
```json
{
  "tracker_id": ["tracker_id must be filled"]
}
```
  </TabItem>
  <TabItem label="404 Not Found">
```text
Catalog for tracker_id: "your-tracker-id" not found.
```
  </TabItem>
</Tabs>
  </div>
</ApiSection>
