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

# Search & AI Endpoints

> API reference for the search and AI chat endpoints used by the Cartally widget.

The Cartally widget communicates with the Cartally proxy API. These endpoints are called automatically by the widget — you do not need to call them yourself unless building a custom frontend.

## Search endpoint

```
POST https://app.cartally.co/api/search
```

Performs a hybrid search (keyword + semantic) across the store's product catalog.

### Request body

| Field            | Type    | Required | Description                                                   |
| ---------------- | ------- | -------- | ------------------------------------------------------------- |
| `query`          | string  | Yes      | Search query text                                             |
| `language`       | string  | No       | Language code (e.g. `en`, `pl`). Auto-detected if omitted     |
| `currency`       | string  | No       | Currency code (e.g. `PLN`, `USD`). Auto-detected if omitted   |
| `limit`          | integer | No       | Results per page (1–100, default: 24)                         |
| `page`           | integer | No       | Page number (default: 1)                                      |
| `ai_search`      | boolean | No       | Enable AI-enhanced search (counts toward AI usage)            |
| `filters`        | object  | No       | Dynamic filter values (e.g. `{"attribute_color": ["black"]}`) |
| `include_facets` | boolean | No       | Return facet counts for filters                               |
| `session_id`     | string  | No       | Widget session ID                                             |

### Response

```json theme={null}
{
  "products": [
    {
      "id": "12345-black",
      "product_id": "12345",
      "product_name": "Mountain Bike Helmet",
      "product_description": "Lightweight helmet...",
      "product_categories": ["Helmets", "Safety"],
      "photos": ["https://myshop.com/img/helmet-black.jpg"],
      "url": "https://myshop.com/product/helmet",
      "price_pln": 19900,
      "price_eur": 4500,
      "attribute_color": ["black"]
    }
  ],
  "suggestions": ["mountain bike", "bike helmet", "road helmet"],
  "questions": ["What is the lightest helmet?"],
  "total_products": 42,
  "facets": { ... },
  "attribute_labels": { "attribute_color": "Color" },
  "color_hex_map": { "black": "#000000" }
}
```

### Authentication

The widget authenticates automatically via the `Origin` header. The proxy verifies that the requesting domain matches a registered shop.

A session token (JWT) is returned in the response headers on the first request and must be sent back in subsequent requests.

***

## AI Chat endpoint

```
POST https://app.cartally.co/api/ai/chat
```

Sends a natural-language query to the AI assistant. Returns a **streaming** response (Server-Sent Events).

### Request body

| Field        | Type   | Required | Description               |
| ------------ | ------ | -------- | ------------------------- |
| `query`      | string | Yes      | Natural-language question |
| `language`   | string | No       | Language code             |
| `currency`   | string | No       | Currency code             |
| `session_id` | string | No       | Widget session ID         |

### Headers

| Header                | Description                                          |
| --------------------- | ---------------------------------------------------- |
| `Origin`              | Your store domain (required)                         |
| `X-Widget-Session-ID` | Widget session ID                                    |
| `X-Ai-Session-ID`     | AI conversation session ID (for follow-up questions) |

### Response

The response is streamed as Server-Sent Events (SSE). Each event contains a chunk of the AI response with product references.

### Usage limits

AI chat requests count toward your plan's AI request limit. When the limit is reached, the endpoint returns HTTP 403.

***

## Rate limits

Both endpoints are rate-limited per session token and per IP address. The widget handles rate limiting automatically with appropriate error messages.
