---
title: Catalog-API
slug: editorial/catalog-api
description: Catalog-API
docTags: 
createdAt: 2022-08-26T13:44:41.000Z
---

&#x20;The Catalog-API is the main interface for apps and frontends to communicate with the Purple backend.

:::hint{type="info"}
This documentation is intended for technical users (integrators and developers). 
:::

# Overview

The Catalog-API is based on [GraphQL](https://graphql.org/). This allows for a type-safe and clearly defined schema while also allowing to query only the data you need.

:::hint{type="warning"}
This documentation assumes familiarity with GraphQL. Please read the official website's [Introduction to GraphQL](https://graphql.org/learn/) to learn about the concepts if you have never worked with GraphQL before.
:::

To get started working with our API, you can use the online editor [GraphiQL](https://catalog.purplemanager.com/graphiql). It allows building and testing your queries without having to setup a local development environment.

You can view inline documentation of all the available types in both tools and your local development environment as the GraphQL schema offers direct support for documentation.

The endpoint that GraphQL clients have to use is: [https://catalog.purplemanager.com/graphql](https://catalog.purplemanager.com/graphql)

## Quick Examples

Below are two simplified example queries you can use to understand how the Catalog-API works when retrieving article data. In both cases, we assume you already have valid appInfo, deviceInfo, and authorization values (for more information on that, see below).

### 1. Article Content-Only

**Use Case**
You want to retrieve a specific article as structured data.&#x20;

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          name
          publicationDate
          # This requests custom properties, e.g. Custom Fields (ACF) defined for that post
          properties {
            key
            value
          }
          # Request fields only available for Posts
          ... on Post {
            # The list of blocks used for the Post in a structured format. With this information you can define your own rendering of parts of the content.
            content {
              id
              parentId
              type
              level
              children
              sequence
              properties {
                key
                value
              }
            }
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "name": {
      "value": "Example Post"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Post",
              "id": "259cd507-212e-47cc-832f-c9231359f97a",
              "name": "Example Post",
              "publicationDate": "2025-01-10T08:45:40.000Z",
              "properties": [
                {
                  "key": "slug",
                  "value": "hello-world"
                }
              ],
              "content": [
                {
                  "id": "d140212f-4976-41d4-9dc5-0fb16cfa9a17",
                  "parentId": "",
                  "type": "core/paragraph",
                  "level": 0,
                  "children": [],
                  "sequence": 0,
                  "properties": [
                    {
                      "key": "purpleId",
                      "value": "d140212f-4976-41d4-9dc5-0fb16cfa9a17"
                    },
                    {
                      "key": "content",
                      "value": "Welcome to Purple. This is your first post. Edit or delete it, then start writing!"
                    }
                  ]
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::

**How it works**

1. We specify the catalog field in the query root, passing in mandatory parameters:
   - **appInfo**: Contains your appId, appVersion, and a preview flag.
   - **deviceInfo**: Captures device/platform details like deviceId, platform, etc.
   - **authorization**: Provides the token or coupon code needed to access premium or restricted contents.
2. Within the catalog field, we use contentsConnection to fetch all kinds of content (e.g., issues, posts, bundles) and filter them. In this example, we filter by the article’s name.
3. We then request the id, name, publication date and custom properties. If the content is a Post (i.e., an article), we’ll receive the article’s plain text.

This query is a great starting point if you only need the text portion of an article without additional formatting or markup, or if you generate article specific markup yourself.

### 2. Article with Markup

**Use Case**
You want the same article content, but this time you need its markup as well—perhaps you’re planning to render it with richer HTML or want to maintain some formatting in your frontend.

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          name
          publicationDate
          # This requests custom properties, e.g. Custom Fields (ACF) defined for that post
          properties {
            key
            value
          }
          # Request fields only available for Posts
          ... on Post {
            contentHtml
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "name": {
      "value": "Example Post"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Post",
              "id": "259cd507-212e-47cc-832f-c9231359f97a",
              "name": "Example Post",
              "publicationDate": "2025-01-10T08:45:40.000Z",
              "properties": [
                {
                  "key": "slug",
                  "value": "hello-world"
                }
              ],
              "contentHtml": "<h1 class='entry-title'>Example Post</h1>\n<p>Welcome to Purple. This is your first post. Edit or delete it, then start writing!</p>\n"
            }
          }
        ]
      }
    }
  }
}
```
:::

&#x20;**How it works**

1. This query is almost identical to the first example but we also request the markup field inside article.
2. The markup field can contain additional formatting or HTML that you can render on your frontend for a richer user experience.
3. As before, we use contentsConnection to fetch and filter the content, but the requested fields now include text and markup.

Using this approach, you can preserve styling and layout elements from the Purple Hub, allowing you to display articles in a more visually appealing way without generating markup in your custom frontend.

# Queries

The Catalog-API offers both the *Query* and *Mutation* root types. 

The most important part of the Catalog-API is the ability to query the contents and it's metadata of your app or website.

The entrypoint for this is the *catalog* field in the *Query* root type. The required arguments define the basic information that all other queries use.

## Common request parameters

### AppInfo

The *AppInfo* type holds the reference to your *appId* (the ID of your app or website in our system), the *appVersion* (the version of your app) and the *preview* flag (determines if you want preview or live contents).

:::hint{type="info"}
You can find the appId in the Purple Manager on the App's *API* page:

::Image[]{src="https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/_NF5eRcLSHia0ibufHzbD_image.png" size="50" width="1080" height="299" position="center" darkWidth="1080" darkHeight="299" showCaption="false"}


:::

### DeviceInfo

The *DeviceInfo* type holds information about the requesting system. The *deviceId&#xA0;*&#x69;s used to uniquely identify the system and allow access to previously anonymously purchased contents, e.g. in app stores.

:::hint{type="info"}
If you are requesting data from a website you should generate a unique ID, e.g. an UUID, and store it in the local storage of the browser. 
:::

The *platform* defines the platform that is being used to request dats. Currently we differentiate between *ANDROID*, *IOS* and *WEB*. It is also used to filter the available contents, e.g. if you want certain contents to be only available on one platform or deliver different version to different platforms.

The *deviceModel* and *deviceOSs* fields are used to determine the device class, e.g. tables or phone for iOS, and for statistical and auditing purposes. Please provide accurate data about the model, e.g. the model name of the device or browser name, and the version of the device or browser.

The *smallestScreenWidthDp* field is only used for the *ANDROID* platform to determine the device class.

### Authorization

The *Authorization&#xA0;*&#x74;ype is used to provide access tokens and subscription codes (coupon codes) to determine access and purchase status for contents. 

## Pagination

Most queries for data support paging using the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm) (arguments *first* and *after*). You can identify this by the Connection suffix at the fieldnames which support paging.

:::hint{type="warning"}
All APIs limit the maximum number of entries to **200 per query**. If you need to request more data you will need to request pages using the *after* argument.

:::

## Filtering and sorting

All connections support filtering and sorting the results. 

### Filtering

To filter the results you can use the filter parameter. The filters provide matchers for many fields of the Connections return type. You can however only use one field matcher at a time. To match based on multiple fields you have to combine multiple filters using the AND and OR fields.

Example: Filter for name or description containing the word "Sun" Expand source

:::CodeblockTabs
Example: Filter for name or description containing the word "Sun"

```json
{
  "filter": {
    "OR": [
      {
        "name": {
          "operation": "CONTAINS",
          "value": "Sun"
        }
      },
      {
        "description": {
          "operation": "CONTAINS",
          "value": "Sun"
        }
      }
    ]
  }
}
```
:::

### Sorting

The filtered results can be sorted using the sort parameter. Each comparator type allows defining the field that is used to compare for the sort and the direction (ascending or descending). Multiple comparators can also be chained, e.g. to sort by publication date and then name.

Example: Sort by publicationDate and name Expand source

## Contents (Issues, Posts and Bundles)

The *contentsConnection* can be used to query issues, posts and bundles of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

The contents have three major types that share the common *Content* interface. 

**Issue**

Issues are magazine style contents. They usually have multiple pages and use our Storytelling Engine and can display animations, PDFs and other media.

**Post**

Posts are (news) article contents produced using our Purple Hub.

**Bundle**

Bundles are collections of Posts and are also produced using our Purple Hub. 

### Example queries

::::ExpandableHeading
### All Posts

This query returns all the Posts of an app.&#x20;

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          # This requests custom properties, e.g. ACFs defined for that post
          properties {
            key
            value
          }
          # Request fields only available for Posts
          ... on Post {
            # The complete body of the post as HTML
            contentHtml
            # The list of blocks used for the Post in a structured format. With this information you can define your own rendering of parts of the content.
            content {
              id
              level
              sequence
              html
            }
            # Same as contentHtml but with reduced content based on the Hub preview settings. This can be used for paywalls to show a preview of the content
            previewContentHtml
            # Same as content, but with the preview data
            previewContents {
              id
              level
              sequence
              html
            }
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "contentType": {
      "value": "POST"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Post",
              "id": "259cd507-212e-47cc-832f-c9231359f97a",
              "version": 10004,
              "name": "Example Post",
              "description": "",
              "index": 0,
              "alias": null,
              "externalId": "1",
              "publicationDate": "2025-01-10T08:45:40.000Z",
              "access": "FREE",
              "properties": [
                {
                  "key": "slug",
                  "value": "hello-world"
                },
                {
                  "key": "purple_seo_meta",
                  "value": "{\"title\":\"Example Post - Public Documentation - Hub\",\"robots\":{\"index\":\"index\",\"follow\":\"follow\",\"max-snippet\":\"max-snippet:-1\",\"max-image-preview\":\"max-image-preview:large\",\"max-video-preview\":\"max-video-preview:-1\"},\"canonical\":\"example-post\",\"og_locale\":\"en_US\",\"og_type\":\"article\",\"og_title\":\"Example Post - Public Documentation - Hub\",\"og_url\":\"example-post\",\"og_site_name\":\"Public Documentation - Hub\",\"article_published_time\":\"2025-01-10T08:45:40+00:00\",\"article_modified_time\":\"2025-01-10T09:31:23+00:00\",\"author\":\"philip.schiffer@sprylab.com\",\"twitter_card\":\"summary_large_image\",\"twitter_misc\":{\"Written by\":\"philip.schiffer@sprylab.com\"}}"
                },
                {
                  "key": "purple_seo_meta_html",
                  "value": "<!-- This site is optimized with the Yoast SEO plugin v21.2 - https://yoast.com/wordpress/plugins/seo/ -->\n<title>Example Post - Public Documentation - Hub</title>\n\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" />\n<link rel=\"canonical\" href=\"example-post\" />\n<meta property=\"og:locale\" content=\"en_US\" />\n<meta property=\"og:type\" content=\"article\" />\n<meta property=\"og:title\" content=\"Example Post - Public Documentation - Hub\" />\n<meta property=\"og:url\" content=\"example-post\" />\n<meta property=\"og:site_name\" content=\"Public Documentation - Hub\" />\n<meta property=\"article:published_time\" content=\"2025-01-10T08:45:40+00:00\" />\n<meta property=\"article:modified_time\" content=\"2025-01-10T09:31:23+00:00\" />\n<meta name=\"author\" content=\"philip.schiffer@sprylab.com\" />\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:label1\" content=\"Written by\" />\n\t<meta name=\"twitter:data1\" content=\"philip.schiffer@sprylab.com\" />\n<!-- / Yoast SEO plugin. -->"
                }
              ],
              "contentHtml": "<h1 class='entry-title'>Example Post</h1>\n<p>Welcome to Purple. This is your first post. Edit or delete it, then start writing!</p>\n",
              "content": [
                {
                  "id": "d140212f-4976-41d4-9dc5-0fb16cfa9a17",
                  "level": 0,
                  "sequence": 0,
                  "html": "\n<p>Welcome to Purple. This is your first post. Edit or delete it, then start writing!</p>\n"
                }
              ],
              "previewContentHtml": null,
              "previewContents": []
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Issues

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          productId
          purchaseData {
            purchased
            purchasedBy
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "contentType": {
      "value": "ISSUE"
    }
  }
}
```

```json
```
:::
::::

::::ExpandableHeading
### All Bundles

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          ... on Bundle {
            contents {
            	id
              content {
                id
                name
                contentHtml
              }
            }
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "contentType": {
      "value": "BUNDLE"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Bundle",
              "id": "3c3172aa-a403-4845-9471-00e9cf9616c4",
              "version": 20004,
              "name": "Example Issue",
              "description": "",
              "index": 0,
              "alias": null,
              "externalId": "23",
              "publicationDate": "2025-01-10T12:01:33.000Z",
              "access": "FREE",
              "contents": [
                {
                  "id": "ff08083f-cc39-4728-9861-34532b17907d",
                  "content": {
                    "id": "ff08083f-cc39-4728-9861-34532b17907d",
                    "name": "Issue Article",
                    "contentHtml": "<h1 class='entry-title'>Issue Article</h1>\n<p>This is an article that is part of an issue</p>\n"
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Posts which have a category "news"

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          categories
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "AND": [
      {
        "contentType": {
          "value": "POST"
        }
      },
      {
        "categories": {
          "content": {
            "value": {
              "value": "news"
            }
          }
        }
      }
    ]
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Post",
              "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
              "version": 10004,
              "name": "Example News",
              "description": "",
              "index": 0,
              "alias": null,
              "externalId": "29",
              "publicationDate": "2025-01-10T13:08:42.000Z",
              "access": "FREE",
              "categories": [
                "news"
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Posts which have a tag "news"

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          tags
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "AND": [
      {
        "contentType": {
          "value": "POST"
        }
      },
      {
        "tags": {
          "content": {
            "value": {
              "value": "news"
            }
          }
        }
      }
    ]
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Post",
              "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
              "version": 30004,
              "name": "Example News",
              "description": "",
              "index": 0,
              "alias": null,
              "externalId": "29",
              "publicationDate": "2025-01-10T13:08:42.000Z",
              "access": "FREE",
              "categories": [
                "news"
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All contents which have a custom property "cover" with value "true"

:::CodeblockTabs
Query

```graphql
query CatalogContents($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: ContentFilter, $sort: [ContentComparator!]) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    contentsConnection(filter: $filter, sort: $sort) {
      edges {
        node {
          __typename
          id
          version
          name
          description
          index
          alias
          externalId
          publicationDate
          access
          tags
          properties {
            key
            value
            type
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "properties": {
      "key": "cover",
      "value": "true"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentsConnection": {
        "edges": [
          {
            "node": {
              "__typename": "Bundle",
              "id": "3c3172aa-a403-4845-9471-00e9cf9616c4",
              "version": 30004,
              "name": "Example Issue",
              "description": "",
              "index": 0,
              "alias": null,
              "externalId": "23",
              "publicationDate": "2025-01-10T12:01:33.000Z",
              "access": "FREE",
              "tags": [],
              "properties": [
                {
                  "key": "slug",
                  "value": "example-issue",
                  "type": "STRING"
                },
                {
                  "key": "cover",
                  "value": "true",
                  "type": "STRING"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Future Contents (Teasers)

The *futureContentConnection* allows retrieving a limited subset of content metadata for contents with a publication date in the future.

:::hint{type="info"}
The *futureContentConnection* is disabled by default as it could lead to leaked articles. It can be enabled in the *API&#x20;*&#x63;onfiguration page of an app in the Purple Manager.
:::

### Use in Purple Hub

Purple Hub uses the `futureContentConnection` to resolve URLs for scheduled posts. This allows editors to see the correct frontend URL in the Permalink section even before the article is published. When the Future Contents API is enabled, Purple Hub queries both `contentsConnection` (for published posts) and `futureContentConnection` (for scheduled posts) to provide accurate URL resolution across all post states. See also [Frontend Links in Purple Hub](docId\:WZ7W_0fOkon0MlpxUpgvV).

::::ExpandableHeading
### All future contents

This query returns all the future contents of an app.&#x20;

:::CodeblockTabs
Query

```graphql
query CatalogFutureContentsQuery($appInfo: AppInfo!, $deviceInfo: DeviceInfo!) {
  catalog(
    appInfo: $appInfo
    deviceInfo: $deviceInfo
  ) {
    futureContentConnection {
      edges{
        node {
          id
          name
          description
          publicationDate
          properties {
            key
            value
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "TEST_REPLACE_ME",
    "deviceModel": "TEST_REPLACE_ME",
    "locale": "de_DE",
    "deviceOs": "TEST_REPLACE_ME",
    "platform": "WEB"
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "futureContentConnection": {
        "edges": [
          {
            "node": {
              "id": "746ce689-1e7d-43bd-a90b-cdaf600c0724",
              "name": "Future Newsstand Issue",
              "description": "An exciting teaser for the content",
              "publicationDate": "2034-12-31T23:00:00.000Z",
              "properties": [
                {
                  "key": "customprop",
                  "value": "value"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Publications

Publications are the main container for contents. Every content is assigned to one publication.

The *publicationsConnection* can be used to query the publications of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

### Example queries

::::ExpandableHeading
### All Publications

:::CodeblockTabs
Query

```graphql
query CatalogPublications($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: PublicationFilter) {
  catalog(
    appInfo: $appInfo
    deviceInfo: $deviceInfo
    authorization: $authorization
  ) {
    publicationsConnection(
      filter: $filter
    ) {
      edges {
        node {
          id
          name
          description
          type
          index
          language
          currentContentId
          thumbnails {
            kind
            url
          }
          properties {
            key
            value
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "publicationsConnection": {
        "edges": [
          {
            "node": {
              "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
              "name": "Newsstand",
              "description": "",
              "type": "KIOSK",
              "index": 1,
              "language": null,
              "currentContentId": "bb3ff14a-13fa-46d4-bd58-2726fd722c55",
              "thumbnails": [],
              "properties": []
            }
          },
          {
            "node": {
              "id": "c72424c7-4226-4e71-87a8-35e24599837c",
              "name": "Newsfeed",
              "description": "",
              "type": "CHANNEL",
              "index": 2,
              "language": null,
              "currentContentId": "7331d1d9-f824-48ef-b06f-746af096caf5",
              "thumbnails": [],
              "properties": [
                {
                  "key": "channel",
                  "value": "true"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Newsfeeds (internally called CHANNEL)

:::CodeblockTabs
Query

```graphql
query CatalogPublications($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: PublicationFilter) {
  catalog(
    appInfo: $appInfo
    deviceInfo: $deviceInfo
    authorization: $authorization
  ) {
    publicationsConnection(
      filter: $filter
    ) {
      edges {
        node {
          id
          name
          description
          type
          index
          language
          currentContentId
          thumbnails {
            kind
            url
          }
          properties {
            key
            value
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "type": {
      "value": "CHANNEL"
    }
  }
}
```

```json
{
  "data": {
    "catalog": {
      "publicationsConnection": {
        "edges": [
          {
            "node": {
              "id": "c72424c7-4226-4e71-87a8-35e24599837c",
              "name": "Newsfeed",
              "description": "",
              "type": "CHANNEL",
              "index": 2,
              "language": null,
              "currentContentId": "7331d1d9-f824-48ef-b06f-746af096caf5",
              "thumbnails": [],
              "properties": [
                {
                  "key": "channel",
                  "value": "true"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Newsstands (internally called KIOSK)

:::CodeblockTabs
Query

```graphql
query CatalogPublications($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: PublicationFilter) {
  catalog(
    appInfo: $appInfo
    deviceInfo: $deviceInfo
    authorization: $authorization
  ) {
    publicationsConnection(
      filter: $filter
    ) {
      totalCount
      edges {
        node {
          id
          name
          description
          type
          index
          language
          currentContentId
          thumbnails {
            kind
            url
          }
          properties {
            key
            value
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "type": {
      "value": "KIOSK"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "publicationsConnection": {
        "edges": [
          {
            "node": {
              "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
              "name": "Newsstand",
              "description": "",
              "type": "KIOSK",
              "index": 1,
              "language": null,
              "currentContentId": "bb3ff14a-13fa-46d4-bd58-2726fd722c55",
              "thumbnails": [],
              "properties": []
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Subscriptions

Apps can offer subscriptions to their users. Currently only native app store subscriptions are supported. Subscriptions will only unlock content for the publications to which they have been assigned.

The *subscriptionsConnection* can be used to query the subscriptions of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

### Example queries

::::ExpandableHeading
### All Subscriptions (ANDROID)

:::hint{type="info"}
Note the deviceInfo -> platform field value of ANDROID. Subscriptions are assigned to a platform (ANDROID/IOS).
:::

:::CodeblockTabs
Query

```graphql
query CatalogSubscriptions($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: SubscriptionFilter, $sort: [SubscriptionComparator!], $first: Int, $after: String) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    subscriptionsConnection(filter: $filter, sort: $sort, first: $first, after: $after) {
      edges {
        node {
          id
          name
          description
          type
          duration
          hidden
          productId
          groupId
          additionalUnlocks {
            count
            unit
          }
          properties {
            key
            value
          }
          thumbnails {
            kind
            url
          }
          eligibilityInfo {
            trial
            introductoryPricing
            discountOffers
          }
          currentReceiptInfo {
            isTrialPeriod
            isIntroOfferPeriod
            expirationDate
            autoResumeDate
            autoRenewing
          }
          historicReceiptInfo {
            hadPurchased
            hadTrial
            hadIntroductoryPricing
          }
          publications {
            id
            name
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "ANDROID"
  },
  "filter": {}
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "subscriptionsConnection": {
        "edges": [
          {
            "node": {
              "id": "40382b25-68e0-48dc-8234-511f84cc9088",
              "name": "Premium 1 Month",
              "description": "1 month of Premium access",
              "type": "AUTORENEWABLE",
              "duration": "ONE_MONTH",
              "hidden": false,
              "productId": "com.example.monthly",
              "groupId": null,
              "additionalUnlocks": {
                "count": 0,
                "unit": "DAY"
              },
              "properties": [],
              "thumbnails": [],
              "eligibilityInfo": {
                "trial": null,
                "introductoryPricing": true,
                "discountOffers": false
              },
              "currentReceiptInfo": null,
              "historicReceiptInfo": {
                "hadPurchased": false,
                "hadTrial": false,
                "hadIntroductoryPricing": false
              },
              "publications": [
                {
                  "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
                  "name": "Newsstand"
                },
                {
                  "id": "c72424c7-4226-4e71-87a8-35e24599837c",
                  "name": "Newsfeed"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Subscriptions (IOS)

:::hint{type="info"}
Note the deviceInfo -> platform field value of IOS. Subscriptions are assigned to a platform (ANDROID/IOS).
:::

:::CodeblockTabs
Query

```graphql
query CatalogSubscriptions($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: SubscriptionFilter, $sort: [SubscriptionComparator!], $first: Int, $after: String) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    subscriptionsConnection(filter: $filter, sort: $sort, first: $first, after: $after) {
      edges {
        node {
          id
          name
          description
          type
          duration
          hidden
          productId
          groupId
          additionalUnlocks {
            count
            unit
          }
          properties {
            key
            value
          }
          thumbnails {
            kind
            url
          }
          eligibilityInfo {
            trial
            introductoryPricing
            discountOffers
          }
          currentReceiptInfo {
            isTrialPeriod
            isIntroOfferPeriod
            expirationDate
            autoResumeDate
            autoRenewing
          }
          historicReceiptInfo {
            hadPurchased
            hadTrial
            hadIntroductoryPricing
          }
          publications {
            id
            name
            type
            properties {
              key
              value
              type
            }
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "IOS"
  },
  "filter": {}
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "subscriptionsConnection": {
        "edges": [
          {
            "node": {
              "id": "51d04143-d847-435e-a762-cbeff24e4fb2",
              "name": "Premium 1 Month",
              "description": "1 month of Premium access",
              "type": "AUTORENEWABLE",
              "duration": "ONE_MONTH",
              "hidden": false,
              "productId": "com.example.monthly",
              "groupId": null,
              "additionalUnlocks": {
                "count": 0,
                "unit": "DAY"
              },
              "properties": [],
              "thumbnails": [],
              "eligibilityInfo": {
                "trial": true,
                "introductoryPricing": true,
                "discountOffers": false
              },
              "currentReceiptInfo": null,
              "historicReceiptInfo": {
                "hadPurchased": false,
                "hadTrial": false,
                "hadIntroductoryPricing": false
              },
              "publications": [
                {
                  "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
                  "name": "Newsstand"
                },
                {
                  "id": "c72424c7-4226-4e71-87a8-35e24599837c",
                  "name": "Newsfeed"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Publication Products

Publication products allows publishers, depending of the type of the product, to offer users to purchase all previously published content or use the same (consumable) app store product for multiple purchases of different contents. Publication products only unlock content for the publications they are assigned to.

The *publicationProductsConnection* can be used to query the available product of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

### Example queries

::::ExpandableHeading
### All Publication products (ANDROID)

:::hint{type="info"}
Note the deviceInfo -> platform field value of ANDROID. Publication products are assigned to a platform (ANDROID/IOS).
:::

:::CodeblockTabs
Query

```graphql
query CatalogPublicationProducts(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $filter: PublicationProductFilter,
    $sort: [PublicationProductComparator!],
    $first: Int,
    $after: String
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        publicationProductsConnection(
            filter: $filter,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            edges {
                node {
                    id
                    name
                    description
                    type
                    hidden
                    productId
                    index
                    properties {
                        key
                        value
                        type
                    }
                    thumbnails {
                        kind
                        url
                    }
                    ... on ContentsCompletionProduct {
                        purchased
                        includesLatestContent
                    }
                    publications {
                        id
                        unlockableContentsConnection {
                            edges {
                                node {
                                    id
                                    name
                                    publicationDate
                                    productId
                                    publicationId
                                    thumbnails {
                                        kind
                                        url
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "ANDROID"
  },
  "filter": {
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "publicationProductsConnection": {
        "edges": [
          {
            "node": {
              "id": "dc4ae6d4-c148-4997-8878-e328d519c467",
              "name": "Consumable Product",
              "description": "",
              "type": "REPEATABLE_CONTENT_PURCHASE",
              "hidden": false,
              "productId": "com.example.consumable",
              "index": 0,
              "properties": [],
              "thumbnails": [],
              "publications": [
                {
                  "id": "c72424c7-4226-4e71-87a8-35e24599837c",
                  "unlockableContentsConnection": {
                    "edges": []
                  }
                },
                {
                  "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
                  "unlockableContentsConnection": {
                    "edges": []
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### All Publication products (IOS)

:::CodeblockTabs
Query

```graphql
query CatalogPublicationProducts(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $filter: PublicationProductFilter,
    $sort: [PublicationProductComparator!],
    $first: Int,
    $after: String
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        publicationProductsConnection(
            filter: $filter,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            edges {
                node {
                    id
                    name
                    description
                    type
                    hidden
                    productId
                    index
                    properties {
                        key
                        value
                        type
                    }
                    thumbnails {
                        kind
                        url
                    }
                    ... on ContentsCompletionProduct {
                        purchased
                        includesLatestContent
                    }
                    publications {
                        id
                        unlockableContentsConnection {
                            edges {
                                node {
                                    id
                                    name
                                    publicationDate
                                    productId
                                    publicationId
                                    thumbnails {
                                        kind
                                        url
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "IOS"
  },
  "filter": {
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "publicationProductsConnection": {
        "edges": [
          {
            "node": {
              "id": "a7d74570-f168-43df-9155-aa5833ab6fa2",
              "name": "Consumable Product",
              "description": "",
              "type": "REPEATABLE_CONTENT_PURCHASE",
              "hidden": false,
              "productId": "com.example.consumable",
              "index": 0,
              "properties": [],
              "thumbnails": [],
              "publications": [
                {
                  "id": "c72424c7-4226-4e71-87a8-35e24599837c",
                  "unlockableContentsConnection": {
                    "edges": []
                  }
                },
                {
                  "id": "66b940ce-f574-4c98-805c-c9785d2fc969",
                  "unlockableContentsConnection": {
                    "edges": []
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Taxonomies

The *taxonomiesConnection* can be used to query the taxonomies, e.g. tags and categories, but also authors of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

### Example queries

::::ExpandableHeading
### All Taxonomies

:::CodeblockTabs
Query

```graphql
query CatalogTaxonomies($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $filter: TaxonomyFilter) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    taxonomiesConnection(filter: $filter) {
      edges {
        node {
          id
          parentId
          type
          name
          properties {
            key
            value
            type
          }
          thumbnails {
            kind
            url
          }
        }
      }
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "taxonomiesConnection": {
        "edges": [
          {
            "node": {
              "id": "max-mustermann",
              "parentId": "",
              "type": "author",
              "name": "Max Mustermann",
              "properties": [
                {
                  "key": "first_name",
                  "value": "",
                  "type": "STRING"
                },
                {
                  "key": "last_name",
                  "value": "",
                  "type": "STRING"
                },
                {
                  "key": "user_email",
                  "value": "",
                  "type": "STRING"
                },
                {
                  "key": "user_url",
                  "value": "",
                  "type": "STRING"
                },
                {
                  "key": "description",
                  "value": "",
                  "type": "STRING"
                }
              ],
              "thumbnails": []
            }
          },
          {
            "node": {
              "id": "news",
              "parentId": "",
              "type": "category",
              "name": "News",
              "properties": [],
              "thumbnails": []
            }
          },
          {
            "node": {
              "id": "news",
              "parentId": "",
              "type": "tag",
              "name": "news",
              "properties": [],
              "thumbnails": []
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Collections

Collections are curated lists of posts/articles. 

The *collectionsConnection* can be used to query the collections of an app. The results can be filtered and sorted using the *filter* and *sort* arguments.

### Example queries

::::ExpandableHeading
### All Collections

:::CodeblockTabs
Query

```graphql
query CatalogCollections(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $filter: CollectionFilter,
    $sort: [CollectionComparator!],
    $first: Int,
    $after: String,
    $elementsFirst: Int,
    $elementsAfter: String
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        collectionsConnection(
            filter: $filter,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            pageInfo {
                hasPreviousPage
                hasNextPage
                startCursor
                endCursor
            }
            edges {
                cursor
                node {
                    id
                    name
                    properties {
                        key
                        value
                        type
                    }
                    elementsConnection(
                        first: $elementsFirst,
                        after: $elementsAfter
                    ) {
                        pageInfo {
                            hasPreviousPage
                            hasNextPage
                            startCursor
                            endCursor
                        }
                        edges {
                            cursor
                            node {
                                ... on ContentElement {
                                    id
                                    content {
                                        id
                                        name
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "collectionsConnection": {
        "pageInfo": {
          "hasPreviousPage": false,
          "hasNextPage": false,
          "startCursor": "1",
          "endCursor": "1"
        },
        "edges": [
          {
            "cursor": "1",
            "node": {
              "id": "8128fec3-110a-4e6e-8654-461eea8f7321",
              "name": "Daily News",
              "properties": [],
              "elementsConnection": {
                "pageInfo": {
                  "hasPreviousPage": false,
                  "hasNextPage": false,
                  "startCursor": "1",
                  "endCursor": "1"
                },
                "edges": [
                  {
                    "cursor": "1",
                    "node": {
                      "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                      "content": {
                        "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                        "name": "Example News"
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### Collection with name

:::CodeblockTabs
Query

```graphql
query CatalogCollections(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $filter: CollectionFilter,
    $sort: [CollectionComparator!],
    $first: Int,
    $after: String,
    $elementsFirst: Int,
    $elementsAfter: String
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        collectionsConnection(
            filter: $filter,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            pageInfo {
                hasPreviousPage
                hasNextPage
                startCursor
                endCursor
            }
            edges {
                cursor
                node {
                    id
                    name
                    properties {
                        key
                        value
                        type
                    }
                    elementsConnection(
                        first: $elementsFirst,
                        after: $elementsAfter
                    ) {
                        pageInfo {
                            hasPreviousPage
                            hasNextPage
                            startCursor
                            endCursor
                        }
                        edges {
                            cursor
                            node {
                                ... on ContentElement {
                                    id
                                    content {
                                        id
                                        name
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "filter": {
    "name": {
      "value": "Daily News"
    }
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "collectionsConnection": {
        "pageInfo": {
          "hasPreviousPage": false,
          "hasNextPage": false,
          "startCursor": "1",
          "endCursor": "1"
        },
        "edges": [
          {
            "cursor": "1",
            "node": {
              "id": "8128fec3-110a-4e6e-8654-461eea8f7321",
              "name": "Daily News",
              "properties": [],
              "elementsConnection": {
                "pageInfo": {
                  "hasPreviousPage": false,
                  "hasNextPage": false,
                  "startCursor": "1",
                  "endCursor": "1"
                },
                "edges": [
                  {
                    "cursor": "1",
                    "node": {
                      "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                      "content": {
                        "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                        "name": "Example News"
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Menus

Menus are currently only used for websites. They allow dynamically configuring the menu of a Purple-based website.

The *menusConnection&#xA0;*&#x63;an be used to query the menus of an app. The results can be filtered using the *filter* argument.

### Example queries

::::ExpandableHeading
### All Menus

:::CodeblockTabs
Query

```graphql
query Menu(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo) {
        menusConnection {
            edges {
                node {
                    id
                    name
                    properties {
                        key
                        value
                        type
                    }
                    items {
                        id
                        parentId
                        name
                        sortIndex
                        url
                        properties {
                            key
                            value
                            type
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  }
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "menusConnection": {
        "edges": [
          {
            "node": {
              "id": "45852f06-50d7-4008-9d5c-89439dbde2fa",
              "name": "Site Menu",
              "properties": [],
              "items": [
                {
                  "id": "792a1527-3136-433e-9239-2e19ec53077a",
                  "parentId": "45852f06-50d7-4008-9d5c-89439dbde2fa",
                  "name": "Example Link",
                  "sortIndex": 1,
                  "url": "https://example.com",
                  "properties": []
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Search

The API allows to perform full-text searches across all contents of an app.

The *contentSearchConnection* can be used to perform full-text searches. 

The [Simple query string syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html#simple-query-string-syntax) can be used inside the *searchPhrase* to specify how the search phrase should be processed.

The following operators are supported:

- \+ signifies AND operation
- \| signifies OR operation
- \- negates a single token
- " wraps a number of tokens to signify a phrase for searching
- \* at the end of a term signifies a prefix query
- ( and ) signify precedence
- \~N after a word signifies edit distance (fuzziness)
- \~N after a phrase signifies slop amount

:::hint{type="warning"}
The "Simple query string syntax" is only available when fuzzyMatching is false.
:::

### Example queries

::::ExpandableHeading
### Search for contents that contain the word "News"

:::CodeblockTabs
Query

```graphql
query CatalogSearch(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $searchPhrase: String!,
    $contentFilter: ContentFilter,
    $fuzzyMatching: Boolean,
    $findAllWords: Boolean,
    $sort: [ContentSearchResultComparator!],
    $first: Int,
    $after: String
    $issuePageSort: [IssuePageComparator!]
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        contentSearchConnection(
            searchPhrase: $searchPhrase,
            contentFilter: $contentFilter,
            fuzzyMatching: $fuzzyMatching,
            findAllWords: $findAllWords,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            edges {
                node {
                    ... on IssueSearchResult {
                        issue {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        pagesConnection(
                            sort: $issuePageSort
                        ) {
                            edges {
                                node {
                                    excerpt
                                    pageIndex
                                    pageNumber
                                    pageLabel
                                    pageTitle
                                    elementAlias
                                }
                            }
                        }
                    }
                    ... on PostSearchResult {
                        post {
                            id
                            name
                            description
                            access
                            contentHtml
                        }
                        excerpt
                    }
                    ... on  BundleSearchResult {
                        bundle {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        posts {
                            post {
                                id
                                name
                            }
                            excerpt
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "searchPhrase": "News"
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentSearchConnection": {
        "edges": [
          {
            "node": {
              "post": {
                "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                "name": "Example News",
                "description": "",
                "access": "FREE",
                "contentHtml": "<h1 class='entry-title'>Example News</h1>\n<p>This is a news article in the news category and news tag</p>\n"
              },
              "excerpt": "Example <strong>News</strong> This is a <strong>news</strong> article in the <strong>news</strong> category and <strong>news</strong> tag"
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### Search for contents that contain the words "News" and "article" (using the option findAllWords)

:::CodeblockTabs
Query

```graphql
query CatalogSearch(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $searchPhrase: String!,
    $contentFilter: ContentFilter,
    $fuzzyMatching: Boolean,
    $findAllWords: Boolean,
    $sort: [ContentSearchResultComparator!],
    $first: Int,
    $after: String
    $issuePageSort: [IssuePageComparator!]
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        contentSearchConnection(
            searchPhrase: $searchPhrase,
            contentFilter: $contentFilter,
            fuzzyMatching: $fuzzyMatching,
            findAllWords: $findAllWords,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            edges {
                node {
                    ... on IssueSearchResult {
                        issue {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        pagesConnection(
                            sort: $issuePageSort
                        ) {
                            edges {
                                node {
                                    excerpt
                                    pageIndex
                                    pageNumber
                                    pageLabel
                                    pageTitle
                                    elementAlias
                                }
                            }
                        }
                    }
                    ... on PostSearchResult {
                        post {
                            id
                            name
                            description
                            access
                            contentHtml
                        }
                        excerpt
                    }
                    ... on  BundleSearchResult {
                        bundle {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        posts {
                            post {
                                id
                                name
                            }
                            excerpt
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "searchPhrase": "News article",
  "findAllWords": true
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentSearchConnection": {
        "edges": [
          {
            "node": {
              "post": {
                "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                "name": "Example News",
                "description": "",
                "access": "FREE",
                "contentHtml": "<h1 class='entry-title'>Example News</h1>\n<p>This is a news article in the news category and news tag</p>\n"
              },
              "excerpt": "Example <strong>News</strong> This is a <strong>news</strong> <strong>article</strong> in the <strong>news</strong> category and <strong>news</strong> tag"
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

::::ExpandableHeading
### Search for contents that contain the words "News" or "article"

:::CodeblockTabs
Query

```graphql
query CatalogSearch(
    $appInfo: AppInfo!,
    $deviceInfo: DeviceInfo!,
    $authorization: Authorization,
    $searchPhrase: String!,
    $contentFilter: ContentFilter,
    $fuzzyMatching: Boolean,
    $findAllWords: Boolean,
    $sort: [ContentSearchResultComparator!],
    $first: Int,
    $after: String
    $issuePageSort: [IssuePageComparator!]
) {
    catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
        contentSearchConnection(
            searchPhrase: $searchPhrase,
            contentFilter: $contentFilter,
            fuzzyMatching: $fuzzyMatching,
            findAllWords: $findAllWords,
            sort: $sort,
            first: $first,
            after: $after
        ) {
            edges {
                node {
                    ... on IssueSearchResult {
                        issue {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        pagesConnection(
                            sort: $issuePageSort
                        ) {
                            edges {
                                node {
                                    excerpt
                                    pageIndex
                                    pageNumber
                                    pageLabel
                                    pageTitle
                                    elementAlias
                                }
                            }
                        }
                    }
                    ... on PostSearchResult {
                        post {
                            id
                            name
                            description
                            access
                            contentHtml
                        }
                        excerpt
                    }
                    ... on  BundleSearchResult {
                        bundle {
                            id
                            name
                            description
                            access
                            purchaseData {
                                purchased
                                purchasedBy
                            }
                        }
                        posts {
                            post {
                                id
                                name
                            }
                            excerpt
                        }
                    }
                }
            }
        }
    }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "searchPhrase": "News article"
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "contentSearchConnection": {
        "edges": [
          {
            "node": {
              "post": {
                "id": "7331d1d9-f824-48ef-b06f-746af096caf5",
                "name": "Example News",
                "description": "",
                "access": "FREE",
                "contentHtml": "<h1 class='entry-title'>Example News</h1>\n<p>This is a news article in the news category and news tag</p>\n"
              },
              "excerpt": "Example <strong>News</strong> This is a <strong>news</strong> <strong>article</strong> in the <strong>news</strong> category and <strong>news</strong> tag"
            }
          },
          {
            "node": {
              "bundle": {
                "id": "3c3172aa-a403-4845-9471-00e9cf9616c4",
                "name": "Example Issue",
                "description": "",
                "access": "FREE",
                "purchaseData": {
                  "purchased": true,
                  "purchasedBy": []
                }
              },
              "posts": [
                {
                  "post": {
                    "id": "ff08083f-cc39-4728-9861-34532b17907d",
                    "name": "Issue Article"
                  },
                  "excerpt": "Issue <strong>Article</strong> This is an <strong>article</strong> that is part of an issue"
                }
              ]
            }
          }
        ]
      }
    }
  }
}
```
:::
::::

## Suggestions

The suggestions API under searchSuggestions takes all contents from a team and provides suggestions based on the provided input string.

### Example queries

::::ExpandableHeading
### Suggestions for "New"

:::CodeblockTabs
Query

```graphql
query CatalogSearch($appInfo: AppInfo!, $deviceInfo: DeviceInfo!, $authorization: Authorization, $input: String!) {
  catalog(appInfo: $appInfo, deviceInfo: $deviceInfo, authorization: $authorization) {
    searchSuggestions(input: $input) {
      text
    }
  }
}
```

Variables

```json
{
  "appInfo": {
    "appId": "149923c7-0c63-4194-98dd-4491eac455dd",
    "appVersion": "1.0",
    "preview": false
  },
  "deviceInfo": {
    "deviceId": "web",
    "deviceModel": "Chrome",
    "deviceOs": "100",
    "locale": "de_DE",
    "platform": "WEB"
  },
  "input": "New"
}
```

Example Response

```json
{
  "data": {
    "catalog": {
      "searchSuggestions": [
        {
          "text": "Newsstand Issue"
        },
        {
          "text": "news"
        },
        {
          "text": "Example News"
        }
      ]
    }
  }
}
```
:::
::::

# API Keys

The Catalog API can be secured using an API key. In order to activate the authorisation for the API, you need to activate the check mark next to "Secured Mode" in the "Basic Settings" tab for your App in the Purple Manager:



::Image[]{alt="Secure Mode Checkmark" src="https://api.archbee.com/api/optimize/ygR6KtT9QI_R0u3uKTJsm/p5x2VdmFjjQ8ghmdDLNWe_image.png" size="70" width="1022" height="114" caption="Secure Mode Checkmark" position="center" showCaption="true"}

Once the secure mode is activated, the API key can be found in the API sub-menu of an app in the Purple Manager
