# Lists

> Rows of products for your pages, such as Popular or New arrivals, and menus of a field's values with their counts. Built ahead and served from a cache, so they aren't searches.

A list is a named row your pages show: **Popular**, **New arrivals**, **On sale**, a holiday's products, or a menu of themes or categories with how many products each has. You set it up once, and your pages ask for it by its ID:

```ts
const [popular, themes] = await client.lists(["popular", "themes"])
```

Each list is a filter and a sort, with products pinned first or hidden. Findlane builds it ahead of time and keeps it in a cache near your shoppers, so a page gets its lists in a few milliseconds. **List requests aren't searches:** they never count toward your plan's searches.

You can rename, reorder or change a list without touching your site's code.

## Set one up

In the dashboard, open an index and choose **Lists**, then **New list**. Give it an ID (such as `popular` or `new-arrivals`), a title your pages can show, and choose what it holds:

- **Products:** a row of products from [filters](/docs/search.md#filters) and one of the index's sorts, such as popularity or newest first. Without a sort, it uses the index's default.
- **Values of a field:** a facet field's values with how many products each has, the most first or by name. Use it for a menu of themes, brands or categories.

The editor shows what the list holds as you change it. Hover a product or value to pin it first or hide it from the list, or search the index to pin a product that isn't in the row.

Agents can set lists up too, with the `save_list` [tool](/docs/agents.md). Servers can use the [API](/docs/api.md#lists) or the [server SDK](/docs/server-sdk.md#lists).

### Settings

| Setting                | Products                                                                          | Values of a field                                        |
| ---------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `source`               | `sort` (the default)                                                              | `values`                                                 |
| `title`                | What a page may show above the row, up to 100 characters.                         | The same.                                                |
| `sort`                 | A sort's ID from the index's [settings](/docs/settings.md); its default without one. | `count` (the most products first, by default) or `name`. |
| `filters`              | [Filters](/docs/search.md#filters), as in a search.                                  | The same: count only the products that match.            |
| `limit`                | 1 to 50 products, 10 by default.                                                  | 1 to 1,000 values, 1,000 by default.                     |
| `pinned`               | Up to 50 objectIDs to show first, in order.                                       | Values to show first, in order.                          |
| `hidden`               | Up to 500 objectIDs never to show.                                                | Values never to show.                                    |
| `attributesToRetrieve` | The fields each product has, for smaller pages; every field without.              |                                                          |
| `field`                |                                                                                   | The facet field whose values the list holds.             |

Sold-out products follow the index's [rank first](/docs/settings.md#rank-first) setting, as in a search. To leave them out, add a filter.

## On your pages

Ask for all of a page's lists in one request. It's a `GET`, so browsers send it without asking the API first, and they may keep the answer for 30 seconds.

With the [browser SDK](/docs/browser-sdk.md#listid-options) (0.15.0):

```ts
// One list; a FindlaneError with status 404 when the index has no such list
const popular = await client.list("popular")

// Several, in the order asked; IDs the index has no list for are left out
const lists = await client.lists(["halloween", "new-arrivals", "themes"])
```

Without the SDK:

```ts
const response = await fetch(
  `https://api.findlane.dev/api/public/indexes/${publicId}/lists?ids=halloween,themes`
)
const { lists } = await response.json()
```

On a server-rendered page, read them with an API key that has the `search` scope: `index.lists.getMany(["popular", "themes"])` with the [server SDK](/docs/server-sdk.md#lists) (0.17.0).

### What a list holds

```json
{
  "id": "halloween",
  "title": "Halloween is coming",
  "kind": "products",
  "hits": [{ "id": "h4", "record": { "title": "Latex mask", "price": 1990 } }],
  "browse": { "sort": "popular", "filters": { "category": "halloween" } },
  "updatedAt": "2026-10-14T09:12:03.000Z"
}
```

`hits` are products as a [search response's hits](/docs/browser-sdk.md#response) are, without highlights. A list of values has `kind: "values"`, `field`, and `values: [{ "value": "Bluey", "count": 41 }]` instead. `browse` is the list's filters and sort, for a "See all" link that opens the same products as a search. `updatedAt` is when what the index's lists hold last changed.

`?limit=` gives fewer products or values than the list holds, such as 4 on a phone.

## How fresh lists are

- **Saving a list builds it** before the dashboard (or the API) answers.
- **A change to the index reaches its lists within about a minute.** The edge sees a rebuilt list within seconds.
- **Refresh now** on the Lists page builds them again at once. It's allowed once a minute per index.
- A list that stops working, such as one filtering on a field that was removed from the settings, keeps what it held before. The Lists page says why.

## Browser search access

Browsers get lists from the same allowed origins as [browser search](/docs/security.md#public-ids-and-allowed-origins). With a [public search policy](/docs/security.md#what-browser-search-can-read), products have only the fields the policy returns, and a list of values is left out unless the policy lets browsers facet on its field. API keys and the dashboard get every field.

## Limits

|                    |                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------- |
| Lists per index    | 3 on Free, 25 on paid plans                                                             |
| Products in a list | 50                                                                                      |
| Values in a list   | 1,000                                                                                   |
| Lists a request    | 10 (or all of the index's, without `ids`)                                               |
| Requests           | 300 a minute per visitor from browsers; an API key's count toward its searches a minute |
| Searches           | None: list requests aren't counted                                                      |
