--- title: Selecting fields description: Use return_fields to control which catalog fields come back on a hit, and understand which fields your credentials can see at all. slug: discovery/fields docKind: guide hub: luigisbox-ai --- A hit carries catalog fields as top-level keys. Which ones arrive is decided by three things, in order: 1. **What your credentials may see.** A browser token never receives `private:` fields. 2. **What the surface returns by default.** Configured per surface. 3. **What you asked for** with `return_fields`. ## `return_fields` An array of field names in the request body: ```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-…' \ -H 'Content-Type: application/json' \ -d '{ "type": "product", "query": "shirt", "return_fields": ["@title", "price", "image_url", "url"] }' ``` | Form | Meaning | |---|---| | `price` | One field, by exact name | | `params.*` | Every field under a nested object | | `*` | Everything visible to your credentials | `*` must stand alone. Combining it with other names is a `422` — `*` already includes them. Limits: up to 100 fields per request, and 512 characters per name. `@id` and `@type` are always present on a hit, whether or not you list them. ## Ask for what you render A product card usually needs a handful of fields. Requesting them explicitly makes the response smaller: ```js const CARD_FIELDS = ['@title', 'price', 'list_price', 'image_url', 'url', 'availability']; const body = { type: 'product', query, return_fields: CARD_FIELDS }; ``` Different placements want different projections. An autocomplete row needs a title, a thumbnail and a price; a results-page card needs more; a product page needs everything. Keep one list per placement rather than one list for the whole integration. ## Field visibility Field visibility follows from the field name and from the credential you authenticated with; it cannot be overridden per request. | Field name | Example | Browser token | Server token | |---|---|---|---| | Plain | `color`, `price` | Visible | Visible | | `@` registered | `@id`, `@title`, `@category` | Visible | Visible | | `lbx:` derived | `lbx:group_primary` | Visible | Visible | | `private:` | `private:margin` | **Never** | Visible | Two consequences: - **Anything a shopper must not read belongs in `private:`.** Discovery requests and responses are visible in browser developer tools. A cost, a margin, a supplier code or an internal note in a plain field is public data. - **A server-side integration can see `private:` fields, so it decides what reaches the page.** If your backend renders search results, set `return_fields` to the fields you intend to display. Passing the whole hit through to your template exposes every field it carries. Asking for a `private:` field with a browser token is not an error; the field is absent from the response. See [How to structure your data](/concepts/catalog-object-model/#how-to-structure-your-data) for the writing side of this. ## Nested fields An attribute holding an object is addressed by dot-path: ```json { "@id": "product/sku-1001", "params": { "material": "cotton", "fit": "regular" } } ``` Address it either one field at a time or as a whole group: ```jsonc { "return_fields": ["params.material"] } // just that one { "return_fields": ["params.*"] } // the whole group ``` The same dot-path works in [filters](/discovery/filters/) and in facet fields. ## Finding out what exists Catalog metadata lists every attribute an object type carries, with its value shape: ```bash curl -G 'https://api.eu1.luigisbox.ai/catalog/v1/lbc_8w3k2p/types/product/attributes' \ --data-urlencode 'query=price' \ -H 'Authorization: Bearer ' ``` See [Catalog metadata](/indexing/catalog-metadata/). ## See also - [Catalog object model](/concepts/catalog-object-model/) — namespaces and what they mean - [Catalog metadata](/indexing/catalog-metadata/) — which fields a catalog holds - [Filters](/discovery/filters/) — the same field names, in filters - [Discovery overview](/discovery/overview/#anatomy-of-a-response)