# Search the catalog `GET /discovery/v1/search` Full-text search over the catalog. Rate limited: a ``429`` carries ``Retry-After``. ## Request example ```bash curl --request GET \ --url 'https://api.eu1.luigisbox.ai/discovery/v1/search?channel_id=&surface_id=&user_id=&personalize=false&filters=&size=10&mode=&debug=false&type=&query=&sort=&cursor=' \ --header 'x-lbx-visitor-id: ' \ --header 'user-agent: ' \ --header 'referer: ' \ --header 'Authorization: Bearer ' ``` ## Query Parameters | Name | Type | Required | Description | Constraints | |---|---|---|---|---| | `channel_id` | `string` | Yes | Channel identifier (serving destination). | >= 1 characters | | `surface_id` | `string` | Yes | Surface identifier, lbs__. The service segment must match the endpoint: lbs_search_* on /search, lbs_collection_* on /collections, lbs_recommender_* on /recommender. | >= 1 characters | | `user_id` | `string` | No | Logged-in user identifier. Optional; omitted/blank values are treated as anonymous. | — | | `personalize` | `boolean` | No | Whether to apply personalization. | — | | `filters` | `string` | No | Filter expression, for example 'brand = nike AND lbx:price < 100'. | <= 4096 characters | | `return_fields` | `Array` | No | Field projection list. Each entry is either '*' (alone, all fields) or a field path, optionally ending in '*' to take a whole subtree (e.g. 'attributes.title' or 'attributes.*'). '*' cannot be combined with other names. | <= 100 items | | `size` | `integer` | No | Maximum number of items to return. Must be between 1 and 100. | >= 1; <= 100 | | `mode` | `string` | No | Special mode flag; 'mock' returns a canned response. | — | | `debug` | `boolean` | No | Request ranking diagnostics. Honoured only on the first page for callers holding ``discovery:debug``; silently ignored otherwise. | — | | `type` | `string` | Yes | Object type to retrieve (e.g. 'product', 'category', 'article'). | >= 1 characters | | `query` | `string` | No | User input search query. | <= 256 characters | | `sort` | `string` | No | Sort expression, e.g. 'price:asc'. | <= 256 characters | | `cursor` | `string` | No | Opaque pagination cursor returned by a previous response. | <= 128 characters | ## Header Parameters | Name | Type | Required | Description | Constraints | |---|---|---|---|---| | `x-lbx-visitor-id` | `string` | Yes | Stable per-browser visitor identifier, generated client-side and persisted (e.g. a UUID in localStorage or a first-party cookie). Send it whether or not personalization is on: it is what links a request to a visitor's history and to the analytics events reporting it. Keep it stable across page loads, sessions and token refreshes; never generate it server-side, or every visitor collapses into one. | >= 1 characters | | `user-agent` | `string` | No | Originating client's User-Agent. Optional; used to derive the platform (ios, android, web) the result set is attributed to. A backend caller should forward the end user's value rather than its own. | — | | `referer` | `string` | No | Originating page URL. Optional; lets the result set be attributed to the page it was served on. | — | ## Responses | Status | Description | Content | |---|---|---| | `200` | Successful Response | application/json: object | | `400` | Malformed request | application/json: object | | `401` | Missing or invalid credentials | application/json: object | | `403` | Authenticated but not permitted | application/json: object | | `404` | Resource not found | application/json: object | | `422` | Request validation failed | application/json: object | | `429` | Rate limit exceeded | application/json: object | | `502` | Upstream service failed | application/json: object | ### 200 Successful Response #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `debug` | `anyOf(object, null)` | No | Ranking diagnostics — an open object whose contents carry no compatibility guarantee. Populated only when the caller passed ``debug=true`` AND holds the ``discovery:debug`` permission. Omitted from the response otherwise. | — | | `debug.*` | `any` | No | Additional property. | — | | `guid` | `string` | Yes | GUID identifying this result set. | — | | `hits` | `Array` | Yes | Ranked list of result hits — only objects this channel can serve. | — | | `hits[].@id` | `string` | Yes | Unique identity of the hit. | — | | `hits[].@type` | `string` | Yes | Type of the hit (e.g. 'product'). | — | | `hits[].*` | `any` | No | Additional property. | — | | `next_page_cursor` | `anyOf(string, null)` | Yes | Opaque cursor for the next page, or ``null`` when there is none — read ``pagination_status`` to tell why. Pass it back verbatim as ``cursor`` to fetch the next page. A page may return fewer than ``size`` hits *and* still carry a cursor: objects that are no longer servable are dropped from the page, so keep paging until the cursor is ``null``. | — | | `pagination_status` | `string` | Yes | Why this response does or does not carry a ``next_page_cursor``: ``more`` — more pages exist and ``next_page_cursor`` is set; ``exhausted`` — this was the last page; ``unsupported`` — this result set cannot be paged and retrying will not produce a cursor; ``unavailable`` — pagination state could not be saved for this request (a transient failure) and re-issuing the search may succeed. | allowed values: more, exhausted, unsupported, unavailable | | `total` | `anyOf(integer, null)` | Yes | Authoritative total across the whole result set, counting only the objects this channel can serve. ``null`` when the result set is larger than is counted exactly — fall back to ``total_approx`` in that case. Calling ``/facets`` for the same result set may fill it in. When the surface collapses variants, this counts variant groups, not individual objects. | — | | `total_approx` | `integer` | Yes | Approximate total for the whole result set, counting only the objects this channel can serve. Always present, so use it as the fallback when ``total`` is ``null``. It may be an estimate, so prefer ``total`` wherever that is set. | — | ##### Response example ```json { "debug": {}, "guid": "example", "hits": [ { "@id": "example", "@type": "example" } ], "next_page_cursor": "example", "pagination_status": "more", "total": 1, "total_approx": 1 } ``` ### 400 Malformed request #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 401 Missing or invalid credentials #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 403 Authenticated but not permitted #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 404 Resource not found #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 422 Request validation failed #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 429 Rate limit exceeded #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ``` ### 502 Upstream service failed #### application/json Schema: `object` ##### Attributes | Attribute | Type | Required | Description | Constraints | |---|---|---|---|---| | `exception_details` | `object` | No | Machine-readable error context; empty object when there is nothing to add. | — | | `exception_details.validation_errors` | `anyOf(Array, null)` | No | Every field-level problem found in the request, when validation is what failed. Absent when the rejection is not about a specific value. | — | | `exception_details.validation_errors[].loc` | `Array` | Yes | Path to the offending value from the request root, e.g. `["body", "filters", 0, "operator"]`. | — | | `exception_details.validation_errors[].msg` | `string` | Yes | What is wrong with the value at `loc`. | — | | `exception_details.validation_errors[].type` | `string` | Yes | Stable machine code for the problem, e.g. `missing` or `string_too_short`. | — | | `exception_details.*` | `any` | No | Additional property. | — | | `reason` | `string` | Yes | Human-readable, actionable error message. | — | | `request_id` | `anyOf(string, null)` | No | Request correlation ID (matches the X-Request-Id response header). | — | ##### Response example ```json { "exception_details": { "validation_errors": [ { "loc": [ "example" ], "msg": "example", "type": "example" } ] }, "reason": "example", "request_id": "example" } ```