Field types

The GraphQL schema is automatically generated based on models, components, remote sources, and fields. Prepr supports all GraphQL's default scalar types, such as String, Int, Float, Boolean, and some custom types. Each field type you add to a model has a unique name used for interaction with the API.

Prepr UI name
Description
IDIn lower camel-case with alphanumeric characters and underscores only. For example, title.

This page lists all core field types available for your API, as well as sample queries to retrieve content for these through the API. Also, it is recommended that you browse a schema with an API Explorer to get a complete overview of all field type definitions and filtering options applicable to your setup.

Text

Text fields return a simple string with the content of the field.

{
  Pages {
      items {
          single_line_text
          multi_line_text
          html_text
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "single_line_text": "The story behind Prepr CMS",
                  "multi_line_text": "Founded in 2018 as a user-friendly CMS for media organizations, we’ve matured into a smart solution trusted by content teams around the globe.",
                  "my_html_text": "<p>Check out this <a href=\"say-quiche\">article</a></p>"
              }
          ]
      }
  }
}

In the case of an HTML text field, the string can contain basic HTML tags for the paragraph, heading, bold, italic, underline, unordered list, ordered list, link, table and alignment styles.

Note

The href value for a link to a content item is its Slug by default as shown in the response example above. To get the content item Id instead, add the header Prepr-Resolve-Internal-Links to your request and set it to false. Clear the cache on the Access tokens page after adding this header to your request.

List (Enum)

List fields return a simple string with the content of the field. The return type will match the linked Enumeration.

{
  Pages {
      items {
          type_of_page
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "type_of_page": "FULL_LANDING_PAGE"
              }
          ]
      }
  }
}

Dynamic Content Field

The Dynamic Content Editor enables editors for a next-level authoring experience. Embed videos, social media posts, maps, assets, and components to create rich content items.

Check out the Dynamic Content Field section on how to query all types of content.

Assets

Assets are photos, videos, audio files or documents that you can attach to a content item. The Asset type comes with its own set of default fields.

Type definition

type Asset {
    _id: String
    name: String
    description: String
    url: String
    cdn_files: List of CdnFileType # Optional
    duration : Int # Duration in seconds
    width : Int
    height : Int
    mime_type: String
    original_name: String
    author: String
    caption: String
    alignment: EnumType AssetAlignment (left, center, right)
}

Check the sample query for retrieving the default asset fields like _id, author, caption and alignment.

{
    Pages {
        items {
            assets {
               _id
               author
               caption
               alignment
            }
        }
    }
}

Images

The GraphQL API exposes a set of image transformation and formatting options. The following table lists the most common operations.

Operation
Argument
Description
Resizewidth, heightTo change the image size.

Options: a value in pixels.
CropcropTo crop a particular area of an image.

Options: north, northeast, east, southeast, south, southwest, west, northwest, center, centre.
PresetspresetTo retrieve cropped images generated in the Prepr Editor interface.

Options: the name you defined for the preset you would like to retrieve.
FormattingformatTo define image format.

Options: jpg, png, etc.

Images are served in the best format if not specified. Read more in the Automatic image optimization paragraph below.
Original Fileas_fileIf true; returns the original uploaded file without any optimisation or compression.

To perform image operations, you need to pass arguments to the image URL field as shown below:

# Arguments: `width`, `height`, and `crop`
# Desired width and height of the image in pixels.
# Crop options: north, northeast, east, southeast, south, southwest, west, northwest, center, centre.

# Arguments: `preset`
# If a preset is configured on the model, a specific crop or size
# can be retrieved by setting the name of the preset. In this example below,
# we created two presets named `desktop` and `mobile`. The desktopUrl and
# mobileUrl prefixes of your own choosing used to differentiate image URLs for crops.

{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        images {
            # Default Image URL
            url
            
            # Scaled to the given dimensions
            url(width: 1920, height: 1080)
            
            # Scaled to the given dimensions using a fixed crop
            url(width: 400, height: 200, crop: "southeast”)
            
            # Using a asset preset
            desktopUrl: url(preset: "desktop")
            mobileUrl: url(preset: "mobile")
        }
    }
} 
{
  "data": {
    "Post": {
      "images": [
        {
          "url": "https://example.stream.prepr.io/70j00cqmzn532t4m86rLdhH-e7ed3944-54e3-46d4-9be5-b5c67629d7b1.jpg"
        }
      ]
    }
  }
}
{
  "data": {
    "Post": {
      "images": {
          "url": "https://example.stream.prepr.io/70j00cqmzn532t4m86rLdhH-e7ed3944-54e3-46d4-9be5-b5c67629d7b1.jpg"
        }
    }
  }
}

Automatic image optimization

Images are automatically served in WebP or AVIF to browsers that natively support those image formats. WebP and AVIF provide better image compression and faster page loading times than other file formats.

Video

Video files uploaded to Prepr will be stored in and played from Mux for all new Prepr accounts. You can configure streaming options for videos by including the resolution and duration attributes in your API request. Using the cover attribute, you can get a video thumbnail from Prepr or customize it with the Mux options. Please see an example code snippet below.

To learn how to display video content in your web app, please follow our guides for live video streaming and video files on-demand. For additional information, refer to the Mux documentation.

Important

To retrieve a playback_id, make sure you use the GraphQL API token version of 2022-08-15 or later.

# Prepr will upload all audio files directly to Mux and add an HLS URL to the asset.
# The HLS streaming URL is returned by default.
# With the `res` option, an MP4 version in `high`, `medium`, and `low` can be requested to support legacy browsers that do not support HLS.
# The cover is adjustable with all Mux image options.

{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        videos {
            playback_id
            hls : url
            mp4_high : url(res:"high")
            mp4_medium : url(res:"medium")
            mp4_low : url(res:"low")
            duration
            cover
        }
    }
} 
{
    "data": {
        "Post": {
            "videos": [
                {
                    "playback_id" : "fyd7tJBz01bUEsbgs7d02US01K8Tp00SB3gWn01WPneVKeCmQIM",
                    "hls": "https://stream.mux.com/fyd7tJBz01bUEsbgs7d02US01K8Tp00SB3gWn01WPneVKeCmQIM.m3u8",
                    "mp4_high": "https://stream.mux.com/fyd7tJBz01bgggUEsbs7d02US01K8Tp00SB3Wn01WPngeVKeCmQIM/high.mp4",
                    "mp4_medium": "https://stream.mux.com/fydd7tJBz01bggbUEsbs7d02US01K8Tp00SB3Wn01WPneVKeCmQIM/medium.mp4",
                    "mp4_low": "https://stream.mux.com/fyd7tJBgz01bUEsbs7d02US01K8Tp00SB3Wn01WPneVKeCmQIM/low.mp4",
                    "duration": 12045,
                    "cover": "https://image.mux.com/fyd7tJBz01bgUEsbs7d02US01K8Tp00SB3Wn01WPneVKeCmQIM/thumbnail.jpg"
                }
            ]
        }
    }
}
# The AWS integration is deprecated and no longer available for new Prepr accounts.

# If you enable the AWS Media Convert integration videos are
# automatically transcoded after uploading. The 1080P MP4 versions is returned
# by default. All other transcoded versions are available as cdn_files.


# REQUEST

{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        videos {
            url
            cover
            duration
            cdn_files { # Optional 
                url
                profile
            }
        }
    }
} 


# RESPONSE

{
    "data": {
        "Post": {
            "videos": [
                {
                    "url": "https://example.files.prepr.io/19ffea1d-19c6-4bd_1080.mp4",
                    "cover": "https://example.stream.prepr.io/w_1920/19ffea1d-19c6.jpg"
                    "duration": 19458,
                }
            ]
        }
    }
}

Audio

Audio files uploaded to Prepr will be stored in and played from Mux for all new Prepr accounts. You can configure streaming options for your audio files by including the resolution and duration attributes in the API request. Please see an example code snippet below.

To learn how to play audio content in your web app, please follow our guidelines for audio files.

# Prepr will upload all audio files directly to Mux and add an HLS URL to the asset.
# The HLS streaming URL is returned by default.
# With the `res` option, an M4A version can be requested to support legacy browsers that do not support HLS.
{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        assets {
            url
            m4a : url(res:"m4a")
            duration
        }
    }
} 
# Thanks to our integration with Mux, Prepr will upload all audio files
# directly to Mux, and will add HLS url to the asset.

{
    "data": {
        "Post": {
            "assets": [
                {
                    "hls": "https://stream.mux.com/f2do00QZa4Z144v01T9loEfXpMLbHoEdYWKwDa4TBKtInY.m3u8",
                    "mp4_high": "https://stream.mux.com/fyd7tJBz01bgggUEsbs7d02US01K8Tp00SB3Wn01WPngeVKeCmQIM/static.m4a",
                    "duration": 52827
                }
            ]
        }
    }
}
# The AWS integration is deprecated and no longer available for new Prepr accounts.

# REQUEST 

# If you enable the AWS Media Convert integration audios are automatically
# transcoded after uploading. The MP3 versions is returned by default.
# All other (optional) transcoded versions are available as cdn_files.

{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        audios {
            _id
            url
            duration
            cdn_files { # Optional 
                url
                profile
            }
        }
    }
}

# RESPONSE

# If you enable the AWS Media Convert integration audios are automatically
# transcoded after uploading. The MP3 versions is returned by default.

{
    "data": {
        "Post": {
            "audios": [
                {
                    "_id": "baed7e0d-f63a-4807-a193-034b6ff10335",
                    "url": "https://example.files.prepr.io/6ad8a6797e207f4c41e33af64b6f8abb.mp3"
                    "duration": 134,
                }
            ]
        }
    }
}

Files

Files or documents will be available by a simple url.

{
    Post(id: "dbd2e3d9-350c-408e-b857-fdca7977c925") {
        documents {
            url
            mime_type
        }
    }
} 
{
    "data": {
        "Post": {
            "documents": [
                {
                    "url": "https://example.files.prepr.io/90b6b6b5-3e56-459c-a8d1-0bdbe48cb35d.pdf",
                    "mime_type": "application/pdf"
                }
            ]
        }
    }
}

Fetching single-asset field

You can choose between using a multiple-asset or single-asset field when adding it to a model or component, depending on the number of assets you intend to add.

When querying a single-asset filed, you'll receive a response similar to this:

{
    "data": {
        "Post": {
            "video": {
                 "playback_id" : "fyd7tJBz01bUEsbgs7d02US01K8Tp00SB3gWn01WPneVKeCmQIM",
                 "hls": "https://stream.mux.com/fyd7tJBz01bUEsbgs7d02US01K8Tp00SB3gWn01WPneVKeCmQIM.m3u8",
                 "duration": 12045
            }
        }
    }
}

Hostnames

To set up hostnames for streaming assets in your front-end application (e.g., when using Nuxt/Next.JS's Image Optimization plugins or for CSP configurations), obtain them from your Prepr environment by going to Settings > Access Tokens.

Integer

Integers are whole number, and are often used to store stock quantities, prices in cents ect. For example, here we have a product with an Integer field for quantity.

{
  Pages {
      items {
          quantity
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "quantity": 53
              }
          ]
      }
  }
}

Float

Float types are fields in which you can make number entries with decimal places, for accurate calculation such as the price of an item, distance, or weight. For example, here we have a product with a Float field for price.

{
    Pages {
        items {
            price
        }
    }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "price": 12.95
              }
          ]
      }
  }
}

Boolean

For example, here we have posts with a Boolean field for premium_only.

{
  Pages {
      items {
          premium_only
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "premium_only": true
              }
          ]
      }
  }
}

Stack

The Stack field stores a list of (personalized/ab tested) models/components. This is a powerful type that allows you to create a site using the Stack field as your page builder.

Find out more how to run A/B tests using the Stack field on this page.
Find out more how to personalize using the Stack field on this page.

One-to-many

Our Post model has a One-to-many stack to the Promo component. Fetching the data is as simple as with any other model field.

Pages {
    sections {
        __typename
        title
        image {
            url
        }
    },
}
{
    "data": {
        "Pages": {
            "items": [
                {
                    "sections": [
                        {
                            "__typename": "Promo",
                            "title": "New Deep Dive Sessions",
                            "image": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                }
                            ]
                        },
                        {
                            "__typename": "Promo",
                            "title": "New Free-diving Sessions",
                            "image": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                }
                            ]
                        },
                        {
                            "__typename": "Promo",
                            "title": "New Snorkeling Sessions",
                            "image": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

Union Type

In this example we have a Page model with a Stack that holds the model Navigation and the components Hero, Promo and Grid. The example below shows how to fetch the different types.

Pages {
    sections {
        __typename
        ... on Navigation {
            name
            nav_items {
                name
                url
                alt
            }
        },
        ... on Hero {
            title
            sub_title
        },
        ... on Promo {
            title
            image {
                url
            }
        },
        ... on Grid {
            title
            number_of_columns
            gallery {
                url                
            }
        },
    },
}
{
    "data": {
        "Pages": {
            "items": [
                {
                    "sections": [
                        {
                            "__typename": "Navigation",
                            "name": "Main Navigation",
                            "nav_items": [
                                {
                                    "name": "About Us",
                                    "url": "/about-us",
                                    "alt": "About our Company"
                                }
                            ]                            
                        },
                        {
                            "__typename": "Hero",
                            "title": "About Us",
                            "sub_title": "Founded in 2018 as a user-friendly CMS for media organizations, we’ve matured into a smart solution trusted by content teams around the globe.",
                        },
                        {
                            "__typename": "Promo",
                            "title": "New Deep Dive Sessions",
                            "image": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                }
                            ]
                        },
                        {
                            "__typename": "Grid",
                            "title": "Our Amsterdam office",
                            "number_of_columns": 3,
                            "gallery": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                },
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/bd51e610-aa8b-4889-81dd-4f4b162c89ed.jpg"
                                },
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/49381d6c-d53c-4ab6-93e8-c06f7cb132e3.jpg"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

Content reference

The Content reference field stores a relation between one or more models. This powerful type allows you for example to create relationships between Posts and a Category or Posts and Author models.

Prepr supports two types of Content references, One-to-many and Union Type references.

One-to-many references allow you to create relationships between two types of defined models. The Union Type fields can reference to a set of models in a single field.

One-to-many

Our Post model has a One-to-many content reference to the Category model. Fetching the data is as simple as with any other model field.

Posts {
    title
    category {
        name
    }
}
{
    "data": {
        "Posts": {
            "items": [
                {
                    "title" : "Introducing Targeted Content personalization",
                    "category": [
                        {
                            "name": "Deep Dive"
                        }
                    ]
                }
            ]
        }
    }
}

Union Type

In this example we have a Page model with a Union type content reference to the Hero, Promo and Grid models. The example below shows how to fetch the different types.

Pages {
    sections {
        __typename
        ... on Hero {
            title
            sub_title
        },
        ... on Promo {
            title
            image {
                url
            }
        },
        ... on Grid {
            title
            number_of_columns
            gallery {
                url                
            }
        },
    },
}
{
    "data": {
        "Pages": {
            "items": [
                {
                    "sections": [
                        {
                            "__typename": "Hero",
                            "title": "About Us",
                            "sub_title": "Founded in 2018 as a user-friendly CMS for media organizations, we’ve matured into a smart solution trusted by content teams around the globe.",
                        },
                        {
                            "__typename": "Promo",
                            "title": "New Deep Dive Sessions",
                            "image": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                }
                            ]
                        },
                        {
                            "__typename": "Grid",
                            "title": "Our Amsterdam office",
                            "number_of_columns": 3,
                            "gallery": [
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                                },
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/bd51e610-aa8b-4889-81dd-4f4b162c89ed.jpg"
                                },
                                {
                                    "url": "https://1d9273inhp5w.b-cdn.net/w_1920/49381d6c-d53c-4ab6-93e8-c06f7cb132e3.jpg"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

Components

Components are transformed into their own GraphQL types. Components are often used to represent a set of reusable fields. To query the content of a component you need to specify the subfields like you do with a content model.

For example, we added a Component named header to the Page model.

{
  Pages {
      items {
          header {
              name
              gallery {
                  url
              }
          }
      }
  }
} 
{
  "data": {
      "Pages": {
          "items": [
              {
                  "header": {
                      "name": "Our mission & culture",
                      "gallery": [
                          {
                              "url": "https://1d9273inhp5w.b-cdn.net/w_1920/40d0e42a-c96a-40bc-a906-c8785a201fbd.jpg"
                          }
                      ]
                  }
              }
          ]
      }
  }
}

Remote content

The Remote content field allows an editor to reference content from an eCommerce platform, external CMS or legacy system in Prepr content items. A Remote Source has its own fields which are configured in the schema.

For example our ecommerce source has a product_id, category_id and image_url field.

{
  Product( id : "7e34880a-bbc7-4b6a-9642-c29c6d91a694" ) {
      ecommerce { // Remote Content field
          _id
          product_id
          category_id
          image_url
      }
  }
}
{
"data": {
  "Product": {
    "ecommerce": [
      {
        "_id": "daa86b97-beec-488c-876d-aa48fb16720e",
        "product_id": "V234792749-23487298347",
        "category_id": "CEJKHDFKHGKFJH-33",
        "image_url": "https://image.ecommerce.com/fyd7tJBz01bgUEsbs7d02US01K8Tp00SB3Wn01WPneVKeCmQIM.jpg"      
      }
    ]
  }
}
}

Check out the how to set up remote content to start with your first integration.

Remote content before API version 2023-01-10 (deprecated)

In the API versions before 2023-01-10 Remote content fields are returned as generic ContentIntegration type. Let's see the same example in the deprecated versions.

{
  Product( id : "7e34880a-bbc7-4b6a-9642-c29c6d91a694" ) {
      ecommerce { // Remote Content field
          _id
          data {
              key
              value
          }
      }
  }
}
{
"data": {
  "Products": {
    "items": [
      {
        "ecommerce": [
          {
            "_id": "daa86b97-beec-488c-876d-aa48fb16720e",
            "data": [
              {
                "key": "product_id",
                "value": "V234792749-23487298347"
              }
            ]
          }
        ]
      }
    ]
  }
}
}

Date

The Date field adheres to ISO 8601 standard. For example, March 14, 2020 is represented as 2020-03-14.

{
    Events {
        items {
            date
        }
    }
}
{
  "data": {
      "Events": {
          "items": [
              {
                  "date": "2022-02-17"
              }
          ]
      }
  }
}

Date & Time

The DateTime field adheres to ISO 8601 standard. For example, 09.30 AM on March 14, 2020 is represented as 2020-03-14T09:30:00+00:00.

{
    Events {
        items {
            date_time
        }
    }
}
{
  "data": {
      "Events": {
          "items": [
              {
                  "date_time": "2022-02-17T12:44:00+00:00"
              }
          ]
      }
  }
}

Date & Time Ranges

The DateTime Range fields are following the specification of the Date / Date & Time fields and have two subfields, from and until.

{
    Events {
        items {
            period {
                from
                until
            }
        }
    }
}
{
  "data": {
      "Events": {
          "items": [
              {
                  "period": [
                      {
                          "from": "2022-02-17",
                          "until": "2022-02-20"
                      }
                  ]
              }
          ]
      }
  }
}

Location

{
    Pages {
        items {
            location {
                latitude
                longitude
            }
        }
    }
}
{
    "data": {
        "Pages": {
            "items": [
                {
                    "location": {
                        "latitude": 52.087864,
                        "longitude": 5.1068509
                    }
                }
            ]
        }
    }
}

BusinessHours

Represents the time periods that this location is open for business. Holds a collection of BusinessHoursPeriod instances.

regular_hours Operating hours for the business.
special_hours This typically includes holiday hours, and other times outside of regular operating hours. These should override regular business hours,

{
    Pages {
        items {
            businesshours {
                regular_hours {
                    open_day
                    open_time
                    close_day
                    close_time  
                }
                special_hours {
                    open_day
                    open_time
                    close_day
                    close_time
                    is_closed
                    valid_from
                    valid_until
                }
            }
        }
    }
}
{
    "data": {
        "Pages": {
            "items": [
                {
                    "businesshours": {
                        "regular_hours": [
                            {
                                "open_day": "MONDAY",
                                "open_time": "10:00",
                                "close_day": "MONDAY",
                                "close_time": "17:30"
                            },
                            {
                                "open_day": "TUESDAY",
                                "open_time": "10:00",
                                "close_day": "TUESDAY",
                                "close_time": "17:30"
                            }
                        ],
                        "special_hours": [
                            {
                                "open_day": "SATURDAY",
                                "open_time": "00:00",
                                "close_day": "SATURDAY",
                                "close_time": "00:00",
                                "is_closed": true,
                                "valid_from": "2022-03-10",
                                "valid_until": "2022-03-10"
                            }
                        ]
                    }
                }
            ]
        }
    }
}

`is_closed`: If true, open_time, close_day, and close_time are ignored,
and should be treated as the location being closed for the entire open_day.

Color

The Color field is made up of HEX code.

{
  Pages {
      items {
          color
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "color": "#910505"
              }
          ]
      }
  }
}

Tag

Tags in Prepr have a predefined schema. This means that the type for any tag in the GraphQL schema follows the definition below.

{
  Pages {
      items {
          tags {
              body
          }
      }
  }
}
{
  "data": {
      "Pages": {
          "items": [
              {
                  "tags": [
                      {
                          "body": "headless"
                      },
                      {
                          "body": "cms"
                      }
                  ]
              }
          ]
      }
  }
}

Story (deprecated)

Use stories to group similar content items together and keep them easy to find. Editors can view the combined engagement of all content items in the story.

{
  Pages {
      items {
          _stories {
              _id
              body
          }
      }
  }
} 
{
  "data": {
      "Pages": {
          "items": [
              {
                  "_stories": [
                      {
                          "_id": "2a35e487-fae6-42d8-ad20-5e400e17a5a3",
                          "body": "My combined stories"
                      }
                  ]
              }
          ]
      }
  }
}