# Filtering, fields and expand

> Filter, sort, project fields, expand references and resolve media in Content Delivery API reads, with one request per page.

> Markdown version of https://kanorio.com/en/developers/basics/fields-and-expand. Append `.md` to any developer docs URL for this format. Index: https://kanorio.com/llms.txt · MCP: https://app.kanorio.com/api/mcp

Collection reads on the Content Delivery API take a small query language. It works the same for your own collections and for the built-in ones, such as `blog`, `blog_categories`, `blog_tags` and `authors`.

```bash
curl "https://{site}/api/v1/collections/courses/items?filter[level]=beginner&sort=-publishedAt&fields=title,cover,teacher&expand=teacher&limit=12"
```

## Filter

Conditions use bracket notation: `filter[field][operator]=value`. `filter[field]=value` is shorthand for `eq`. Conditions combine with AND. For OR, group conditions under `filter[any][0]`, `filter[any][1]` and so on.

| Operator | Works on | Example |
|---|---|---|
| `eq`, `ne` | Scalars | `filter[level][eq]=beginner` |
| `in`, `nin` | Scalars, comma-separated values | `filter[level][in]=beginner,advanced` |
| `gt`, `gte`, `lt`, `lte` | Numbers, dates | `filter[price][lte]=50` |
| `contains`, `ncontains` | Text | `filter[title][contains]=bread` |
| `match` | Text and rich text, several words | `filter[content][match]=sourdough starter` |
| `exists` | Any field | `filter[cover][exists]=true` |
| `has` | Multi-select, multi-reference | `filter[tags][has]=tag_01` |
| `eq_slug` | Reference, by the referenced item's slug | `filter[teacher][eq_slug]=ada` |
| `has_slug` | Multi-reference, by slug | `filter[categories][has_slug]=recipes` |

`slug`, `publishedAt`, `createdAt` and `updatedAt` are filterable on every collection. Dates accept relative values such as `now-30d` or `now+1w`. The reference lists the exact limits on conditions and values.

## Sort

`sort=-publishedAt,title` sorts by up to a few fields. A leading `-` means descending. Scalar fields and the item attributes above are sortable. Rich text, JSON, media and multi-value fields are not.

## Fields

`fields=title,excerpt,cover` returns only those keys of `fieldData`. `id`, `slug`, `publishedAt` and `updatedAt` always come back. Use it on list pages so you do not download every article body.

## Expand

`expand=teacher` replaces one level of reference lookups. Each item gets `expanded.teacher` with the referenced item, and its images join the top-level `assets` map. On `blog`, `expand=authors,categories,tags` expands the post's authors, categories and tags, and `primary_author` and `primary_category` give you the first of each.

## Assets

Image, gallery and file fields hold asset ids. Every response that references media has a top-level `assets` map that resolves them, so you never need a second request.

```json
{
  "assets": {
    "ast_01": {
      "assetId": "ast_01",
      "url": "https://imagedelivery.net/.../public",
      "width": 1600,
      "height": 1067,
      "alt": "Loaves cooling on a rack",
      "focus": { "x": 0.5, "y": 0.4 },
      "placeholder": "data:image/webp;base64,...",
      "edgeColor": "#f4efe6",
      "mimeType": "image/jpeg",
      "kind": "image"
    }
  }
}
```

- `placeholder` is a tiny blurred preview, ready for a blur-up `<img>` or Next.js `blurDataURL`.
- `focus` is the focal point as 0 to 1 coordinates. Use it for `object-position` when you crop. It is `null` when unset.
- `edgeColor` is the solid color shared by all four edges, such as the white behind a product photo. Use it as the background when you show the image with `object-fit: contain`. It is `null` for transparent or multi-colored images; use `placeholder` as a blurred backdrop instead.
- For a smaller image, replace the trailing `/public` of a public image URL with a variant such as `/w=800,fit=scale-down`.
- When the site watermarks images, `url` is already the watermarked version.

## Formats

Blog posts return Markdown in `fieldData.content`, plus structured `segments` and a `toc` of headings. Add `formats=html,plaintext` to also get `contentHtml` and `plaintext`. `segments` splits the article into Markdown and embedded blocks, such as calls to action, FAQs and galleries, so you can render each block with your own components.

## Gated content

When a collection restricts fields to members or buyers, anonymous reads omit those fields and include `access`, for example `{ "granted": false, "gated": ["content"], "requires": { "kind": "entitlement", "featureKey": "premium" } }`. Send a signed-in customer's `knr_cat_` token to get the full item. Render per item from each item's own `access`.

## Drafts

Add `preview=1` and send `X-Kanorio-Preview: knr_pv_...` from your server to read unpublished drafts. See [Authentication](https://kanorio.com/en/developers/authentication).
