---
title: "The Experience Edge schema"
slug: "the-experience-edge-schema"
abstract: "Learn more about entry points, endpoints, and template definitions."
---
# The Experience Edge schema

Sitecore Experience Edge has a read-only GraphQL schema designed to accommodate common front-end use cases for headless Sitecore development. It exposes limited information about Sitecore items. For example, standard fields are not available by default.

If you need standard template fields in Experience Edge, you must [explicitly publish them](https://doc.sitecore.com/xmc/en/developers/xm-cloud/en/making-fields-from-the-standard-template-publishable.html).

The following queries are available as entry points:

- `item` - allows querying an item by path or ID.
- `layout` - allows querying an item by site and route path, typically for the purpose of accessing its Layout Service JSON (`rendered`).
- `search` - allows constructing a Boolean field search query for finding items by field value or common properties.
- `site` - allows querying content sites for site information.

For more information, see the [example queries](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/query-examples-for-the-delivery-api.html "Query examples for the Delivery API") and use the **Docs** tab in the GraphQL testing UI of the Preview endpoint IDE.

## Template projection

The types available in the Experience Edge schema reflect the template definitions of the Sitecore instance that published to it. You can enable strongly-typed template fields by using inline fragments that select fields from specific types.

In Sitecore, multiple templates can have the same name and templates with field names that conflict with core fields on the item graph type. In GraphQL, the names of types and fields must be unique. When a naming collision occurs, the item or field item with the newest creation date has `_{guid}` appended to the name. The creation date is used because the ordering must be stable, and a graph type name must never change after it has been referenced.

> [!note]
> GraphQL types are only created for templates that follow the Helix content structure. This means that GraphQL types are generated only for templates under the following paths:
>
> -   `<foundation>/sitecore/templates/Foundation</foundation>`
>
> -   `<feature>/sitecore/templates/Feature</feature>`
>
> -   `<project>/sitecore/templates/Project</project>`
>
> -   `<userdefined>/sitecore/templates/User Defined</userdefined>`

## Pagination

Paginated queries and fields in the Experience Edge schema, such as the search query, utilize a cursor-based system to request result pages.

For paginated queries:

- Query arguments include `first` (number of results to return) and `after` (the beginning cursor). `first` has a default value of `10`.
- Query results include `pageInfo` with `hasNext` (whether there are more results) and `endCursor` (used in the after argument to obtain the next page).
- Query results also include `total` (provides the total number of available results).

    > [!note]
    > The first argument has a special meaning to query the complexity calculation used by the underlying GraphQL library of the `Preview` schema. In particular, using the nested `children` field on the Item graph type, can cause errors, such as *Query is too complex to execute*. The following section includes recommendations for handling query complexity.

## Query complexity

The Experience Edge query complexity is limited to 250. We recommend you test your query before using it in a runtime environment, to make sure it meets the complexity requirements. If your query is too complex, try the following:

- Break it into multiple smaller queries. For example, use one query to retrieve a data set, and apply subsequent queries to that dataset. Large queries of multiple objects increase query complexity substantially.
- Remove unnecessary fields from the query.

## Available fields for content search

In Experience Edge, you can use the GraphQL `search` query on the special fields listed in the following table. When querying templates, you can only query user-defined fields and the following special fields. For example, you can query the user-defined `title` field of the sample item template, but not `_Sortorder`.

| Field | Description |
| --- | --- |
| `_templates` | Contains all template GUIDs, including base templates. Can be used to find all the items that use the template in the hierarchy. |
| `_path` | Contains parent items, and can be used to retrieve descendants of an item by its GUID. For example, if you use a `contains` clause and the ID of the `/home` path, the results include `/home` and its children, such as `/home/about_us`. |
| `_parent` | The ID of the item’s immediate parent. |
| `_name` | The item name. |
| `_language` | The item language. |
| `_hasLayout` | Shows whether the item has presentation details/layout data. |

### Search operator behavior

The `search` query supports the following operators.

> [!note]
> Search operator behavior differs depending on whether you are querying the Delivery endpoint or the Preview endpoint (which uses a tokenized search index).

- **EQ (Equals)** - matches only user defined fields whose value is an exact match.
    - On the **Delivery endpoint**, this operator matches only user defined fields whose value is an exact match. The entire field must match the search value exactly, and partial matches are not returned.

        For example, searching for *ipsum* with the `EQ` operator will not match a field containing *lorem ipsum dolor sit amet*, but it will match a field whose value is exactly *ipsum*.

    - On the **Preview endpoint**, works as the `CONTAINS` operator for text fields because all text fields in the Solr search index are tokenized by default. This means it may return multiple results, even when an exact match is expected.

        For example, searching for *ipsum* with the `EQ` operator might return results for fields containing *lorem ipsum dolor sit amet*.

        To ensure **exact matching** with `EQ` in the Preview endpoint, use the SearchQueryFieldMapping feature to map tokenized fields to non-tokenized computed fields. See also the related support article [KB1003665](https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003665).

    Use this operator when you need precise, whole-field matching, but be aware of tokenization behavior on the Preview endpoint.

- **CONTAINS** - performs a substring match within a field.
    - On the **Delivery endpoint**, the value is matched as-is without tokenization or ranking.

        For example, searching for *ipsum* with the `CONTAINS` operator matches any field where the value appears anywhere within the text, such as *lorem ipsum dolor sit amet*.

    - On the **Preview endpoint**, the `CONTAINS` operator can return multiple results based on tokenized field values. This is because the Preview endpoint uses a tokenized search index.

    Use this operator for partial text matches and filtering content based on words or phrases within a field.

> [!note]
> The GraphQL search field is designed for filtering content, not for implementing full-text or site search functionality. For more advanced search capabilities, consider using a dedicated search service.

### Search query examples

This is an example of searching for items using the `CONTAINS` operator in a user defined field:

```csharp
query Search {
  search(
    where: {
      name: "title",
      value: "Sitecore",
      operator: CONTAINS
    }
  ) {
    results {
      id
      name
    }
  }
}

```

Here's an example of searching for items using an exact match in a user defined field:

```csharp
query Search {
  search(
    where: {
      name: "_parent"
      value: "110D559FDEA542EA9C1C8A5DF7E70EF9"
      operator: EQ
    }
  ) {
    results {
      id
      name
    }
  }
}

```

Here's an example of combining multiple clauses:

```csharp
query Search {
  search(
    where: {
      AND: [
        {
          name: "_parent"
          value: "110D559FDEA542EA9C1C8A5DF7E70EF9"
          operator: EQ
        },
        {
          name: "title"
          value: "another"
          operator: CONTAINS
        }
      ]
    }
  ) {
    results {
      id
      name
    }
  }
}

```