---
title: Retrieve content in Xperience by Kentico
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

## The approaches

[ContentRetriever API](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md) is our primary API for fetching content. It includes many default settings that operate based on common scenarios and available Xperience context, such as automatic language selection, preview mode detection, secured content handling, and caching. You can easily override these defaults by providing parameters to the API.

The [Content Item Query API](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-item-query-api.md) is the underlying, low-level API used by _ContentRetriever_. Although it requires more development effort, it gives developers greater flexibility to customize content retrieval for specific scenarios.

## Which approach to use

**Always use ContentRetriever if possible.** It:

- Automatically resolves language, preview mode, and other request context for you
- Allows for simple, more readable code
- Provides built-in caching options, so you don't need to set up [`IProgressiveCache`](https://docs.kentico.com/documentation/developers-and-admins/development/caching/data-caching.md) yourself

Aim to use _Content item query_ only for scenarios that _ContentRetriever_ can't cover, for example:

- When your code runs outside a request tied to a specific website channel (e.g., background services, scheduled tasks), and you need to provide the website context, language and preview mode manually
- You need to query items without knowing their concrete content types in advance (for example, mixed-type results from a **Combined content selector**) and don't want to maintain/provide a list of every single content type to `RetrieveContentOfContentTypes`

> **Tip:** Encode this decision logic into your repository's instruction files for AI coding assistants (e.g., a `*.instructions.md` file scoped to `**/*.cs`). The [Kentico Community Portal](https://github.com/Kentico/community-portal) does this in its [Xperience.instructions.md](https://github.com/Kentico/community-portal/blob/main/.github/instructions/Xperience.instructions.md), which simply states: "Use the `Kentico.Content.Web.Mvc.IContentRetriever` interface when querying for content."
>
> A rule like this helps agents default to ContentRetriever instead of suggesting older or lower-level APIs.
>
> The more ContentRetriever usage already exists in your codebase, the more context the agent has to follow the convention on its own.

### Content retrieval in the Training guides repo

Our example [Training guides repository](https://github.com/Kentico/xperience-by-kentico-training-guides) centralizes content retrieval behind custom [`IContentItemRetrieverService`](https://docs.kentico.com/guides/development/advanced-content/examine-the-content-retrieval-service.md), and that service builds nearly all of its methods on top of ContentRetriever.

This keeps the benefits described above – built-in caching, less boilerplate, and consistent default behavior for language, preview mode, and secured items – centralized in one place, so you don't need to reimplement retrieval logic across all viewcomponents and controllers.

The main trade-off shows up when a page's specific content type isn't known ahead of time, such as when resolving a **Combined content selector** value that allows more than one content type. [`RetrieveWebPageByContentItemGuid`](https://docs.kentico.com/guides/development/advanced-content/examine-the-content-retrieval-service.md#retrievewebpagebycontentitemguid) has two overloads for this: a generic one that uses ContentRetriever directly once the concrete page type is known, and a non-generic one that falls back to the lower-level `ContentItemQueryBuilder`, since ContentRetriever's generic methods require a concrete registered content type and won't accept the shared `IWebPageFieldsSource` interface.

## Anti-patterns to avoid

- **Re-implementing caching ContentRetriever already provides.** Wrapping ContentRetriever calls in your own `IProgressiveCache` logic duplicates work the API already performs through its `RetrievalCacheSettings` parameter, and risks inconsistent cache keys or dependencies.
- **Requesting more linked item depth than a view actually uses.** A high `depth`/`LinkedItemsMaxLevel` value resolves and maps linked content several levels deep, even if only the top-level fields end up rendered.
- **Mapping full content type fields when only shared schema fields are needed.** When a query targets a reusable field schema and doesn't use any type-specific fields, set [`IncludeContentTypeFields`](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md) to `false` to skip mapping data your code won't use.

For a real-world example of a content model that leans heavily on reusable field schemas, see [Training guides commerce schemas](https://docs.kentico.com/guides/development/commerce/explore-training-guides-catalog.md#training-guides-commerce-schemas).

## What's next

With these approaches in mind, see how the Training guides repository puts them to use in custom [`IContentItemRetrieverService`](https://docs.kentico.com/guides/development/advanced-content/examine-the-content-retrieval-service.md).
