Schema
The Codex GraphQL API generates the schema definition based on the models created in the respective organization.
Types
The GraphQL schema is generated from the models defined in the specific organization in Codex. For each model in your organization, the Codex GraphQL API created a corresponding GraphQL type.
Names
Type name is the alias of the model created in Codex with title case. For example: 'Signature', 'Recipe', 'Publication' etc.
Reserved type names
Below is a list of reserved type names, which means you cannot use them as alias of a model.
Query type Query
Scalar types String, Float, Int, Boolean, DateTime, Json, 
All internal Codex types start with the keyword Codex. That means you cannot create models by using an alias that starts with the keyword Codex.
Fields
GraphQL type fields are generated from the corresponding content type fields. Each type contains a list of common fields explained below.
Names
Fields name is the alias of the model field as configured in Codex. For example: 'title', 'description', 'thumbnail', 'price' etc.
Types
Field type is determibed based on the following mappings:
| Codex Type | GraphQL Type | 
|---|---|
| Text | String | 
| List of texts | [String] | 
| Number (int) | Int | 
| List of numbers (int) | [Int] | 
| Number (decimal) | Decimal | 
| List of number (decimal) | [Decimal] | 
| DateTime | DateTime | 
| Boolean | Boolean | 
| Location | CodexLocation | 
| Referece | CodexEntry | 
| List of Refereces | CodexEntryCollection | 
| Media | CodexMedia | 
| Media | [CodexMedia] | 
| RichText | String | 
| RichContent | [CodexContentBlock] | 
| RichContent (v2) | CodexRichContent | 
| Author | CodexAuthor | 
| List of authors | [CodexAuthor] | 
| Tag | String | 
| List of tags | [String] | 
| Section | CodexSection | 
| List of sections | [CodexSection] | 
| Url | String | 
Entry interface
All object types generated from Codex for the models inherit the Entry interface. The entry interface contains a list of fields which are common for all models and their object types respectively.
enum CodexEntryStatus {
  PUBLISHED
  DELETED
  DRAFT
  UNPUBLISHED
  ARCHIVED
  SCHEDULED
  EDITED
}
type CodexSystem {
  title: String,
  slug: String,
  clonedFrom: String
  modelAlias: String,
  modelId: String,
  externalId: String
  versionId: String!
  siteId: String!
  metrics: CodexMetrics
  labels: [CodexLabel]
  status: CodexEntryStatus
  publishedAt: DateTime
  firstPublishedAt: DateTime
  createdAt: DateTime
  updatedAt: DateTime
  unpublishedAt: DateTime
}
interface CodexEntry {
  """
  The id of the entry.
  """
  id: String!
  """
  System information about the entry.
  """
  system: CodexSystem
  """
  Additional dynamic metadata about the entry.
  """
  attrs: Json
}
The common fields are:
id - String value representing the id of the entry. This value is generated by Codex. The ids are auto generated by Codex and are unique globaly, meaning no two entries will have the same Id even if they are of different models.
system Object value representing system fields about the entry, handled by Codex.
attrs Object value representing dynamic metadata for the entry. This field is for API purposes only.
System
Entry system is a common object for all entries that contains common metadata about the entry. The fields of System are:
title - String value representing the title of the entry. This title has the same value as the field configured to represent the title of the entry.
modelAlias - String value representing the alias of the model that the entry belongs to.
modelId - String value representing the id of the model that the entry belongs to.
externalId - String value representing the an external id of the entry. This value is not generated by Codex.
versionId - String value representing the version id of the entry. This value is generated by Codex.
siteId - String value representing the site id of the entry.
metrics - Object representing metrics about to the entry.
labels - Array of objects representing labels assigned to the entry.
status - Enum value representing the status of the entry.
publishedAt - DateTime representing the publish date time of the entry in UTC.
firstPublishedAt DateTime representing the first publish date time of the entry in UTC.
createdAt DateTime representing the create date time of the entry in UTC
updatedAt DateTime representing the latest update date time of the entry in UTC
unpublishedAt DateTime representing the first publish date time of the entry in UTC.
Codex types
The Codex GraphQL API contains a list of pre defined object types for some of the more advanced fields types provided in model builder. Below you can find more information about each object type:
Location
Location object type represents the location field in Codex model builder. It contains information about the address, latitude and longitude of a speicifc location.
type CodexLocation {
  address: String
  latitude: String
  longitude: String
}
Media
Media object type represents the media field in Codex model builder. A media in Codex is an asset which can be an image, file, video, playlist, audio or podcast (powered by GjirafaTech Video Player and Platform)
enum CodexAssetType {
  IMAGE
  FILE
  VIDEO
  VIDEO_PLAYLIST
  AUDIO
  PODCAST
}
type CodexMedia {
  id: String
  type: CodexAssetType!
  media: Media
  url(transformation: CodexAssetTransformation, focalPointRatio: String): String
  focalPoints: [CodexRatioFocalPoint]
}
Each media field can have multiple ratios for focal points. Since these focal point coordinates are on media field leve, Codex GraphQL API provides a new asset URL resolver for media values where you can also specify the ratio focal point that you want to use in that image. If a specific image has the ratio square of '1:1' you can retrieve the image with the URL specific for that ratio based on adjustments set in Codex Admin.
The CodexRatioFocalPoint has the following properties:
type CodexRatioFocalPoint {
  ratio: String!
  focalPoint: CodexFocalPoint
}
Rich Content
Rich Content object type represents the value of RichContent field in Codex model builder. It contains an array of blocks (RichContentBlock), all entries references inside the rich content editor and all the media used in the same field.
type CodexRichContent {
  blocks: [CodexRichContentBlock]
  entries(offset: Int, limit: Int): CodexEntryCollection
  media(offset: Int, limit: Int): CodexAssetCollection
    @deprecated(
      reason: "This type of media field will be deprecated. Use _v2 field instead."
    )
  media_v2(offset: Int, limit: Int): CodexMediaCollection
}
type CodexRichContentBlock {
  type: String
  text: String
  content: Json
  marks: [CodexRichContentBlockMark]
  attrs: Json
  contentHTML: String
}
type CodexRichContentBlockMark {
  type: String
  attrs: Json
}
Rich Content as V2
RichContent object type is a new change in Codex GraphQL API which is expected to replace the old version of Rich Content output type as an array of blocks. For backward compatibility reasons, right now each rich content field will created two fields in the generated model object type
  alias: [CodexContentBlock!]
  alias_v2: CodexRichContent
The first field will be left as it is for a period of time untill all the GraphQL users will migrate to the new field and then will be removed from the generated schema.
We recommend users to start using the new generated field with the "_v2" prefix which contains the automatic resolving of referenced entries and media used inside the Rich Content field.
Content Block
DEPRECATED: This type will be replaced with the new version of RichContentBlock (see above) in the future
Content block object type represents a block inside the Rich Content field in Codex model builder. It contains metadata about the blocks used in the editor. If you want to learn more about Content Block type, please read the Editor documentation.
type CodexContentBlockMark {
  type: String
  attrs: Json
}
type CodexContentBlock {
  type: String
  text: String
  content: Json
  marks: [CodexContentBlockMark!]
  attrs: Json
  contentHTML: String
  entries(offset: Int, limit: Int): CodexEntryCollection
  media(offset: Int, limit: Int): CodexMediaCollection
}
The entries list is automatically filled when a block references entries any model or any media. For example, when the users adds the reference block, they can choose multiple entries to reference (embed) inside the Rich Content field. These references are automatically added to the entries field of ContentBlock. The same applies for the media block.
Metrics
Metrics object type represents content metrics about the entry based on the fields used in the model. It contains numbers about nr. of words, characters, sentences images and the estimated reading time for the entry.
type CodexMetrics {
  wordCount: Int
  characterCount: Int
  sentenceCount: Int
  imageCount: Int
  readingTime: Int
}
Section
Section object type represents the Codex sections that you can assign to entries. It contains the fields presented below.
type CodexSection {
  id: String!
  title: String
  parentId: String
  slug: String
  url: String
  siteId: String
  externalId: String
  path: [CodexSection]
  parent: CodexSection
  description: String
  children(offset: Int, limit: Int): CodexSectionCollection
  media(offset: Int, limit: Int): CodexAssetCollection
  references(offset: Int, limit: Int): CodexEntryCollection
}
Label
Label object type represents the Codex labels that you can assign to entries. It contains the fields presented below.
type CodexLabel {
  id: String!
  name: String
  description: String
  color: String
  siteId: String
  externalId: String
}
Author
Author object type represents the Codex authors that you can assign to entries as a special field. It contains the fields presented below.
type CodexAuthor {
  id: String!
  userId: String
  byline: String
  externalId: String
  firstName: String
  lastName: String
  url: String
  imageId: String
  biography: String
  profession: [String!]
  email: String
  website: String
  facebook: String
  instagram: String
  twitter: String
  linkedin: String
  tiktok: String
  telegram: String
  image: CodexAsset
}
Assets
Codex provides native asset management through the GraphQL API. The asset object types provides a set of fields and methods for delivering content to end users. The GraphQL API offers a predefined schema for retrieving assets from Codex. Below you can find the representation of an asset:
type CodexAsset {
  id: String!
  title: String
  contentType: String
  fileName: String
  path: String
  caption: String
  alt: String
  author: String
  source: String
  size: Long
  tags: [String!]
  externalId: String
  versionId: String
  width: Int
  height: Int
  duration: Float
  type: CodexAssetType!
  focalPoint: CodexFocalPoint
  url(transformation: CodexAssetTransformation, useFocalPoint: Boolean): String
}
Assets in Codex can be of of multiple types: Images, Files, Videos, VideoPlaylists, Audios or Podcasts. Codex provides out of the box features for images uploaded through Assets API, such as on the fly image transformation or automatic compression.
enum CodexAssetType {
  IMAGE
  FILE
  VIDEO
  VIDEO_PLAYLIST
  AUDIO
  PODCAST
}
Focal point is the X/Y represantation of the main content of the image, which can be adjusted by users in Codex Admin. The values are from 0-1 and represent the percentage of the focal point position starting from top-left corner of the image. For example the center focal point has the valuex x: 0.5 and y: 0,5.
type CodexFocalPoint {
  x: Float
  y: Float
}
Asset transformation
Codex provides on the fly image transformation powered by GjirafaTech Captain CDN. By default the original image is returned. If you want to change the size of the image or the quality, you can use the image transformation argument in the URL field for the CodexImage. The transformation argument provides these options:
input CodexAssetTransformation {
  width: Int
  height: Int
  resize: CodexImageTransformationResize
  quality: Int
  gravity: CodexImageTransformationGravity
  format: CodexVideoTransformationFormat
  preset: String
  orientation: CodexVideoTransformationOrientation
}
enum CodexImageTransformationResize {
  FIT
  FILL
  AUTO
}
enum CodexImageTransformationGravity {
  NORTH
  SOUTH
  EAST
  WEST
  NORTH_EAST
  NORTH_WEST
  SOUTH_EAST
  SOUTH_WEST
  CENTER
}
enum CodexVideoTransformationFormat {
  THUMBNAIL
  HTML
  JS
  JSON
}
enum CodexVideoTransformationOrientation {
  HORIZONTAL
  VERTICAL
}
If you specify the useFocalPoint to true, the GraphQL API will include adjust the gravity query parameters based on the focal point specified for that asset in Codex admin.
By default, you will get horizontal video player, unless you specify it differently with the CodexVideoTransformationOrientation.
Video Format
Codex provides out of the box URL building for delivering videos from GjirafaTech VP. The supported formats are:
Thumbnail: renders the URL of the thumbnail of the video as an imageHTML: renders the HTML embed URL for the videoJS: renders the Javascript file URL for embeding the videoJSON: renders the JSON config URL for embeding the video
Lists
Codex provides native listing management through the GraphQL API. Below you can find the representation of an asset:
type CodexList {
  id: String!
  name: String
  description: String
  siteId: String
  externalId: String
  entries(
    offset: Int
    limit: Int
    where: CodexListEntryFilter
    order: CodexListEntryOrder
  ): CodexListEntryCollection
}
type CodexListEntry {
  startAt: DateTime
  endAt: DateTime
  entry: CodexEntry
}
You can filter the list entries based on their startAt and endAt date time fields to retrieve entries that are going to be displayed at a specific time in a web page.
Example
Let's take an example of a model created in Codex for recipes.
{
  "alias": "recipe",
  "fields": [
    {
      "alias": "title",
      "type": "text",
      "valueType": "single"
    },
    {
      "alias": "timeToCook",
      "type": "number",
      "valueType": "single"
    },
    {
      "alias": "tags",
      "type": "text",
      "valueType": "list"
    },
    {
      "alias": "image",
      "type": "media",
      "valueType": "single"
    },
    {
      "alias": "parameters",
      "type": "json",
      "valueType": "single"
    }
  ]
}
The generated GraphQL object type would be
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  image: CodexMedia
  parameters: Json
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
Single entry retrieval
All retrieval of data from Codex GraphQL APi is done through the root query object type. The query object contains the fields for retrieving entries for all models created in Codex.
When you want to retrieve a single entry of a model, you can use the single entry field of the root query. The name of the field is the same as the name of the type generated based on the alias of the model in camelCase. If we take the example of the recipe model from the previous section, to query a single recipe you would need to write the following GraphQL query. You need to pass the id of the entry as an argument for retrieving the respective entry.
type Query {
  recipe(id: String): Recipe
}
An example for retrieving a single recipe with a specific Id would be:
query {
  recipe(
    id: "meTrC06uRK"
  ){
    id
    timeToCook
    tags
    image
    parameters
  }
}
Multi entry retrieval
When you want to retrieve multiple entries from a specific model, you can use the entry collection field of the root query. The name of the field is the alias of the model plus the keyword collection: {alias}Collection. For each collection the following object types are created in the Codex GraphQL API
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  image: CodexMedia
  parameters: Json
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
type RecipeCollection {
  items: [Recipe]
  offset: Int
  limit: Int
  total: Int
}
type RecipeFilter {
  id: CodexIdFilter
  title: CodexStringFilter
  timeToCook: CodexIntFilter
  tags: CodexStringListFilter
  system: CodexSystemFilter
  and: [RecipeFilter]
  or: [RecipeFilter]
}
type RecipeOrder {
 id: CodexOrderDirection
 title: CodexOrderDirection
 timeToCook: CodexOrderDirection
 system: CodexSystemOrder
 thenBy: [RecipeOrder]
}
type RecipeRelations implements EntryRelations {
  entryCollection(
    offset: Int
    limit: Int
  ): EntryCollection
}
type Query {
  recipeCollection(
    offset: Int
    limit: Int
    where: RecipeFilter
    order: RecipeOrder
  ): RecipeCollection
}
Each collection field of query returns a collection object type. The collection contains four fields
items
Array of object where each item of of the object type the collection belongs too. For example for recipe model items returns an array of recipe object types: [recipe].
offset
Integer representing the number of items to be skipped in the result.
limit
Integer representing the number of items to be returned in the result.
total
Integer representing the total number of entries that are part of the collection.
To query multiple recipes you would need to write the following GraphQL query:
query {
  recipeCollection {
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
  }
}
Pagination
By using collection query arguments and collection result fields, you can perform custom pagination for all collections. Codex GraphQL API supports two pagination methods: offset-based pagination and cursor-based pagination for infinite scroll.
Offset-based Pagination
An example query for getting paginated entries from recipe model using offset-based pagination would be:
query {
  recipeCollection(
    offset: 20 
    limit: 20
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
Cursor-based Pagination (Infinite Scroll)
Codex GraphQL API now supports cursor-based pagination to enable infinite scroll functionality. This method uses a continuationToken instead of an offset.
Key points about cursor-based pagination:
- To initiate cursor-based pagination, start with 
offset: 0. - The API will return a 
continuationTokenin the response body when you start from the beginning. - For subsequent requests, use the 
continuationTokeninstead of the offset. - When using 
continuationToken, theoffsetparameter is ignored, butlimitis still respected. - The next 
continuationTokenis only returned if you pass the previouscontinuationTokenin your request. - Cursor-based pagination does not support arbitrary jumps in the result set. You must use each continuationToken sequentially to traverse the results.
 
Here's an example of how to use cursor-based pagination:
Initial request:
query {
  recipeCollection(
    offset: 0
    limit: 20
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    continuationToken
    limit
    total
  }
}
Subsequent requests:
query {
  recipeCollection(
    continuationToken: "WzAuMCwxNzE0MzkyNDc3MDE2XQ=="
    limit: 20
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    continuationToken
    limit
    total
  }
}
The continuationToken is an opaque string that encodes the pagination state. Always use the most recent continuationToken returned by the API for the next request to ensure consistent results.
This approach allows for efficient implementation of infinite scroll functionality in client applications, as it doesn't require keeping track of the current page number or calculating offsets.
It's important to note that you cannot perform arbitrary jumps in the result set when using cursor-based pagination. You must use each continuationToken sequentially to move through the results, which makes it ideal for infinite scroll scenarios but less suitable for applications that require random access to pages.
Filtering
You can filter all entries belonging to a specific model on any of their fields or the common Entry interface fields. For each model, a model filter input is generated which contains filtering options for the fields belonging to that model.
Below you can find the filter input generated for our recipe model from the previous examples:
type RecipeFilter {
  id: CodexIdFilter
  title: CodexStringFilter
  timeToCook: CodexIntFilter
  tags: CodexStringListFilter
  system: CodexSystemFilter
  and: [RecipeFilter]
  or: [RecipeFilter]
}
Each generated filter input contains a a set of inputs for field data type supported by Codex. Below you can find the native filter input from Codex.
Boolean filter
You can filter with equals (eq) or not equals (ne) operator for each boolean field in your models.
input CodexBooleanFilter {
  eq: Boolean
  ne: Boolean
}
DateTime filters
You can filter with equals (eq), not equals (ne), less than (lt), less than or equals (lte), greather than (gt), greater than or equals (gte), exists (exists) operators for each date and time field in your models. You can also perform more complet filtering using and & or logical operators for combining multiple fitlers in the same request.
input CodexDateTimeFilter {
  eq: DateTime
  ne: DateTime
  lt: DateTime
  lte: DateTime
  gt: DateTime
  gte: DateTime
  exists: Boolean
  and: [CodexDateTimeFilter!]
  or: [CodexDateTimeFilter!]
}
Float filters
You can filter with equals (eq), not equals (ne), less than (lt), less than or equals (lte), greather than (gt), greater than or equals (gte), exists (exists) operators for each number field with decimal values in your models. You can also perform more complet filtering using and & or logical operators for combining multiple fitlers in the same request.
input CodexFloatFilter {
  eq: Float
  ne: Float
  lt: Float
  lte: Float
  gt: Float
  gte: Float
  in: [Float!]
  notIn: [Float!]
  exists: Boolean
  and: [CodexFloatFilter!]
  or: [CodexFloatFilter!]
}
You can filter with contains all (all), contains some (some) or contains none (none) operators for each float field with list value type in your models.
input CodexFloatListFilter {
  all: [Float!]
  some: [Float!]
  none: [Float!]
}
Id filters
For id fields (such as entry id field) you can use the CodexIdFilter input. It offers equals (eq), not equals (ne), in (in), not in (notIn), exists (exists) operators for foltering. All Codex object types contain string unique identifiers. You can also perform more complet filtering using and & or logical operators for combining multiple fitlers in the same request.
input CodexIdFilter {
  eq: String
  ne: String
  in: [String!]
  notIn: [String!]
  exists: Boolean
  and: [CodexIdFilter!]
  or: [CodexIdFilter!]
}
Int filters
You can filter with equals (eq), not equals (ne), less than (lt), less than or equals (lte), greather than (gt), greater than or equals (gte), exists (exists) operators for each number field with integer values in your models. You can also perform more complet filtering using and & or logical operators for combining multiple fitlers in the same request.
input CodexIntFilter {
  eq: Int
  ne: Int
  lt: Int
  lte: Int
  gt: Int
  gte: Int
  in: [Int!]
  notIn: [Int!]
  exists: Boolean
  and: [CodexIntFilter!]
  or: [CodexIntFilter!]
}
You can filter with contains all (all), contains some (some) or contains none (none) operators for each integer field with list value type in your models.
input CodexIntListFilter {
  all: [Int!]
  some: [Int!]
  none: [Int!]
}
String filters
You can filter with equals (eq), not equals (ne), in (in), not in (notIn), contains (contains), not contains (notContains), exists (exists), starts with (startsWith), ends with (endsWith), starts with any (startsWithAny) or ends with any (endsWithAny) operators for each text field in your models. All string operators are case insensitive. You can also perform more complet filtering using and & or logical operators for combining multiple fitlers in the same request.
input CodexStringFilter {
  eq: String
  ne: String
  in: [String!]
  notIn: [String!]
  contains: String
  notContains: String
  exists: Boolean
  startsWith: String
  endsWith: String
  startsWithAny: [String!]
  endsWithAny: [String!]
  and: [CodexStringFilter!]
  or: [CodexStringFilter!]
}
You can filter with contains all (all), contains some (some) or contains none (none) operators for each text field with list value type in your models.
```graphql
input CodexStringListFilter {
  all: [String!]
  some: [String!]
  none: [String!]
}
Reference filters
You can filter with exists (exists), entry id (entryId) or model alias (model) for each reference field in your models. The entry id and model operations are built on top of String filter.
input CodexReferenceFieldFilter {
  exists: Boolean
  entryId: CodexStringFilter
  model: CodexStringFilter
}
input CodexReferenceListFieldFilter {
  entryId: CodexStringListFilter
  model: CodexStringListFilter
}
Media filters
You can filter with exists (exists), asset id (id) or asset type (type) for each media field in your models. The asset id is built on top of stirng filter.
input CodexMediaFieldFilter {
  exists: Boolean
  id: CodexStringFilter
  type: CodexAssetTypeFilter
}
input CodexMediaListFieldFilter {
  id: CodexStringListFilter
  type: CodexAssetTypeListFilter
}
input CodexAssetTypeFilter {
  in: [CodexAssetType!]
  notIn: [CodexAssetType!]
  exists: Boolean
}
input CodexAssetTypeListFilter {
  all: [CodexAssetType!]
  none: [CodexAssetType!]
  some: [CodexAssetType!]
}
Section field filters
You can filter with equals (eq), not equals (ne), in (in), not in (notIn) and inlcude children (includeChildren) operations for each section field in your models. All these operations are performed with section ids.
If you set includeChildren to true, the filter will automatically include all child sections nested under the specified parent sections in both CodexSectionFieldFilter and CodexSectionListFieldFilter.
input CodexSectionFieldFilter {
  eq: String
  ne: String
  in: [String!]
  notIn: [String!]
  includeChildren: Boolean
}
input CodexSectionListFieldFilter {
  all: [String!]
  some: [String!]
  none: [String!]
  includeChildren: Boolean
}
Author field filters
You can filter with equals (eq), not equals (ne), in (in) and not in (notIn) operations for each author field in your models. All these operations are performed with author ids
input CodexAuthorFieldFilter {
  eq: String
  ne: String
  in: [String!]
  notIn: [String!]
}
input CodexAuthorListFieldFilter {
  all: [String!]
  some: [String!]
  none: [String!]
}
Status filter
input CodexEntryStatusFilter {
  in: [CodexEntryStatus!]
  notIn: [CodexEntryStatus!]
  exists: Boolean
}
System filters
If you need to perform filtering on system fields you can use the system filter input objects. It offers filtering on the below fields.
input CodexSystemFilter {
  title: CodexStringFilter
  slug: CodexStringFilter
  siteId: CodexIdFilter
  externalId: CodexStringFilter
  createdAt: CodexDateTimeFilter
  updatedAt: CodexDateTimeFilter
  publishedAt: CodexDateTimeFilter
  firstPublishedAt: CodexDateTimeFilter
  unpublishedAt: CodexDateTimeFilter
  status: CodexEntryStatusFilter
  labels: CodexStringListFilter
  and: [CodexSystemFilter!]
  or: [CodexSystemFilter!]
}
For example if you want to retrieve all recipes that have timeToCook higher than 5 and contain the tag 'healthy' than you would write the followig query:
query {
  recipeCollection (
      where: { 
        timeToCook: { gt: 5 }
        tags: { some: { eq: "healthy" } }
      }
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
Combining multiple fields in the where filter input is performed using the "and" logic operator. The example above is equivalent to the query below:
query {
  recipeCollection (
      where: {
        and: [
          { timeToCook: { gt: 5 } }
          { tags: { some: { eq: "healthy" } } }
        ]
      }
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
You can also perform the "or" logical operator if you want to retrieve entries that fit any of the specified criterias. For example if you want to retrieve all recipes that have time to cook equal to 5 OR contain the tag healthy, execture the following query:
query {
  recipeCollection (
    where: {
      or: [
        { timeToCook: { eq: 5 } }
        { tags: { some: { eq: "healthy" } } }
      ]
    }
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
Rich Content filters
You can filter entries based on the content of Rich Content fields. This allows you to find entries that contain specific elements, have a certain character count, or are linked to other entries or media.
input CodexRichContentFieldFilter {
  exists: Boolean
  blocks: CodexRichContentBlockFilter
  charCount: CodexIntFilter
  and: [CodexRichContentFieldFilter!]
  or: [CodexRichContentFieldFilter!]
}
input CodexRichContentBlockFilter {
  type: CodexStringFilter
  value: CodexStringFilter
  attrs: CodexRichContentBlockAttrsFilter
  and: [CodexRichContentBlockFilter!]
  or: [CodexRichContentBlockFilter!]
}
input CodexRichContentBlockAttrsFilter {
  properties: [CodexRichContentBlockAttrsPropertiesFilter]
}
input CodexRichContentBlockAttrsPropertiesFilter {
  key: String!
  value: CodexStringFilter
}
Examples:
Entries with No Rich Content:
query {
  articleCollection (where: {
   text: {
    exists: false
   }
  }) {
    items {
      id
      system {
        title
      }
    }
  }
}
Entries with Less than X Characters:
query {
  articleCollection (where: {
   text: {
    charCount: {
      lt: 2930
    }
   }
  }) {
    items {
      id
      system {
        title
      }
    }
  }
}
Entries Not Linked to Any Entry:
query {
  articleCollection (where: {
   text: {
    blocks: {
      type: {
        notIn: ["codex_reference"]
      }
    }
   }
  }) {
    items {
      id
      system {
        title
      }
    }
  }
}
Entries Not Linked to Any Media:
query {
  articleCollection (where: {
   text: {
    blocks: {
      type: {
        notIn: ["codex_media"]
      }
    }
   }
  }) {
    items {
      id
      system {
        title
      }
    }
  }
}
Usage of a Particular Element:
query {
  articleCollection (where: {
   text: {
    blocks: {
      type: {
        in: ["heading"]
      }
      attrs: {
        properties: {
          key: "level"
          value: {
            eq: "1"
          }
        }
      }
    }
   }
  }) {
    items {
      id
      system {
        title
      }
    }
  }
}
Ordering
By default all entries belonging to a sepcific collection are ordered based on their published date & time in descending mode.
If you want to order entries based on another field, you can use the order argument of the collection fields. For each collection a order input is generated which contains sorting options for all orderable fields belonging to that model.
enum CodexOrderDirection {
  ASC
  DESC
}
type RecipeOrder {
 id: CodexOrderDirection
 title: CodexOrderDirection
 timeToCook: CodexOrderDirection
 system: CodexSystemOrder
 thenBy: [RecipeOrder]
}
For example if you want to sort recipes based on the title asceding, than you would write the following query:
query {
  recipeCollection (
    order: { 
      title: ASC 
    }
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
You can also apply ordering on multiple fields by using the thenBy field of the order input. Ordering on multiple fields can be used only if you have multiple entries with the same value for a specific field.
query {
  recipeCollection (
    order: { 
      timeToCook: ASC
      thenBy: 
      [
        {
          title: DESC
        }
      ] 
    }
  ){
    items {
      id
      timeToCook
      tags
      image
      parameters
    }
    offset
    limit
    total
  }
}
References
Codex model builder offers the possibility to reference entries from different models into the reference field. Depending on the reference field configuration the Codex GraphQL API generates the necessary schema to enable developers to retrieve the referenced content in an intuitive manner. Let's take the previous example of our recipe model. We are going to create a new model restaurant which represents content for specific restaurants in a city. Let's define the restaurant model as follows:
type Restaurant implements CodexEntry {
  id: String!
  name: String
  address: CodexLocation
  image: CodexMedia
  startHour: Int
  endHour: Int
  hasDelivery: Boolean
  
  system: CodexSystem
  attrs: Json
  relations: RestaurantRelations
}
Single strict reference
We are also going to add a new field to our existing recipe model with the alias restaurant which references to the Restaurant model as a single value. Now the updated schema of our recipe model is:
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  restaurant: Restaurant
  image: CodexMedia
  parameters: Json
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
You can retrieve all fields of the referenced restaurant same as you will retrieve other fields of recipe.
query {
  recipe(
    id: "RECIPE_ID"
  ){
    id
    timeToCook
    tags
    image
    parameters
    restaurant: {
      id
      name
      address {
        address
        latitude
        longitude
      }
      startHour
      endHour
      hasdelivery
    }
  }
}
Single dynamic reference
By default reference fields can include entries from all existing models. If you don't restrict allowed models in the created reference field (or allow more than one model to be referenced) then the Codex GraphQL API will generate the field with the generic Entry interface for the field.
Let's add a new field in our recipe model with the alias related which can by any entry from any model as a related content which will be displayed to end-users. The updated schema for our recipe model is:
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  restaurant: Reference
  image: Media
  parameters: Json
  restaurant: Restaurant
  related: Entry
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
To retrieve the fields of the referenced entry you can use Inline Fragments from GraphQL. Let's say our related entry can be another recipe or a restaurant, to retrieve fields from each one of them we can use the following query:
query {
  recipe(
    id: "RECIPE_ID"
  ){
    id
    timeToCook
    tags
    image
    parameters
    related {
      id
      ... on Recipe {
        title
        timeToCook
      }
      ... on Restaurant {
        name
        hasDelivery
      }
    }
  }
}
Multi strict reference
We are also going to add a new field to our existing recipe model with the alias restaurants which references to the Restaurant model as a list value. Now the updated schema of our recipe model is:
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  restaurant: Reference
  image: Media
  parameters: Json
  restaurant(
    offset: Int
    limit: Int
  ): RestaurantCollection
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
You can retrieve all fields of the referenced restaurants same as you will retrieve other fields of recipe. You can also limit the number of referenced restaurants you want to retrieve, or see the total number of restaurants referenced.
query {
  recipe(
    id: "RECIPE_ID"
  ){
    id
    timeToCook
    tags
    image
    parameters
    restaurants (limit: 3) {
      items: {
        id
        name
        address {
          address
          latitude
          longitude
        }
        startHour
        endHour
        hasdelivery
      }
      total
    }
  }
}
Multi dynamic reference
By default reference fields can include entries from all existing models. If you don't restrict allowed models in the created reference field (or allow more than one model to be referenced) then the Codex GraphQL API will generate the field with the generic Entry interface for the field.
Let's add a new field in our recipe model with the alias related which can by any entry from any model as a related content which will be displayed to end-users. The updated schema for our recipe model is:
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  restaurant: Reference
  image: Media
  parameters: Json
  restaurant: Restaurant
  related(
    offset: Int
    limit: Int
  ): EntryCollection
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
To retrieve the fields of the referenced entries you can use Inline Fragments from GraphQL. Let's say our related entry can be another recipe or a restaurant, to retrieve fields from each one of them we can use the following query:
query {
  recipe(
    id: "RECIPE_ID"
  ){
    id
    timeToCook
    tags
    image
    parameters
    related (limit: 3) {
      items {
        id
        ... on Recipe {
          title
          timeToCook
        }
        ... on Restaurant {
          name
          hasDelivery
        }
      }
      total
    }
  }
}
Relations
By using references you can create advanced relations between different models in Codex. Apart from automatic field generation based on reference field configurations, Codex GraphQL also generates reverse relation retrieval for querying all entities that have references an entry. You can query all of these entries by using the relations field, which is a common field for each entry.
In our recipe model we have a single reference to the restaurant model. The generated relations field for restaurants are:
type RecipeRelations implements EntryRelations {
  recipeCollection(
    offset: Int
    limit: Int
    where: RecipeFilter
    order: RecipeOrder
  ): RecipeCollection
  entryCollection(
    offset: Int
    limit: Int
    where: CodexEntryFilter
    order: CodexEntryOrder
  ): CodexEntryCollection
}
Since our reference field in recipe model allows only restaurant models, then our restaurant model contains a field for all recipes that are referencing a restaurant entry. By default all relation object contain the entryCollection field which returns all entries referencing the restaurant regardless of the model or field configuration.
If we would like to retrieve 10 recipes that you can find in a particular restaurant, you can perform the following query:
query {
  restaurant(
    id: "RESTAURANT_ID"
  ) {
      id
      name
      address
      image
      startHour
      endHour
      hasDelivery
      
      relations {
        recipeCollection(limit: 10) {
          items {
            id
            title
            timeToCook
            tags
          }
        }
      }
  }
}
You can perform additional filtering and ordering on top of relations results by using the where and order arguments. These arguments are generated based on collection type.
query {
  restaurant(
    id: "RESTAURANT_ID"
  ) {
      id
      name
      address
      image
      startHour
      endHour
      hasDelivery
      
      relations {
        recipeCollection(
          limit: 10
          where: {
            and: [
              { timeToCook: { gt: 5 } }
              { tags: { some: { eq: "healthy" } } }
            ]
          }
        ) {
          items {
            id
            title
            timeToCook
            tags
          }
        }
      }
  }
}
Next entries
In the relations type for each specific model you will be able to find a field named next{Alias}EntryCollection which returns a collection of entries for that model, relative to that specific entry based on filtering and sorting specified in arguments. This allows you to retrieve "next" or "previous" entries. For example, you can retrieve the recipes published after a specific recipe (next) by using the asceding order in the publishedAt system field, or retrieve the recipes published before a specific recipe (previous) by using the descending order in the publishedAt system field. The query would look like this:
query {
  recipe(
    id: "RECIPE_ID"
  ){
    id
    timeToCook
    tags
    image
    parameters
    relations {
      nextRecipes: nextRecipeCollection (
        limit: 5
        order: {
          system: {
            publishedAt: ASC
          }
        }
      ) {
        items {
          id
          timeToCook
          //other fields
        }
      }
      previousRecipes: nextRecipeCollection (
        limit: 5
        order: {
          system: {
            publishedAt: DESC
          }
        }
      ) {
        items {
          id
          timeToCook
          //other fields
        }
      }
    }
  }
}
You can sort by model specific number or date time fields. This feature works only with number and date time fields. If you use any other field type in sorting it will return a null result.
You can also filter out entries using the model specific filter input, allowing you to filter by any filterable fields of the model same way as you can do in the main model collection queries.
Please keep in mind performance when using this feature, since it will introduce multiple round trips to the database to retrieve the relative next entries. It is recommended to be used on single entry queries. Using it in large lists of entries might cause latencies on responses.
Generic queries
In addition to collections for entries of a specific model, Codex GraphQL allows you to query for the generic Entry interface in the root query object. Same as with other models, it offers two methods entry for single entry retrievak and entryCollection for multi entry retrieval.
type Query {
  entry(id: String): CodexEntry
  entryCollection(
    offset: Int
    limit: Int
    where: CodexEntryFilter
    order: CodexEntryOrder
  ): CodexEntryCollection
}
Let's say we have two models in our schema so far, recipe and restaurant.
type Restaurant implements CodexEntry {
  id: String!
  name: String
  address: CodexLocation
  image: CodexMedia
  startHour: Int
  endHour: Int
  hasDelivery: Boolean
  
  system: CodexSystem
  attrs: Json
  relations: RestaurantRelations
}
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  tags: [String]
  restaurant: Reference
  image: Media
  parameters: Json
  restaurant: Restaurant
  
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
If we have the entry ID but don't know the model of the id, then we can use the generic entry retrieval method and then use inline fragments to select specific fields from each model respectively. By default you can use the common fields of all entries without needing to use the inline fragments.
query {
  entry(
    id: "meTrC06uRK"
  ){
    id
    system {
      title
      publishedAt
    }
    ... on Recipe {
      title
      timeToCook
    }
    ... on Restaurant {
      name
      hasDelivery
    }
  }
}
We can also retrieve multiple entries from all the models in the generic entry collection query method. Same as in the previous example, by using the inline fragmenting we can select specific fields from different models. For example if we want to retrieve top 5 most recently published entries from all the models, we can perform the following query:
query {
  entryCollection(
    limit: 5
  ){
    items {
      id
      system {
        title
        publishedAt
      }
      ... on Recipe {
        title
        timeToCook
      }
      ... on Restaurant {
        name
        hasDelivery
      }
    }
    limit
    total
  }
}
Generic filtering
Codex GraphQL API provides advanced filtering in the generic entry collection method. It generates the generic entry filter based on all existing models in your Codex organization. For each model created in Codex one filter input is generated for all the filterable fields of the model and also that filter input is added to the generic entry filtering input as a sub-field. It allows developers to perform complex filtering on multiple models in one request. This kind of filtering is useful when you want to filter all entries in common fields (such as id or system fields) or perform more advanced filtering in common fields defined in the models. Let's take an example when we have two models that have some common fields and see the generated schema:
type Recipe implements CodexEntry {
  id: String!
  title: String
  timeToCook: Int
  premium: Boolean
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
input RecipeFilter {
  id: CodexIdFilter
  title: CodexStringFilter
  timeToCook: CodexIntFilter
  premium: CodexBooleanFilter
  
  system: CodexSystemFilter
} 
type Article implements CodexEntry {
  id: String!
  title: String
  timeToRead: Int
  premium: Boolean
  system: CodexSystem
  attrs: Json
  relations: RecipeRelations
} 
input RecipeFilter {
  id: CodexIdFilter
  title: CodexStringFilter
  timeToRead: CodexIntFilter
  premium: CodexBooleanFilter
  
  system: CodexSystemFilter
} 
"""
The generic entry filter
"""
input CodexEntryFilter {
  id: CodexIdFilter
  restaurant: RestaurantFilter
  article: ArticleFilter
  system: CodexSystemFilter
  and: [CodexEntryFilter]
  or: [CodexEntryFilter]
}
Let's say you want to have all entries that contain the keyword Codex in the title. You can perform this kind of filtering without know the exact fields of the entries by using the generic entry collection method:
query {
  entryCollection(
    where: {
      system: {
        title: {
          contains: "codex"
        }
      }
    }
    limit: 10
  ) {
    items {
      id
      system {
        title
        publishedAt
      }
      ... on Recipe {
        title
        timeToCook
      }
      ... on Article {
        title
        timeToRead
      }
    }
  }
}
If you need more advanced filtering based on model fields, than you can use the generated filters from each model respectively. Let's say we want to display all premium recipes or articles in our homepage.
query {
  entryCollection(
    where: {
      or: [
        {
          recipe: {
            premium: {
              eq: true
            }
          }
        },
        {
          article: {
            premium: {
              eq: true
            }
          }
        }
      ]
    }
    limit: 10
  ) {
    items {
      id
      system {
        title
        publishedAt
      }
      ... on Recipe {
        title
        timeToCook
        premium
      }
      ... on Article {
        title
        timeToRead
        premium
      }
    }
  }
}
If you use any of the model filter inputs as a sub filter in the generic entry collection query, then Codex GraphQL API first checks if the entry belongs to that specific model before applying the filtering on the sub fields. That's why this kind of filtering are most useful by using the OR logical operator when you have to combine field filters from multiple models. Performing the above example with the AND logical operator will return no result, because one entry cannot belong to Recipe and Article filter at the same time.