---
canonical: https://amplience.com/developers/docs/apis/content-delivery-graphql/graphql-filter-api/
title: Filter
description: Developer guide for how to use the Amplience GraphQL Content Delivery API  filter functionality, including how to list, sort and filter content, with examples.
audience: Developer
image: https://cdn.media.amplience.net/i/ampproduct/light_mode_error?w=1200&h=630
image_width: 1200
image_height: 630
date_published: 2023-03-30
date_modified: 2025-07-28
---

# GraphQL filter

The GraphQL API lets you list, sort and filter your content. You can choose the sort order of your results and filter content using one or more custom properties.

On this page we'll explain how to use the GraphQL filter functionality, including how to [list](#listing-content), [sort](#sorting-content) and [filter](#filtering-content) content. We will provide examples for how to perform each of these actions. Alongside the examples we have also provided a number of schema examples and code snippets so that you can try them out on your own hub.

You can try out any of the examples on this page, or your own queries, on our [Amplience examples playground](https://amplience-examples.cdn.content.amplience.net/graphql)

## Naming

The name you give your content type schema is what will be used to query your content in GraphQL. This is because the graphs in GraphQL are created by converting all content type schemas for a given hub into a single GraphQL schema, known as a graph. For example, if you were to create a new content type schema and use the name 'blog post' at the end of the URI path (i.e. after the last "/"), your content type schema would be known as 'BlogPost' in GraphQL.

At the same time, a GraphQL query is created to allow users to filter by content type. The GraphQL types created to be used for filter by type queries prefix the single GraphQL type name with "all" and camelCase the single GraphQL type name.

Some examples below:

| content type schema name | GraphQL name | GraphQL Filter name |
| ------------------------ | ------------ | ------------------- |
| `author`                 | `author`     | `allAuthor`         |
| `BlogPost`               | `blogpost`   | `allBlogPost`       |
| `Media`                  | `media`      | `allMedia`          |

For more examples and information about the naming process, [click here](https://amplience.com/developers/docs/apis/content-delivery/content-delivery-graphql/#graph-conversion-and-graphql-type-names).

## GraphQL arguments

### Arguments

Filter by content type queries support four different arguments to be passed in, these are:

| Argument name | Description                                                                                                                                           |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `first`       | Show the first [n] results, user defines [n].                                                                                                         |
| `last`        | Show the last [n] results, user defines [n].                                                                                                          |
| `before`      | Passes a cursor as a string and is combined with either the "first" or "last" argument to return the first/last [n] results before the given cursor.  |
| `after`       | Passes a cursor as a variable and is combined with either the "first" or "last" argument to return the first/last [n] results after the given cursor) |

> **Note:** A filter by type query requires either the "First" or "Last" argument to be defined in order for the query to be valid. "First" and "Before" also can not be used together. Similarly, "Last" and "After" can not be used together.

### Fields

Filter by content type queries support 2 different fields, these are:

| Argument name | Description                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `edge`        | This field is used to specify which fields to return for each content item of that type. Further details of how to use this field are described below. |
| `pageInfo`    | This field is used to return pagination information.                                                                                                   |

### Edge

The `edge` field is used to specify which fields to return for each content
item of that type. The "edge" field is made up of two further fields, see below:

| Argument name | Description                                                                                                                                          |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cursor`      | This field is used to return a cursor for each content item for the given content type.                                                              |
| `node`        | This field is used to specify fields from the content item to return. This field contains all fields the corresponding single GraphQL type contains. |

### Page Info

The "pageInfo" field is used to return pagination information. The "pageInfo" field is made up of four further fields, see below:

| Argument name     | Description                                                                                   |
| ----------------- | --------------------------------------------------------------------------------------------- |
| `endCursor`       | When specified returns the End Cursor for the results page.                                   |
| `hasPreviousPage` | When specified returns a Boolean response indicating if the current page has a previous page. |
| `hasNextPage`     | When specified returns a Boolean response indicating if the current page has a next page      |
| `startCursor`     | When specified returns the Start Cursor for the results page.                                 |

## Pagination

GraphQL filter uses the cursor connections specification to allow pagination of results. With pagination, a maximum of 50 results is returned for each page. You can specify the page size in the filter request. If you don't specify the page size, the maximum number of 50 items will be returned.

In the following example the page size is set to 1 using the `first` argument, which gives us our response in a descending manner. In this case, the first content item will be returned per page in the response.

```graphql
query {
  allExampleAuthor(first: 1) {
    edges {
      node {
        name
      }
    }
  }
}
```

Alternatively, if we wanted the last item from our content, we would use the `last` argument and set this to 1.

```graphql
query {
  allExampleAuthor(last: 1) {
    edges {
      node {
        name
      }
    }
  }
}
```

In the next example the page size is set to the first 3, so a maximum of 3 content items will be returned per page in the response.

```graphql
query {
  allExampleAuthor(first: 3) {
    edges {
      node {
        name
      }
    }
  }
}
```

Due to the maximum page size being 50, we cannot set the page size to more than this number. If we do, an error will be given that tells us the correct number of items that can be shown per page. In the screenshot below, we have set the page size to 100 using the `first` argument. In response, we have received an error informing us that the max page size is 50.

![The maximum page size](https://cdn.media.amplience.net/i/ampproduct/light_mode_error?w=1880&fmt=png&)

If you would like to know whether your paginated content has a next or previous page, you would use the `hasNextPage` or `hasPreviousPage` argument, which would return a boolean result. For example, below we are checking to see whether our paginated list of author names would have a next page if we set the page size to 2.

```graphql
{
  allExampleAuthor(first: 2) {
    pageInfo {
      hasNextPage
    }
  }
}
```

This gives us the following result, which shows us that our content indeed does have another page of results for us to query for:

```graphql

  "data": {
    "allExampleAuthor": {
      "pageInfo": {
        "hasNextPage": true
      }
    }
  }
}
```

To query for the next page of content, we will need to fetch the `endCursor` and `startCursor`. An example of an `endCursor` query follows the below format:

```graphql
{
  allExampleAuthor(first: 2) {
    pageInfo {
      endCursor
    }
  }
}
```

This gives us the `endCursor` as a response:

```graphql
{
  "data": {
    "allExampleAuthor": {
      "pageInfo": {
        "endCursor": "eyJzb3J0S2V5IjoiNjQyMzdlZGEyMDc3MmQwMDAxYTkwNDU3IiwiaXRlbUlkIjoiYW1wbGllbmNlLWV4YW1wbGVzOjdlZmNjMjkwLWMxYzEtNGRkYS05ZmU1LTU1ZGIzMTU2Y2VlNSJ9"
      }
    }
  }
}
```

We can then use this `endCursor` string to query for last results of the next page of results. To do this we would include the `endCursor` string in our query while using the `before` argument:

```graphql
{
  allExampleAuthor(
    before: "eyJzb3J0S2V5IjoiNjQyMzdlZGEyMDc3MmQwMDAxYTkwNDU3IiwiaXRlbUlkIjoiYW1wbGllbmNlLWV4YW1wbGVzOjdlZmNjMjkwLWMxYzEtNGRkYS05ZmU1LTU1ZGIzMTU2Y2VlNSJ9"
    last: 1
  ) {
    edges {
      node {
        name
      }
    }
  }
}
```

Alternatively, we can include the `startCursor` string in our query while using the `after` argument to query for the first results, as shown below.

```graphql
{
  allExampleAuthor(
    after: "eyJzb3J0S2V5IjoiNjQyMzdmOTAwMzE5ZGIwMDAxY2Q5NzdkIiwiaXRlbUlkIjoiYW1wbGllbmNlLWV4YW1wbGVzOjAyMGY1Y2I4LTIxOWYtNDI4MC04ZGQ2LTcyZjIwMjJhNGU3OSJ9"
    first: 1
  ) {
    edges {
      node {
        name
      }
    }
  }
}
```

To get the `startCursor`, we would query for it in the same way we query for the `endCursor`.

For more information about pagination and limits, read the [API limits page](https://amplience.com/developers/docs/apis/limits).

## Listing content

If you want to list content for a given content type you can use the `all[GraphQL name]` typename. For example, if you have a content type schema called `BlogPost`, you would use the `allBlogPost` GraphQL typename to list all pieces of content for that Content Type. Alternatively, if you want to return a single piece of content by a specific delivery ID or Key, you would then query by `BlogPost` without the `all` prefix.

In the example shown below we are querying for the titles and descriptions of all content created by the blog content type schema. To do this we use the `edge` and `node` field within our query:

```json
{
  allBlogPostFilter(first: 3) {
    edges {
      node {
        title
        description
      }
    }
  }
}
```

All blog titles and descriptions created using this schema will be returned in the response:

```json
{
  "data": {
    "allBlogPostFilter": {
      "edges": [
        {
          "node": {
            "title": "Menswear recommendations",
            "description": "Menswear picks for your spring wardrobe refresh"
          }
        },
        {
          "node": {
            "title": "Indoor play ideas for the kids this half term",
            "description": "Try out our ideas for indoor play and entertainment this week."
          }
        },
        {
          "node": {
            "title": "Beauty picks for your new spring look",
            "description": "Fancy some new products for the new season? Look no further, we've got you covered."
          }
        }
      ]
    }
  }
}
```

### More list examples

These examples demonstrate how to use the first and last arguments when listing content in GraphQL. In this instance, we are listing the names of authors from the author content type.

#### Return first two names in list of author names from author type

```graphql
{
  allExampleAuthor(first: 2) {
    edges {
      node {
        name
      }
    }
  }
}
```

The above query gives us the following GraphQL response:

```graphql
{
  "data": {
    "allExampleAuthor": {
      "edges": [
        {
          "node": {
            "name": "Kemi Elizabeth"
          }
        },
        {
          "node": {
            "name": "Jon Lansdell"
          }
        }
      ]
    }
  }
}
```

#### Return last two items in list of author names from author type

```graphql
query {
  allExampleAuthor(last: 2) {
    edges {
      node {
        name
      }
    }
  }
}
```

The above query gives us the following GraphQL response:

```graphql
{
  "data": {
    "allExampleAuthor": {
      "edges": [
        {
          "node": {
            "name": "Kemi Elizabeth Ojogbede"
          }
        },
        {
          "node": {
            "name": "Helen Elizabeth Symington"
          }
        }
      ]
    }
  }
}
```

For more information on how the first and last arguments work, refer to [Pagination](##Pagination).

## Filtering content

You can filter on other string, number or boolean properties defined in your content type schema. For example, you could return all products with a category of "mens suits" or all blogs with the category of "homeware". Filters can be combined, so you can filter on products with a category of "ties" that are in the "Silk" product family, or all blogs in a particular category with a read time of 10.

### The filterable trait

If you want to filter on any other properties then these properties must be defined in a `trait:filterable` object in the content type schema.

The trait includes a `filterBy` array that includes the path for each property that you will use to filter your content. Path entries are specified in JSON Pointer format and can be string, number or boolean types. The `filterBy` array can contain up to 5 paths, not including the schema id which is included automatically.

Before defining a path to be filtered on, a `graphql:filtername` must be given using standard camel case. This must be followed by the `filterBy` array which will be used to make a request to the filter API to retrieve content with properties of the specified value.

In the example we are using the `category` property as a filter.

```json
"trait:filterable": {
    "filterBy": [
      {
        "graphql:filtername": "byCategory",
        "paths": ["/category"]
      }
    ]
  }
```

Note that you can only include properties defined in the schema itself and not in any linked content.

### Filtering using multiple properties

Filters can be combined, so you could request all products that have a categoryId of "mens-accessories-ties" and a product family of "Silk". To combine filters you need to define a path containing both filters. In the example shown below the `productFamily` and `categoryId` properties are combined:

```json
"trait:filterable": {
		"filterBy": [
        "graphql:filtername": "byProductFamilyAndCategory",
        "paths": ["/productFamily", "/categoryId"]
	}
```

Up to 5 entries can be included in a single path.

### Specifying filter in your GraphQL query

To filter content using one of the paths defined in your `filterBy` array, include the schema, the `graphql:filtername` and the path in your GraphQL query. In the example shown below, we're requesting the categoryID and SKU numbers of all content created by the PDP content block content type that has a product family of "Womenswear". Note that you always need to include the schema in the request.

```graphQL
query {
  allPdpContentBlock (
    first: 3,
  	filter:{
      byProductFamily:{
        productFamily:"Womenswear"
      }
    })
  {
    edges {
      node {
        categoryId
        sku
      }
    }
  }
}
```

This query returns the following response:

```json
{
  "data": {
    "allPdpContentBlock": {
      "edges": [
        {
          "node": {
            "categoryId": "grey-jacket",
            "sku": "FR32450"
          }
        },
        {
          "node": {
            "categoryId": "tailored-jacket",
            "sku": "JSD451245"
          }
        }
      ]
    }
  }
}
```

If you want to query for content while filtering on multiple properties, you would need to first specify the paths you would like to filter on within the content type schema, and give that path a `graphql:filtername`.

For example, if we wanted to filter on both product family and category ID for a particular Pdp content block, we would first specify the paths in our content type schema and give it a `graphql:filtername` of `byProductFamilyAndCategory`, written in camel case. When querying for the content later, we would simply specify the `graphql:filtername` in our filter field and detail both the particular product family and category ID we're searching for.

The following code snippet shows what this query would look like if we were searching for the SKU id and meta info for all Pdp Content Blocks with the product family "Womenswear" and the category id "grey-jacket":

```graphQL
query {
  allPdpContentBlock (
    first: 3,
  	filter:{
      byProductFamilyAndCategory:{
        categoryId: "grey-jacket"
        productFamily:"Womenswear"
      }
    })
  {
    edges {
      node {
        sku
        _meta {
          deliveryId
          name
        }
      }
    }
  }
}
```

This query returns the following response:

```json
{
  "data": {
    "allPdpContentBlock": {
      "edges": [
        {
          "node": {
            "sku": "FR32450",
            "_meta": {
              "deliveryId": "0341d22d-d7c9-49c5-9474-036c5b0ce243",
              "name": "Womenswear product"
            }
          }
        }
      ]
    }
  }
}
```

## Sorting content

By default content will be returned sorted by date created, but you can specify your own sort order. For example, a list of blog posts could be sorted by read time or ranking.

To define a sort option you need to include a `trait:sortable` object in you content type schema containing the sort key, `graphql:sortname` and the path to one or more properties used to sort the content. It should be noted that if you choose to use a default sort key, you do not need to specify the `graphql:sortname`.

### The sort trait

The `trait:sortable` object is added at the top level of the schema and can contain up to 3 sort paths, one of which must have the "default" key.

The trait includes a `sortBy` array that includes the path for each property that you will use to for your content. Path entries are specified in JSON pointer format and can be string, number or boolean types.

The `trait:sortable` object shown below includes a default sort key that is used to sort blog content using the `readTime` property. Due to this being the default sort key, we do not need to specify the `graphql:sortname`.

```json
    "trait:sortable": {
    "sortBy": [
      {
        "key": "default",
        "paths": ["/readTime"]
      },
     ]
    }
```

You can specify multiple entries in a sort path, up to a maximum of 5.

In the example below we have specified two sort keys: "default" and "readTime".

The default sort key will sort the content by `date` and `ranking`. If the blog post date of two items is the same, then the `ranking` will be used as a tie breaker.

The "readTime" sort key will sort the content by `readTime` followed by `date` and then if those properties are both equal, "ranking" will be used.

The use of a `graphql:sortname` is encouraged, but if one is not included, there will be an attempt to infer the sort name from the key field. If the inferred name causes a naming collision with another sort name, it will prevent the generation of a schema. In this case, a unique `graphql:sortname` would have to be specified.

When creating a sort name, make sure to use standard camel case naming conventions - ie. `byTime`, `byDate`, `byRanking`.

> **Note:** Using a duplicate `graphql:sortname` or `graphql:filtername` will cause a schema to not be generated until the conflict is resolved by a unique `graphql:sortname` or `graphql:filtername` being specified.

```json
"trait:sortable": {
    "sortBy": [
      {
        "key": "default",
        "paths": ["/date", "/ranking"]
      },
      {
        "graphql:sortname": "byTime",
        "key": "readTime",
        "paths": ["/readTime", "/date", "/ranking"]
      }
    ]
  },
```

### Specifying sort in your GraphQL query

If you have included a `trait:sortable` object in your content type schema, then if you don't specify a sort in your GraphQL filter query, the content will be sorted using your default sort and in ascending order.

To specify a sort, include a `sortBy` object in your query. In the example shown below, we're requesting the titles of all items created by our blog content type and sorted in descending order by `readTime`, followed by `date` and then `ranking`. If you don't specify a sort order, then ascending order will be used.

If you do not include a sort trait in your schema, the content will be sorted by date created.

```graphql
{
  allBlogPostFilter(first: 3, sortBy: { key: byTime, order: DESC }) {
    edges {
      node {
        title
      }
    }
  }
}
```

This gives us the following JSON format response:

```json
{
  "data": {
    "allBlogPostFilter": {
      "edges": [
        {
          "node": {
            "title": "Beauty picks for your new spring look"
          }
        },
        {
          "node": {
            "title": "Indoor play ideas for the kids this half term"
          }
        },
        {
          "node": {
            "title": "Menswear recommendations"
          }
        }
      ]
    }
  }
}
```

### Other notes

- The default and maximum page size is 50.
- The request timeout is 10 seconds. If this time is exceeded the request will return a 524 error
- There is a complexity limit of 1000 items. This refers to the number of content items involved in processing a request. If the limit is exceeded, a 524 error is returned.
- If you request filter paths that are not included in your content type schema then the request will not return an error and instead 0 items will be returned.

## Example schemas

The example requests on this page use two schemas:

- **Blog post filter and sort**.
  This is an update to the blog post schema used in our search examples. It has been modified to support filtering and sorting. It's included in the [schema examples](https://amplience.com/developers/docs/schema-reference/schema-examples) and also on [its own page](https://amplience.com/developers/docs/schema-reference/schema-examples/filter/blog-filter-sort).

- **Product details**.
  This is a product details schema that has multiple filterable properties.
  It's also included in the [schema examples](https://amplience.com/developers/docs/schema-reference/schema-examples) and also on [its own page](https://amplience.com/developers/docs/schema-reference/schema-examples/filter/filter-product-details).

## Related pages

[GraphQL overview](https://amplience.com/developers/docs/apis/content-delivery-graphql/overview)

[JSON pointer](https://tools.ietf.org/html/rfc6901)

[Schema examples](https://amplience.com/developers/docs/schema-reference/schema-examples)

[Limits](https://amplience.com/developers/docs/apis/limits)
