---
title: Autocomplete API
description: Use the autocomplete API endpoint to get a search-as-you-type functionality.
slug: autocomplete/api/v2/autocomplete
docKind: endpoint
hub: autocomplete
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="GET" url="https://live.luigisbox.com/autocomplete/v2" />
  </div>
## Overview

The Autocomplete API provides search-as-you-type functionality. It is designed to return results quickly for incomplete search queries, suggesting items, categories, or other indexed content to the user as they type.

This endpoint supports several important features:

- **Typo correction:** Handle misspelled terms gracefully.
- **Personalization:** Re-rank results based on user history.
- **Filtering:** Restrict suggestions to specific categories or attributes.

<Aside type="tip">
  This endpoint is public and requires no authentication. We strongly recommend implementing it directly on the frontend to minimize latency. For guidance on when to use the API directly versus `Autocomplete.js`, see [Integration Best Practices](/autocomplete/guides/integration-best-practices/).
</Aside>
</ApiSection>

<ApiSection>
## Request parameters

To request autocomplete results, provide your tracker ID, the user's current query, and the object types you want to receive.

### Required parameters

| Parameter | Type | Required | Description |
| :-- | :-- | :-- | :-- |
| `tracker_id` | string | ✓ | Your unique site identifier within Luigi's Box. |
| `q` | string | ✓ | The partial user query, for example `iph`. |
| `type` | string | ✓ | Result types and counts in the format `type:count`. Example: `item:6,category:3`. |

### Optional parameters

#### Identity & personalization

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `user_id` | string | Identifier used for personalization. For authenticated users, use the analytics `customer_id`. For anonymous users, use the analytics `client_id`. Omit for non-personalized requests. See [User identification](/platform-foundations/api-principles/#user-identification) and [Events API common parameters](/analytics/api/events/#common-parameters). |
| `client_id` | string | Stable anonymous identifier. Must match the `client_id` sent in analytics. See [Events API common parameters](/analytics/api/events/#common-parameters). |

#### Filtering & sorting

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `f_type[]` | string | Filters results of a specific type. Format: `f_<type>[]=<field>:<value>`. Supports exact matches, OR logic with repeated parameters, and numeric or date ranges such as `price:10|50`. |
| `neg_f_type[]` | string | Excludes results of a specific type. Format: `neg_f_<type>[]=<field>:<value>`, where `<type>` matches one of the requested result types. Supports repeated parameters and numeric or date ranges such as `price:10|50`, including open-ended ranges like `price:10|`. |
| `sort_type` | string | Sorts results of a specific type. Format: `sort_<type>=<field>:<direction>`, for example `sort_item=price:asc`. |
| `prefer[]` | string | Boosts matching items without strictly filtering them. Format: `prefer[]=<field>:<value>`. Unlike `f_type[]`, this applies to every requested result type. |

#### Context & model selection

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `context` | string | Arbitrary placement context such as `mobile_header` or `checkout_page`. Use it to segment analytics by where the query originated. |
| `ctx[]` | string | Model-selection context in `key:value` format, for example `ctx[]=warehouse:berlin`. Keys must match contexts defined in [Analytics](/analytics/#concepts-context). |

#### Output control

| Parameter | Type | Description |
| :-- | :-- | :-- |
| `hit_fields` | string | Comma-separated list of fields to return, for example `title,url,price`. Request only what you render to reduce latency. |
| `non_collapsed_variants` | boolean | When `true`, returns all product variants instead of collapsing them into a parent hit. Default: `false`. |

### Request headers

| Header | Value | Required | Description |
| :-- | :-- | :-- | :-- |
| `Accept-Encoding` | `gzip, deflate` | Recommended | Enables compressed responses to reduce payload size. |

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

```shell
curl "https://live.luigisbox.com/autocomplete/v2?tracker_id=YOUR_TRACKER_ID&q=text&type=item:6" \
  -H "Accept-Encoding: gzip, deflate"
```
  </div>
</ApiSection>

<ApiSection>
## How to Make a Request

To make a valid request:

1. Send a `GET` request to `https://live.luigisbox.com/autocomplete/v2`.
2. Include `tracker_id`, the partial query `q`, and the desired `type` values.
3. URL-encode query parameters correctly.
4. Send `Accept-Encoding: gzip, deflate` for better performance.

For a step-by-step walkthrough, see [Quickstart: Query Suggestions](/quickstart/autocomplete/query-suggestions/).

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

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

luigisbox_host = 'https://live.luigisbox.com'
endpoint_path = '/autocomplete/v2'
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'] = 'text'
  req.params['type'] = 'item:6'
  req.headers['Accept-Encoding'] = 'gzip, deflate'
end

if response.success?
  puts JSON.pretty_generate(JSON.parse(response.body))
else
  puts "Error: HTTP Status #{response.status}, Response: #{response.body}"
end
```
      </div>
      <div slot="php">

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

use GuzzleHttp\Client;

$client = new Client();
$response = $client->request('GET', 'https://live.luigisbox.com/autocomplete/v2', [
    'query' => [
        'tracker_id' => 'your_tracker_id',
        'q' => 'text',
        'type' => 'item:6',
    ],
    'headers' => [
        'Accept-Encoding' => 'gzip, deflate',
    ],
]);

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

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

axios
  .get('https://live.luigisbox.com/autocomplete/v2', {
    params: {
      tracker_id: 'your_tracker_id',
      q: 'text',
      type: 'item:6',
    },
    headers: {
      'Accept-Encoding': 'gzip, deflate',
    },
  })
  .then((response) => {
    console.log(JSON.stringify(response.data, null, 2));
  })
  .catch((error) => {
    if (error.response) {
      console.error(`Error: HTTP Status ${error.response.status}`);
      console.error(JSON.stringify(error.response.data));
    } else {
      console.error(error.message);
    }
  });
```
      </div>
    </ApiCodeTabs>
  </div>
</ApiSection>

<ApiSection>
## Response structure

The response is a JSON object containing the requested hits and related metadata.

<Aside type="caution">
  Check `suggested_url` before rendering results. If it is present, your frontend should redirect the user immediately. See [Advanced Features](/autocomplete/guides/advanced-features/#fixits-and-redirects) for implementation details.
</Aside>

### Response attributes

| Field | Type | Description |
| :-- | :-- | :-- |
| `exact_match_hits_count` | integer | Number of hits matching the query exactly. |
| `partial_match_hits_count` | integer | Number of hits matched through typo tolerance or partial matching. |
| `partial_match_terms` | array | Terms used during partial matching or typo correction. |
| `hits` | array | The list of result objects. |
| `hits[].type` | string | Type of the result object, for example `item` or `category`. |
| `hits[].url` | string | Unique identity of the result object. |
| `hits[].updated_at` | string | ISO 8601 timestamp of the last update. |
| `hits[].attributes` | object | Indexed fields for the result. Highlighted strings can include `<em>` tags, and raw values are often available as `field.untouched`. |
| `hits[].pinned` | boolean | Present when the result was added by customization. |
| `campaigns` | array | Active banner or fixit campaigns for this query. |
| `suggested_url` | string | Redirect target when the query matches a redirect rule. |

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

```json
{
  "exact_match_hits_count": 6,
  "partial_match_hits_count": 0,
  "partial_match_terms": [],
  "hits": [
    {
      "url": "http://www.e-shop.com/products/123456",
      "attributes": {
        "image_link": "http://www.e-shop.com/assets/imgs/123.jpg",
        "title": "<em>Product</em> X",
        "title.untouched": "Product X",
        "price": "5.52 EUR",
        "availability_rank_text": "true"
      },
      "type": "item",
      "updated_at": "2017-11-23T00:00:00+00:00"
    }
  ],
  "campaigns": [
    {
      "id": 12,
      "target_url": "https://www.e-shop.com/promo",
      "banners": {
        "autocomplete_top": {
          "desktop_url": "https://www.e-shop.com/banner-1.jpg",
          "mobile_url": "https://www.e-shop.com/banner-2.jpg"
        }
      }
    }
  ],
  "suggested_url": null
}
```
  </div>
</ApiSection>

<ApiSection>
## Error handling

The API uses standard HTTP status codes to indicate success or failure.

| HTTP Status | Description |
| :-- | :-- |
| `200 OK` | The request succeeded and results are returned. |
| `400 Bad Request` | The request was malformed — missing or invalid parameters. |
| `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>
