--- title: Discovery overview description: The four discovery endpoints, the request body fields they share, and the shape of a result set. slug: discovery/overview docKind: concept hub: luigisbox-ai --- Discovery is the read side of Luigi's Box AI: you ask a configured **surface** a question and it answers with a ranked list of catalog objects. Four endpoints cover the whole surface area. | Endpoint | Ask it for | The request supplies | |---|---|---| | [`POST /discovery/v1/search`](/discovery/search/) | Results for a query | A search query | | [`POST /discovery/v1/collections`](/discovery/collections/) | A listing page | A scope, such as a category | | [`POST /discovery/v1/recommender`](/discovery/recommendations/) | Recommendations | Anchor objects, or nothing | | [`POST /discovery/v1/facets`](/discovery/facets/) | Filters for a result set | The `guid` of a previous result set | Two more endpoints support the first four: [object lookup](/discovery/objects/) fetches objects by reference without ranking them, and [variant resolution](/discovery/variants/) expands a product into its group. Every discovery endpoint is a `POST` that carries its inputs as a JSON body. Filters and sort are structured JSON objects. ## Anatomy of a request ```bash curl -X POST 'https://api.eu1.luigisbox.ai/discovery/v1/search?channel_id=lbn_4hj9tv&surface_id=lbs_search_main' \ -H 'Authorization: Bearer ' \ -H 'X-Lbx-Visitor-Id: 8f14e45f-ea0f-4b5c-9a1d-2b3c4d5e6f70' \ -H 'Content-Type: application/json' \ -d '{ "type": "product", "query": "running shoes", "size": 24 }' ``` Three inputs say *where* the request is being served, and they are on nearly every call: | Input | Where | What it names | |---|---|---| | `channel_id` | Query parameter | The serving destination — which storefront or market this is | | `surface_id` | Query parameter | The configured discovery unit answering the request | | `type` | Body field | Which kind of object you want back: `product`, `category`, `brand`, … | `channel_id` and `surface_id` are query parameters; everything the surface is asked goes in the JSON body. `channel_id` names the resource the request is authorized on, so leaving it out is a `400` rather than a `422`. The surface's intent has to match the endpoint. `lbs_search_main` belongs to `/search`; sending it to `/recommender` is rejected. See [Surface identifiers](/concepts/identifiers/#surface-identifiers). `type` is required and singular. An autocomplete panel showing products, categories and suggested phrases issues three requests, one per type. Each type gets its own ranking and its own result count. ## Body fields every ranked endpoint shares | Field | Default | Purpose | |---|---|---| | `filters` | none | Restrict results — see [Filters](/discovery/filters/) | | `return_fields` | surface default | Choose which fields come back — see [Selecting fields](/discovery/fields/) | | `size` | `10` | How many results. Max 100. | | `user_id` | anonymous | The signed-in shopper — see [Personalization](/discovery/personalization/) | | `personalize` | `true` | Whether to personalize this request | An unrecognised body field is a `422`. `/search` and `/collections` additionally take `sort` and `cursor`; see [Sorting and pagination](/discovery/sorting-and-pagination/). ## Required headers | Header | Required | Purpose | |---|---|---| | `Authorization: Bearer ` | Yes | A token for the `…/discovery` audience | | `Content-Type: application/json` | Yes | Every discovery endpoint takes a JSON body | | `X-Lbx-Visitor-Id` | Yes, except on `/facets` | Identifies the browser | | `User-Agent`, `Referer` | Optional | Improve traffic classification and reporting | A request without `X-Lbx-Visitor-Id` is rejected, except on `/facets`, which re-reads a result set the visitor was already identified for. Generate the identifier once per browser and keep it stable. See [Identifying the shopper](/api-basics/requests-and-responses/#identifying-the-shopper). ## Anatomy of a response ```json { "hits": [ { "@id": "product/sku-1001", "@type": "product", "@title": "Blue Cotton T-Shirt", "price": 29.9, "url": "https://example.com/products/blue-cotton-t-shirt" } ], "total": 412, "total_approx": 412, "guid": "3ab549eb64a20a0c", "next_page_cursor": "eyJvIjoyNCwic…", "pagination_status": "more" } ``` ### Hits are flat A hit is a flat JSON object. `@id` and `@type` are always present; everything else is the catalog fields the surface returns, under the names you indexed them with. There is no `attributes` wrapper and no per-field envelope: ```js hits.map((hit) => ({ id: hit['@id'], title: hit['@title'], price: hit.price })); ``` Which fields appear depends on the surface's configuration, your `return_fields`, and your credentials — a browser token never sees `private:` fields. See [Selecting fields](/discovery/fields/). ### Two totals | Field | Meaning | |---|---| | `total` | The exact count. `null` when the result set is too large to count exactly. | | `total_approx` | Always present. Use it when `total` is `null`. | For a result count in your UI, read `total ?? total_approx`. If the surface collapses variants, the count is of variant *groups*, not individual products — five sizes of one shirt count once. Calling [`/facets`](/discovery/facets/) on the result set upgrades `total` to an exact figure. ### The `guid` Every ranked response carries a `guid` identifying that result set. Pass it to [`/facets`](/discovery/facets/) to compute filters over the same results, and to [`/variants`](/discovery/variants/) when expanding groups from that page. It is opaque — do not parse it. ## A typical results page 1. `POST /search` with the query → hits, `total`, `guid`. 2. `POST /facets` with that `guid` → the filter sidebar. 3. Shopper picks a filter → `POST /search` again with `filters`, producing a new `guid`. 4. Shopper scrolls → `POST /search` again with `cursor` from `next_page_cursor`. 5. Report what was shown and clicked with [analytics events](/analytics/sending-events/). A surface learns from the interactions you report; without them its ranking does not improve. ## See also - [Search](/discovery/search/) · [Collections](/discovery/collections/) · [Recommendations](/discovery/recommendations/) - [Facets](/discovery/facets/) · [Filters](/discovery/filters/) · [Object lookup](/discovery/objects/) - [Sorting and pagination](/discovery/sorting-and-pagination/) · [Selecting fields](/discovery/fields/) - [Personalization](/discovery/personalization/) · [Product variants](/discovery/variants/) - [Business rules](/merchandising/business-rules/overview/) — shaping results by hand