Skip to content

GraphQL API

Use the GraphQL API to request content from Contismo outside the Studio, such as in a website, app, or other external system.

Each project environment has its own GraphQL endpoint.

To find the correct endpoint:

  1. Open your project in the Studio.
  2. Go to Settings and find the GraphQL endpoint for the environment you want to query.
  3. Use that URL when configuring your client or integration.

Authenticate requests by sending your API key in the Authorization header:

Authorization: Bearer <your-api-key>

Make sure the key you use has access to the project and environment you are querying.

The following example requests a list of entries from a blogPost model:

query {
blogPostCollection(limit: 10) {
items {
id
title
body
}
}
}

This returns up to 10 items, including the id, title, and body fields for each one.

To request a single entry, query the model type directly and provide the entry ID:

query {
blogPost(id: "entry-id-here") {
id
title
body
}
}

This is useful when you already know which entry you need to retrieve.

Use the uiTranslations field when your website or app needs reusable interface copy managed in the Studio.

The field returns a list of key-value pairs for a locale:

query {
uiTranslations {
key
value
}
}

By default, this returns values for the project default locale.

When your schema exposes locale enums, you can also pass the optional locale argument to request another locale.

This is useful for front-end strings such as navigation labels, buttons, notices, and shared UI messages.

For details about managing these values in the Studio, see UI Translations.

GraphQL mutations require a GraphQL - Read/Write API key (gqlw_ prefix). Read-only keys can query content but cannot run mutations.

Mutations are generated from your content models. For a model with API ID BlogPost, the available operations include:

  • createBlogPost — create an entry
  • updateBlogPost — update fields, status, or schedule dates
  • deleteBlogPost — soft-delete an entry

Global mutations are also available for assets, schema management, and entry translations:

  • createAsset / deleteAsset
  • createContentModel / updateContentModel / deleteContentModel
  • createComponent / updateComponent / deleteComponent
  • linkEntryTranslation / disconnectEntryTranslation

Per-model create mutations accept optional linkToEntryId to create a linked locale variant in one step.

mutation {
createBlogPost(
locale: "en"
status: DRAFT
input: {
title: "Hello world"
body: "First post"
}
) {
_id
_status
title
}
}
mutation {
updateBlogPost(
id: "entry-id-here"
status: PUBLISHED
input: {
title: "Hello world"
}
) {
_id
_status
}
}

Asset uploads use base64-encoded file content:

mutation {
createAsset(input: {
filename: "photo.jpg"
mimeType: "image/jpeg"
contentBase64: "<base64-encoded-bytes>"
}) {
id
url
}
}

GraphQL type names and field names are based on the API IDs configured in the Studio.

That means:

  • model API IDs determine the queryable types
  • field API IDs determine the fields you can request

If you change API IDs in the Studio, your queries may need to be updated to match.

When working with the GraphQL API, it is usually a good idea to:

  • use pagination for larger collections
  • request only the fields you actually need
  • check model and field API IDs carefully
  • account for locale arguments in localized projects, where supported

These practices help keep queries predictable and efficient.

Content and taxonomy entry types include underscore-prefixed metadata alongside your model fields. Common examples:

  • _id: the entry’s identifier
  • _status: delivery status (for example draft, published, or scheduled)
  • _locale: the locale for this entry
  • _localizations: all entries linked as locale variants of the same logical content (same content model, different locales)
  • _workflowStage: when an editorial workflow is configured for the model, the entry’s current workflow stage (apiId and name). This is separate from _status: the workflow describes editorial progress (e.g. review, approval), while _status describes what is delivered through the API.

Use the schema explorer to see the full set of metadata fields for your project.

When your project has multiple locales, related entries can be linked so they represent the same content in different languages. The API does not expose a separate “translation group” type; you work with entries and use _localizations to read linked variants.

query {
blogPost(id: "en-entry-id") {
_id
_localizations {
_id
_locale {
id
}
}
}
}

Use linkToEntryId on create{Model} to create an entry in another locale and link it to an existing entry:

mutation {
createBlogPost(
locale: "fr"
linkToEntryId: "en-entry-id"
input: {
title: "Bonjour"
}
) {
_id
_localizations {
_id
}
}
}

Use global mutations when both entries already exist:

  • linkEntryTranslation(entryId, peerEntryId) — move entryId into the same group as peerEntryId
  • disconnectEntryTranslation(entryId) — remove entryId from its group (other members stay linked)

Both return EntryTranslationMutationResult (a union of your entry types). Use an inline fragment for the model you expect:

mutation {
linkEntryTranslation(
entryId: "fr-entry-id"
peerEntryId: "en-entry-id"
) {
... on Entry_BlogPost {
_id
_localizations {
_id
_locale {
id
}
}
}
}
}

Replace Entry_BlogPost with the GraphQL type name for your model (shown in the GraphQL Explorer).

| Situation | Error code | | --------- | ------------ | | Entries use different content models | BAD_REQUEST | | Both entries are in the same locale | CONFLICT | | The group already has an entry for that locale | CONFLICT | | Entry not found | NOT_FOUND |

Linking and disconnecting require entry update permission (or update-own for entries you created). If another user is actively editing an entry in the Studio, mutations may return ENTRY_EDIT_LOCK_CONFLICT.