---
title: Working with pages in the API
related:
  - https://docs.kentico.com/13/managing-website-content/working-with-pages.md
  - https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md
  - https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types.md
  - https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md
  - https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md
  - https://docs.kentico.com/13/custom-development/retrieving-database-data-using-objectquery-api.md
---

> 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 Xperience API allows you to retrieve and manage page content using custom code.

Use the following API to work with pages:

- **TreeNode**(_CMS.DocumentEngine_ namespace) – object that represents pages. The _TreeNode_ class encapsulates data from the _CMS\_Tree_ and _CMS\_Document_ [tables](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/page-database-structure.md), and the coupled data tables of individual page types.
- **DocumentQuery** and **MultiDocumentQuery** (_CMS.DocumentEngine_ namespace) – classes that represent a query for loading pages. These classes do not employ any predefined parametrization, which means that you need to parametrize everything yourself. This makes them suitable for custom scenarios, where you require higher control over the query. Both are similar in functionality:
  - **DocumentQuery** allows you to retrieve pages of a single [page type](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types.md) (when an instance is created with a page type class name as the constructor parameter) or general pages of any type (when using a parameterless constructor). If used for a single specific page type, the resulting query automatically includes coupled data of the given page type (e.g., news, articles). _DocumentQuery_ is also used internally by the _IPageRetriever_ service and any custom providers or repositories built around it.
  - **MultiDocumentQuery** allows you to retrieve pages of multiple page types in a single query at the cost of effectiveness. The coupled data of page types is not retrieved unless explicitly requested using the _WithCoupledColumns_ [parametrization method](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md).
- **IPageRetriever** (_Kentico.Content.Web.Mvc_ namespace) – interface that provides a service for retrieving pages in basic live site scenarios. _IPageRetriever_ internally utilizes _DocumentQuery_ or _MultiDocumentQuery_, and then further adjusts the query using the context of the current request, which has the following effects:
  - content is always retrieved from the current site.
  - content is always retrieved in the culture of the current context.
  - the current site's _Combine with default culture_ setting is always reflected in the retrieved content.
  - the correct version of pages is retrieved depending on whether the content is displayed on the live site or in the administration interface.

> **Info:** **Page query parametrization methods**
>
> For detailed information about the options that allow you to parameterize page queries, see the dedicated reference: [Reference - DocumentQuery methods](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md)

> **Info:** **Loading other objects**
>
> To learn how to retrieve other types of non-page data from the Xperience database, see [Retrieving database data using ObjectQuery API](https://docs.kentico.com/13/custom-development/retrieving-database-data-using-objectquery-api.md).

> **Tip:** **Tip**: Optimize the performance of your website by [caching the retrieved page data](https://docs.kentico.com/13/configuring-xperience/configuring-caching/caching-on-mvc-sites.md).

## Retrieving pages on the live site

For basic retrieval of pages in the code of your live site, use the **IPageRetriever** service. The service is available in the _Kentico.Content.Web.Mvc_ namespace, which is provided by the NuGet packages installed in your live site application.

1. Obtain an instance of the **IPageRetriever** service (for example through [dependency injection](https://docs.kentico.com/13/developing-websites/initializing-xperience-services-with-dependency-injection.md)).
2. Call one of the service's **Retrieve** methods, and parameterize it using [DocumentQuery methods](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md) to only include the pages you need.

The _IPageRetriever_ methods return a collection of **TreeNode** objects representing the given pages (or a specific page type class inheriting from _TreeNode_).

```csharp title="Example"

private readonly IPageRetriever pageRetriever;

// Gets an instance of the IPageRetriever service using dependency injection
public ExampleController(IPageRetriever pageRetriever)
{
    this.pageRetriever = pageRetriever;
}

public ActionResult Index()
{
    // Retrieves pages of the 'Article' page type that are in the '/Articles/May' section of the content tree
    var articles = pageRetriever.Retrieve<Article>( documentQuery => documentQuery
                    .Path("/Articles/May", PathTypeEnum.Children));

    // Retrieves pages of a custom 'Landing page' page type from the '/Landing-pages/Products' section of the content tree
    var landingPages = pageRetriever.Retrieve("Custom.LandingPage"( documentQuery => documentQuery
                    .Path"/Landing-pages/Products", PathTypeEnum.Children));

    // Retrieves pages of multiple page types from the '/Archive' section of the content tree
    var pages = pageRetriever.RetrieveMultiple( multiDocumentQuery => multiDocumentQuery
                    .Path("/Archive", PathTypeEnum.Children));
}

```

## Retrieving pages in custom scenarios

**IPageRetriever** automatically performs some parameterization of the query to simplify the code for the most common scenarios and requires live site context to function. However, if writing outside of your web application or if you require full control over the query, you can directly use the **DocumentQuery** or **MultiDocumentQuery** classes to ensure that there is not any unexpected parametrization done in the background.

```csharp

// Retrieves all pages that match the query
var pages = new MultiDocumentQuery()
                    .OnCurrentSite()
                    .Path("/Articles/Reviews")
                    .Culture("en-us")
                    .CombineWithDefaultCulture()
                    .PublishedVersion()
                    .WithCoupledColumns();

```

```csharp

// Retrieves pages of the specified page type that match the query
var pages = new DocumentQuery("Custom.Smartphone")
                    .OnCurrentSite()
                    .Path("/Products")
                    .Culture("en-us")
                    .CombineWithDefaultCulture()
                    .PublishedVersion();

```

### Retrieving pages under workflow

When retrieving pages under [workflow](https://docs.kentico.com/13/configuring-xperience/configuring-the-environment-for-content-editors/configuring-workflows.md), you may want to retrieve the latest edited version in some cases and the published version in others.

- Use the **PublishedVersion** [parametrization method](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md) to retrieve the published version of pages under workflow (when retrieving pages to be displayed to visitors).
- Use the **LatestVersion** [method](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md) to retrieve the latest edited version of pages under workflow (when retrieving pages for further editing or previewing of unpublished changes).

> **Note:** **Note**: The **Published** [parametrization method](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/reference-documentquery-methods.md) does not specify the version of the pages you retrieve, instead it limits the retrieved pages to only those that are currently published according to the value of their  **Published from** / **Published to**  settings and have a published version.

### Retrieving content in the preview mode and page builder

When retrieving page content using **DocumentQuery** or **MultiDocumentQuery** in the code of your website application for the [preview mode](https://docs.kentico.com/13/developing-websites/retrieving-content/adding-preview-mode-support.md) or the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) interface, you want to get the latest version of the content. However, you still need the published version to be displayed on the live site. To achieve this, you can parametrize queries to conditionally serve a different version of content based on where the content is displayed.

> **Tip:** **Tip:** If you do not specifically require **DocumentQuery** or **MultiDocumentQuery** for a custom scenario, it is recommended to use the **IPageRetriever** service, which is preconfigured to provide the correct version of content.

```csharp

using CMS.DocumentEngine;

using Kentico.Content.Web.Mvc;
using Kentico.PageBuilder.Web.Mvc;
using Kentico.Web.Mvc;

// Checks whether the current page is displayed in preview mode or the edit mode of the page builder
bool showLatest = HttpContext.Kentico().PageBuilder().EditMode || HttpContext.Kentico().Preview().Enabled;

// Retrieves the latest edited version of pages in preview mode or the page builder, but the published version in other cases
var pages = new DocumentQuery("Custom.Smartphone")
                    .OnCurrentSite()
                    .Culture("en-us")
                    .LatestVersion(showLatest);

```

## Working with retrieved pages

You can iterate through the retrieved collection to access the properties of individual pages. The available columns depend on how you parametrized the query when retrieving the pages.

```csharp

// Retrieves smartphone pages
var smartphones = new DocumentQuery("Custom.Smartphone")
                        .OnCurrentSite()
                        .Culture("en-us")
                        .Path("/Products/", PathTypeEnum.Children)
                        .LatestVersion();

// Writes the 'DocumentName' and 'SmartphoneOS' values of each of the retrieved smartphones into an HTTP output response stream
foreach (TreeNode smartphone in smartphones)
{      
    string smartphoneOS = smartphone.GetValue<string>("SmartphoneOS", "Default OS");
    Response.Write(HTMLHelper.HTMLEncode(smartphone.DocumentName) + " - " + HTMLHelper.HTMLEncode(smartphoneOS) + "<br />");
}

```

> **Tip:** **Tip**: To see more examples of how to work with pages using the Xperience API, see the [API Examples](https://docs.kentico.com/13api/content-management/pages.md) documentation.

## Updating pages

To update a page (_TreeNode_ object):

1. Retrieve the latest edited version of a page (using the methods described above).
2. Modify the page's data:
   - For general page fields, directly set the corresponding _TreeNode_ properties.
   - For the fields of specific page types, call the _TreeNode.SetValue("FieldName", value)_ method.
3. Call the **TreeNode.Update()** method.

For examples and additional scenarios, see the [API Examples](https://docs.kentico.com/13api/content-management/pages.md) documentation.

> **Note:** **Updating pages under workflow**
>
> When using the API to update pages under [workflow](https://docs.kentico.com/13/configuring-xperience/configuring-the-environment-for-content-editors/configuring-workflows.md) or [versioning](https://docs.kentico.com/13/configuring-xperience/configuring-the-environment-for-content-editors/configuring-and-using-page-versioning.md), always retrieve the page objects with all fields. Otherwise, the update may cause data loss. Use one of the following approaches:
>
> - Use _DocumentQuery_ and retrieve the latest edited version of pages of a specific page type.
> - Use _MultiDocumentQuery_ and retrieve the latest edited version of pages. Use the **Types** method to specify page types to retrieve and **WithCoupledColumns** method to prevent loss of data from page type fields.

## Creating new pages

To create a page:

1. Retrieve a parent page under which you want to create the new page (using the methods described above).
2. Create a new _TreeNode_ object by calling the _TreeNode.New("PageTypeCodeName")_ method.
3. Set the page's data:
   - For general page fields, set the corresponding _TreeNode_ properties.
   - For the fields of specific page types, call the _TreeNode.SetValue("FieldName", value)_ method.
4. Save the page by calling the **Insert(parentTreeNode)** method of the new _TreeNode_ object.

For examples and additional scenarios, see the [API Examples](https://docs.kentico.com/13api/content-management/pages.md) documentation.
