Schema Generation

The GraphQL schema definition is generated from the content model at request time so it is always current.

Types

The GraphQL schema is generated from the content types defined in the specified environment of the space (or master if no environment has been specified). For each content type in your environment the GraphQL Content API creates a corresponding GraphQL type.

Names

Type name is the PascalCase version of the content type ID, stripped of non-alphanumeric characters. For example:

Original valueTransformed value
"my-2content-type""My2ContentType"

If two or more content type IDs would be transformed to the same type name, a COLLIDING_TYPE_NAMES error is returned. For more information about errors see the GraphQL Errors section.

If the generated name starts with a number or collides with a reserved type name, it gets prefixed with ContentType. For example:

Original content type IDTransformed type name
LocationContentTypeLocation
5TbTQ4S6xqSeAU6WGQmQ2eContentType5TbTQ4S6xqSeAU6WGQmQ2e

To keep the original name in query responses, consider using aliases:

1query {
2 location: contentTypeLocation(id: "some-id") {
3 # ... location fields
4 }
5}

Reserved type names

Query, String, Int, Float, Boolean, Location, Circle, Rectangle, DateTime, RichText, Asset, AssetCollection, AssetLinkingCollections, AssetFilter, AssetOrder, Entry, EntryCollection, EntryOrder, Sys, SysFilter, ContentfulMetadata, ContentfulTag, ContentfulMetadataFilter, ContentfulMetadataTagsFilter, Dimension, HexColor, Quality, ImageResizeFocus, ImageResizeStrategy, ImageFormat, ImageTransformOptions, ResourceSys, ResourceLink, ResourceLinkCollection, and Never.

Example

For example, a single content type is defined as follows:

1{
2 sys: {
3 id: "friendly-user"
4 },
5 fields: [
6 ...
7 ]
8}

Using this content type definition, the API automatically generates the corresponding schema definition. Notice how the GraphQL type is named after the content type ID. The produced Query object exposes two fields that you can use to query content of that type: one for fetching individual content (friendlyUser in the example) and another to do queries over all the content of the type (friendlyUserCollection). Collections are explained in more detail in the Collection fields section.

1type Sys {
2 id: String
3 spaceId: String
4 environmentId: String
5}
6
7type ContentfulMetadata {
8 tags: [ContentfulTag]!
9}
10
11type ContentfulTag {
12 id: String!
13 name: String!
14}
15
16type FriendlyUser {
17 sys: Sys
18 contentfulMetadata: ContentfulMetadata
19 # ... fields
20}
21
22input FriendlyUserFilter {
23 # ... field based filters
24}
25
26type FriendlyUserCollection {
27 skip: Int!
28 limit: Int!
29 total: Int!
30 items: [FriendlyUser]!
31}
32
33type Query {
34 friendlyUser(id: String!): FriendlyUser
35 friendlyUserCollection(
36 skip: Int
37 limit: Int,
38 where: FriendlyUserFilter
39 ): FriendlyUserCollection
40}

Fields

GraphQL type fields are generated from the corresponding content type fields. Each type has three additional fields: sys, contentfulMetadata and linkedFrom.

Names

Field name is the lower camelCase version of the field ID, stripped of non-alphanumeric characters. For example:

Original valueTransformed value
"my-field8-name""myField8Name"

If two or more field IDs on the same content type would be transformed to the same field name, a COLLIDING_FIELD_NAMES error is returned.

If the generated name collides with a reserved field name, a RESERVED_FIELD_NAME error is returned. Reserved field names are sys, contentfulMetadata and linkedFrom.

For more information about errors see the errors section.

Types

Field type is determined based on the following mappings:

Contentful typeGraphQL Type
SymbolString
TextString
NumberFloat
IntegerInt
DateDateTime
BooleanBoolean
ObjectJSON
Array of Symbol[String]

Fields of type Link and Array of Link are handled as explained in Modeling relationships.

Fields of type Location are handled as explained in Locations.

Fields of type RichText are handled as explained in Rich text.

Fields of type Never are handled as explained in Never.

Arguments

Fields on entries provide an optional locale argument, allowing the locale to be overridden for a single field. The current scope’s locale is used if a locale is not specified. If the requested locale does not exist, an UNKNOWN_LOCALE error is returned for this path.

Fields also support an optional useFallbackLocale argument. When set to false, the field returns null if no value exists in the requested locale, instead of the fallback locale. For more information, see the Disabling locale fallback section.

Example

Continuing with the previous example, extend the Friendly User content type with three fields: age, name and addresses:

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 {
9 id: "age",
10 type: "Integer"
11 },
12 {
13 id: "name",
14 type: "Symbol"
15 },
16 {
17 id: "addresses",
18 type: "Array",
19 items: {
20 type: "Symbol"
21 }
22 }
23 ]
24}

The resulting GraphQL schema is:

1type FriendlyUser {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: FriendlyUserLinkingCollections
5 age(locale: String, useFallbackLocale: Boolean): Int
6 name(locale: String, useFallbackLocale: Boolean): String
7 addresses(locale: String, useFallbackLocale: Boolean): [String]
8}

Schema generation failure

Schema generation fails when:

  • Two or more content type IDs would be transformed to the same type name.
  • Two or more field IDs on the same content type would be transformed to the same field name.
  • Any field ID would be transformed to sys, contentfulMetadata or linkedFrom.

You cannot change the content type ID without regenerating the content type, so be aware of these restrictions while creating your content models.

Colliding type names

In order to successfully generate the schema, the GraphQL type generated from a content type ID has to be unique.

Type uniqueness check will fail if a content type ID is transformed into a GraphQL type that already exists.

This can happen in two cases:

  • when two or more content type IDs are transformed into the same GraphQL type name.
  • when a content type ID is transformed into a GraphQL type name that collides with an existing GraphQL helper type.

While the first case is straightforward, let’s take a closer look at the second case.

GraphQL generates the following helper types for each content type:

  • Collection
  • LinkingCollections
  • Filter
  • Order

For a content type Plants with id plants, GraphQL will generate type Plants and the following helper types:

  • PlantsCollection
  • PlantsLinkingCollections
  • PlantsFilter
  • PlantsOrder

If we happen to have a second content type called PlantsOrder with id plantsOrder, schema creation will fail. The GraphQL type PlantsOrder will collide with the PlantsOrder helper type generated for Plants content type.

To avoid type name collisions for a new content type, make sure that the GraphQL types and helper types generated for it won’t collide with any of the existing GraphQL types.

Sys field

Each GraphQL type derived from a content type and the Asset type will also have a system-defined sys field. This field exposes meta-information about the content.

1type Sys {
2 id: String!
3 spaceId: String!
4 environmentId: String!
5 publishedAt: DateTime
6 firstPublishedAt: DateTime
7 publishedVersion: Int
8}
9type MyContentType {
10 ... # content fields
11 sys: Sys!
12}
13type Asset {
14 ... # content fields
15 sys: Sys!
16}
FieldTypeDescription
idStringUnique identifier of the resource.
spaceIdStringUnique identifier of the resource’s space.
environmentIdStringUnique identifier of the resource’s environment.
publishedAtDateTimeDateTime string of the resource’s last published time.
firstPublishedAtDateTimeDateTime string of the resource’s first published time.
publishedVersionIntThe version of the draft resource when it was published.

ContentfulMetadata field

Each GraphQL type derived from a content type and the Asset type will also have a contentfulMetadata field. This field exposes information on the public tags that exist on the content.

To learn more about tags, see the tags section of the Content Management API reference.

1type ContentfulMetadata {
2 tags: [ContentfulTag]!
3}
4type ContentfulTag {
5 id: String!
6 name: String!
7}
8type MyContentType {
9 ... # content fields
10 contentfulMetadata: ContentfulMetadata
11}
12type Asset {
13 ... # content fields
14 contentfulMetadata: ContentfulMetadata
15}
FieldTypeDescription
idStringUnique identifier of the tag.
nameStringThe resolved tag name.

Modeling relationships

One of the benefits of GraphQL is that it simplifies traversing the graph of relationships between different types.

In Contentful, relationships are modeled using links. An entry field can be a link to another entry or a list of links to other entries. The content type of the entries that can be linked from a given field can be restricted using the linkContentType validation. Although optional, it is recommended to define linkContentType for your link fields for a better experience.

A field may also link to an asset by specifying linkType: "Asset". In this case there is no linkContentType validation — the GraphQL type of the field is always Asset.

One-to-one single-type relationships

One-to-one single-type relationships are modeled by content type fields that link to at most one entry of a fixed type. For example, each FriendlyUser entry has a manager field that links to one entry of content type FriendlyUser.

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 ...,
9 {
10 id: "manager",
11 type: "Link",
12 linkType: "Entry",
13 validations: [{ linkContentType: ["friendlyUser"] }]
14 }
15 ]
16}

This results in the following schema:

1type FriendlyUser {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 manager: FriendlyUser
5 # ... other fields
6}

One-to-one multi-type relationships

It is possible for an entry field to link to entries of different content types. For example, each FriendlyUser may have a pet that is either a Dog or a Cat. This is modeled with the following content types:

1{
2 name: "Cat",
3 sys: {
4 id: "cat",
5 ...
6 }
7}
8
9{
10 name: "Dog",
11 sys: {
12 id: "dog",
13 ...
14 }
15}
16
17{
18 name: "Friendly User"
19 sys: {
20 id: "friendly-user",
21 ...
22 },
23 fields: [
24 ...,
25 {
26 id: "pet",
27 type: "Link",
28 linkType: "Entry",
29 validations: [{ linkContentType: ["cat", "dog"] }]
30 }
31 ]
32}

This results in the following schema:

1union FriendlyUserPet = Cat | Dog
2
3type FriendlyUser {
4 sys: Sys
5 contentfulMetadata: ContentfulMetadata
6 pet: FriendlyUserPet
7}

One-to-many single-type relationships

One-to-many relationships are modeled with arrays of links. For example, a FriendlyUser might have multiple friends.

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 ...,
9 {
10 id: "friends",
11 type: "Array",
12 items: {
13 type: "Link",
14 linkType: "Entry",
15 validations: [{ linkContentType: ["friendlyUser"] }]
16 }
17 }
18 ]
19}

In the resulting GraphQL schema the friends field is renamed to friendsCollection and is of a collection type, the same type that is used for top-level collections for the FriendlyUser content type. The field has the same skip and limit arguments as the top-level collection field and the same limits apply.

1type FriendlyUser {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 friendsCollection(skip: Int, limit: Int): FriendlyUserCollection
5 # ...
6}
7
8type FriendlyUserCollection {
9 skip: Int!
10 limit: Int!
11 total: Int!
12 items: [FriendlyUser]!
13}

One-to-many multi-type relationships

As with one-to-one relationships, a collection field can link to entries of different content types. For example, a FriendlyUser can have multiple pets, each of which is either a Dog or a Cat.

1{
2 name: "Cat",
3 sys: {
4 id: "cat",
5 ...
6 }
7}
8
9{
10 name: "Dog",
11 sys: {
12 id: "dog",
13 ...
14 }
15}
16
17{
18 name: "Friendly User"
19 sys: {
20 id: "friendly-user",
21 ...
22 },
23 fields: [
24 ...,
25 {
26 id: "pets",
27 type: "Array",
28 items: {
29 type: "Link",
30 linkType: "Entry",
31 validations: [{ linkContentType: ["dog", "cat"] }]
32 }
33 }
34 ]
35}

This results in the following schema:

1union FriendlyUserPetsItem = Cat | Dog
2
3type FriendlyUserPetsCollection {
4 skip: Int!
5 limit: Int!
6 total: Int!
7 items: [FriendlyUserPetsItem]!
8}
9
10type FriendlyUser {
11 sys: Sys
12 contentfulMetadata: ContentfulMetadata
13 petsCollection(skip: Int, limit: Int): FriendlyUserPetsCollection
14 # ...
15}

You can retrieve the collection of entries linking to a specific entry (or asset) by using the linkedFrom field in your query.

For example, consider a Friendly User content type defined as follows:

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 ...,
9 {
10 id: "photo",
11 type: "Link",
12 linkType: "Asset"
13 },
14 {
15 id: "pets",
16 type: "Array",
17 items: {
18 type: "Link",
19 linkType: "Entry",
20 validations: [{ linkContentType: ["dog", "cat"] }]
21 }
22 }
23 ]
24}

Friendly User links to the Asset type through the photo field, which is a link to an asset. It also links to the Dog and Cat types through the pets field, which is a list of links to entries, with content types restricted to Dog and Cat.

Based on those relationships, a friendlyUserCollection field is generated inside the linkedFrom fields of the Asset, Dog, and Cat types:

1type Cat {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: {
5 friendlyUserCollection: FriendlyUserCollection
6 entryCollection: EntryCollection
7 }
8 name: String
9 # ...
10}
11
12type Dog {
13 sys: Sys
14 contentfulMetadata: ContentfulMetadata
15 linkedFrom: {
16 friendlyUserCollection: FriendlyUserCollection
17 entryCollection: EntryCollection
18 }
19 name: String
20 # ...
21}
22
23type Asset {
24 sys: Sys
25 contentfulMetadata: ContentfulMetadata
26 linkedFrom: {
27 friendlyUserCollection: FriendlyUserCollection
28 entryCollection: EntryCollection
29 }
30 title: String
31 # ...
32}

To retrieve names of all the cats and their owners:

1query {
2 catCollection {
3 items {
4 name
5 linkedFrom {
6 friendlyUserCollection {
7 items {
8 firstName
9 }
10 }
11 }
12 }
13 }
14}

Notice that each linkedFrom field also has a generic entryCollection field. This field is always present and allows you to query for linking entries of all types. If you don’t have linkContentType validations defined for your fields, entryCollection is the only way to query for linking entries:

1query {
2 catCollection {
3 items {
4 name
5 linkedFrom {
6 entryCollection {
7 items {
8 ... on FriendlyUser {
9 firstName
10 }
11 }
12 }
13 }
14 }
15 }
16}

By default the current locale is used to search entry fields for links to the specific entry or asset. To override this behavior the linkedFrom field accepts an optional allowedLocales argument.

Note that this does not change the locale of the entries in the collection.

Due to the way GraphQL API treats arrays you can omit brackets if you only need a single locale.

1query {
2 catCollection {
3 items {
4 name
5 germanLinks: linkedFrom(allowedLocales: "de-DE") {
6 friendlyUserCollection {
7 items {
8 firstName
9 }
10 }
11 }
12 multilanguageLinks: linkedFrom(allowedLocales: ["de-DE", "en-US"]) {
13 friendlyUserCollection {
14 items {
15 firstName
16 }
17 }
18 }
19 }
20 }
21}

Inline fragments

Since every GraphQL API type implements the Entry interface, the content type of the entries can be linked without validation:

1interface Entry {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4}

Link to single entry (no validation)

The relationships are modeled by content type fields that link to at most one entry. For example, each FriendlyUser entry has a manager field that links to one entry of content type FriendlyUser.

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 ...,
9 {
10 id: "manager",
11 type: "Link",
12 linkType: "Entry",
13 }
14 ]
15}

This results in the following schema:

1type FriendlyUser implements Entry {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: FriendlyUserLinkingCollections
5 manager: Entry
6 # ... other fields
7}

To query the manager field to be of type FriendlyUser:

1query {
2 friendlyUser(id: "hans") {
3 manager {
4 ... on FriendlyUser {
5 # some user fields
6 }
7 }
8 }
9}

The relationships are modeled by content type fields that link to a collection of entities. For example, each FriendlyUser entry has a managers field that links to a collection of entries.

1{
2 name: "Friendly User"
3 sys: {
4 id: "friendly-user",
5 ...
6 },
7 fields: [
8 ...,
9 {
10 id: "managers",
11 type: "Array",
12 items: {
13 type: 'Link',
14 linkType: 'Entry'
15 }
16 }
17 ]
18}

This results in the following schema:

1type FriendlyUser implements Entry {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: FriendlyUserLinkingCollections
5 managersCollection: FriendlyUserManagersCollection
6 # ... other fields
7}

To only get the entries of type FriendlyUser:

1query {
2 friendlyUser(id: "hans") {
3 managersCollection {
4 items {
5 ... on FriendlyUser {
6 # some user fields
7 }
8 }
9 }
10 }
11}

Entries

In addition to collections for entries of a specific content type, querying for the generic Entry interface is supported on the root Query type.

1type Query {
2 entryCollection(skip: Int, limit: Int): EntryCollection
3}

The query above returns the following GraphQL types:

1type Entry {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4}
5
6type EntryCollection {
7 skip: Int!
8 limit: Int!
9 total: Int!
10 items: [Entry]!
11}

Example — retrieve entries across content types using the root collection type:

1type Person {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 surname: String
5}
1type Cat {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 name: String
5}
1query {
2 entryCollection {
3 items {
4 sys {
5 id
6 }
7 contentfulMetadata {
8 tags {
9 id
10 }
11 }
12
13 ... on Cat {
14 name
15 }
16
17 ... on Person {
18 surname
19 }
20 }
21 }
22}

Assets

Assets in Contentful have a predefined schema function. This means that the type for any asset in the GraphQL schema follows the definition below:

1type Asset {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: AssetLinkingCollections
5 title: String
6 description: String
7 contentType: String
8 fileName: String
9 url: String
10 size: Int
11 width: Int?
12 height: Int?
13}

Assets are also supported as root queries. At present, there are two root queries for it: single asset and collection of assets.

1type Query {
2 # ...
3 asset(id: String!): Asset
4 assetCollection(skip: Int, limit: Int): AssetCollection
5}

The queries above return the following GraphQL types:

1type Asset {
2 sys: Sys
3 contentfulMetadata: ContentfulMetadata
4 linkedFrom: AssetLinkingCollections
5 title: String
6 description: String
7 contentType: String
8 fileName: String
9 url: String
10 size: Int
11 width: Int?
12 height: Int?
13}
14
15type AssetCollection {
16 skip: Int!
17 limit: Int!
18 total: Int!
19 items: [Asset]!
20}

Unlike the CDA, the GraphQL Content API always serves asset URLs with a protocol, defaulting to HTTPS.

Image transformations

The GraphQL Content API exposes a set of image transformation options, such as cropping or resizing. To request image transformations for an asset, pass a transform argument to its url field:

1{
2 asset(id: "KTsF62Q4gg60q6WCsWJw8") {
3 title
4 url(transform: {
5 width: 500,
6 height: 300,
7 resizeStrategy: FILL,
8 resizeFocus: BOTTOM,
9 backgroundColor: "rgb:321032",
10 cornerRadius: 100,
11 format: JPG,
12 quality: 90
13 })
14 }
15}

Transformation options translate to query string parameters that are appended to the url in the response. The resulting URL endpoints to the transformed version of the image.

1{
2 "data": {
3 "asset": {
4 "title": "contentful-team",
5 "url": "https://images.ctfassets.net/f8bqpb154z8p/4dgP2U7BeMuk0icguS4qGw/bc9431adf0b4a798b1aee97b2c56aa60/Contentful_team.png?w=500&h=300&q=90&fit=fill&f=bottom&r=100&bg=rgb%3A321032&fm=jpg"
6 }
7 }
8}

Transformation options take no effect when the asset is not an image.

width and height

Desired width and height of the image in pixels. Accept values between 1 and 4000. If not defined, default to the original image width and height.

quality

Desired quality of the image. Used for PNG8, JPG, JPG_PROGRESSIVE and WEBP formats. Accepts percentage values, between 1 and 100.

cornerRadius

Desired corner radius in pixels. Results in an image with rounded corners (pass -1 for a full circle/ellipse). If not defined, defaults to 0. Uses the desired background color as padding color, unless the format is JPG or JPG_PROGRESSIVE and resize strategy is PAD, then defaults to white.

resizeStrategy

Desired resize strategy. Accepts the following enum type values:

  • FIT (default) — resizes the image to fit into the specified dimensions.
  • PAD — resizes the image to the specified dimensions, padding the image if needed. Uses desired background color as padding color.
  • FILL — resizes the image to the specified dimensions, cropping the image if needed.
  • SCALE — resizes the image to the specified dimensions, changing the original aspect ratio if needed.
  • CROP — crops a part of the original image to fit into the specified dimensions.
  • THUMB — creates a thumbnail from the image focusing on the focus area.

resizeFocus

Desired resize focus area. Accepts the following enum type values:

  • CENTER (default)
  • TOP, RIGHT, LEFT, BOTTOM
  • TOP_RIGHT, TOP_LEFT, BOTTOM_RIGHT, BOTTOM_LEFT
  • FACE — focuses on the largest face.
  • FACES — focuses on the area containing all the faces.

It has no effect when used with FIT or SCALE resize strategy.

backgroundColor

Desired background color, used with corner radius or PAD resize strategy. Accepts RGB values in rgb:ffffff format. If not defined, defaults to transparent (for PNG, PNG8 and WEBP) or white (for JPG and JPG_PROGRESSIVE).

format

Desired image format. Accepts the following enum values:

  • JPG
  • JPG_PROGRESSIVE — stores multiple passes of an image in progressively higher detail.
  • PNG
  • PNG8 — supports up to 256 colors, weighs less than the standard 24-bit PNG.
  • WEBP
  • AVIF

If not defined, defaults to the original image format.

Asset keys

Asset keys are used when signing embargoed asset URLs.

Note: The Embargoed assets feature is only available on specific plans. Reach out to your Sales representative for more information about feature availability.

Secure asset URLs delivered by the CDA, CMA, CPA, or GraphQL API will have a host of (images,assets,videos,downloads).secure.ctfassets.net. They cannot be accessed without first signing the URL.

Signing an embargoed asset URL is accomplished by the following steps:

  1. Create an asset key for the space the asset URL belongs to. You must specify an expiresAt value, a Unix epoch timestamp in seconds, and this can be no more than 48 hours in the future.
  2. Create a JWT with the embargoed asset URL as the sub (JWT subject). Sign the JWT with the asset key’s secret.
  3. Affix to the original embargoed asset URL the following query parameters:
    • policy — the asset key’s policy
    • token — the JWT created in step 2
  4. You may affix other query parameters as well, for example when using the Images API. These do not impact the validity of the signed URL.

By default, a signed asset URL will stop functioning after the expiresAt value that was specified when creating the asset key. When generating the JWT, you may optionally specify an exp (expiry) that will cause the signed URL to be unusable at the specified expiry time. If a per-URL expiry is greater than the expiresAt value specified when creating the asset key, the asset key’s expiresAt value will be used instead.

Note: You cannot create an Asset Key via the GraphQL API. Use the CMA, CDA, or CPA based on your access needs.

Locations

Locations are represented as types with the properties lat and lon:

1type Location {
2 lat: Float
3 lon: Float
4}

Collections can be filtered on fields with Location type by applying supported location filters.

Rich Text

Rich text fields are represented as types with two properties:

  • json — exposes the actual RichText field value in a JSON format
  • links — allows you to deeply query various types of referenced entities

For example, if the content type Article has a RichText field text, the following types are generated:

1type Article {
2 text: ArticleText
3}
4
5type ArticleText {
6 json: JSON!
7 links: ArticleTextLinks!
8}
9
10type ArticleTextLinks {
11 entries: ArticleTextEntries!
12 assets: ArticleTextAssets!
13 resources: ArticleTextResourceLinks!
14}
15
16type ArticleTextEntries {
17 inline: [Entry]!
18 block: [Entry]!
19 hyperlink: [Entry]!
20}
21
22type ArticleTextAssets {
23 block: [Asset]!
24 hyperlink: [Asset]!
25}
26
27type ArticleTextResourceLinks {
28 block: [ResourceLink!]!
29}

Example query for a RichText field value and linked entities:

1query {
2 article(id: "some-article") {
3 text {
4 json
5 links {
6 assets {
7 block {
8 title
9 url
10 }
11 }
12 entries {
13 inline {
14 sys {
15 id
16 }
17 ... on Person {
18 name
19 age
20 }
21 }
22 }
23 resources {
24 block {
25 sys {
26 type
27 urn
28 linkType
29 }
30 }
31 }
32 }
33 }
34 }
35}

Never

The Never field type is used with the Functions feature. This type is assigned to the _data suffixed field when an error occurred during schema generation. For example, when the remote schema cannot be fetched, the _data fields depending on that schema will have the Never type. Field selections on a Never field will always return null, and the error information can be found in the errors array of the response.

Note that your Contentful schema can be fetched as it is and will not be impacted by any errors caused by external references.