> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alana.shopping/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Products

> Semantically search products with Algolia-compatible response format

## Authentication

All requests must include an API key via the `X-API-Key` header or `api_key` query parameter.

```bash theme={null}
curl -X POST https://alana.shopping/api/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ak_your_api_key" \
  -d '{"query": "camiseta azul"}'
```

## Rate Limits

| Level            | Limit          | Window   |
| ---------------- | -------------- | -------- |
| Per API key      | 1,000 requests | 1 minute |
| Per API key + IP | 100 requests   | 1 minute |

When a rate limit is exceeded, the response has status `429` with a `Retry-After` header indicating seconds until reset.

## Sorting

| Value                 | Description                 |
| --------------------- | --------------------------- |
| `relevance` (default) | Semantic similarity ranking |
| `price_asc`           | Price low to high           |
| `price_desc`          | Price high to low           |
| `newest`              | Most recently added         |
| `optimization_score`  | AI Commerce Score           |

## Pagination

* `page`: 0-based page number (default: 0)
* `hitsPerPage`: Results per page, max 100 (default: 20)

## Response Format

Compatible with [Algolia InstantSearch](https://www.algolia.com/doc/api-reference/api-methods/search/) for drop-in frontend integration.

<ResponseField name="hits" type="SearchHit[]" required>
  Array of matching products. Each hit includes `_highlightResult` with matched
  query terms wrapped in `<em>` tags.
</ResponseField>

<ResponseField name="nbHits" type="integer" required>
  Total number of matching results across all pages.
</ResponseField>

<ResponseField name="page" type="integer" required>
  Current page number (0-based).
</ResponseField>

<ResponseField name="nbPages" type="integer" required>
  Total number of pages.
</ResponseField>

<ResponseField name="hitsPerPage" type="integer" required>
  Number of results per page.
</ResponseField>

<ResponseField name="facets" type="object">
  Facet counts per attribute and value. Only populated when `facets` is
  specified in the request.

  ```json theme={null}
  { "brand": { "Nike": 12, "Adidas": 7 }, "availability": { "in_stock": 18 } }
  ```
</ResponseField>

<ResponseField name="processingTimeMs" type="integer" required>
  Query processing time in milliseconds.
</ResponseField>

<ResponseField name="correctedQuery" type="string">
  Spell-corrected query string, present only when different from input.
</ResponseField>
