TypeScript SDK
The Contismo TypeScript SDK is the official TypeScript client for the Contismo GraphQL Content API. Use it to query content, run mutations, introspect your schema, and generate TypeScript types for your project.
The package is published on npm as @contismo/sdk.
Install
Section titled “Install”Install the SDK in your application:
pnpm add @contismo/sdkThe SDK requires Node.js 20 or newer.
Authentication
Section titled “Authentication”The SDK authenticates with a Contismo GraphQL API key and sends Authorization and the X-Environment header automatically.
API keys are created in the Studio under Settings → API Keys.
| Key prefix | Access |
|---|---|
gql_ |
Queries and introspection |
gqlw_ |
Queries, mutations, and introspection |
Use a gql_ key for read-only delivery clients. Use a gqlw_ key only where your application needs to create, update, or delete content.
Quick Start
Section titled “Quick Start”- Create
contismo.config.tsat your project root. 2. Runpnpm contismo generateto pull your schema and generate TypeScript types. 3. Create a client and query content withfetchorfetchOne.
import { defineConfig } from "@contismo/sdk/config";
export default defineConfig({ client: { apiKey: "gql_...", endpoint: "https://graphql.contismo.com", environment: "master", },});pnpm contismo generateimport { ContismoClient } from "@contismo/sdk";import { BlogPost } from "./generated/contismo-models";
const client = new ContismoClient();
const { items: posts } = await client.fetch(BlogPost, { select: { _id: true, title: true, }, limit: 10,});The first argument to fetch is the content model API ID from the Studio, or a generated model ref from contismo-models.ts (see Query Content).
Configuration
Section titled “Configuration”The required client options in contismo.config.ts are:
| Option | Description |
|---|---|
apiKey |
GraphQL API key from the Studio |
endpoint |
GraphQL endpoint, usually https://graphql.contismo.com |
environment |
Environment API ID, sent as X-Environment |
Add optional codegen settings when you want to change output paths:
import { defineConfig } from "@contismo/sdk/config";
export default defineConfig({ client: { apiKey: "gql_...", endpoint: "https://graphql.contismo.com", environment: "master", }, codegen: { outputDir: "./src/generated", outputFile: "contismo.ts", schemaDir: "./contismo", },});By default, pnpm contismo generate writes:
contismo/schema.jsonsrc/generated/contismo.ts— entry types such asEntry_BlogPostcontismo-models.ts— model registry,ContismoEntryMap, and typed model refs such asBlogPost
Explicit Client Setup
Section titled “Explicit Client Setup”If your app does not use a config file, pass credentials directly:
import { ContismoClient } from "@contismo/sdk";
const client = new ContismoClient({ apiKey: "gql_...", endpoint: "https://graphql.contismo.com", environment: "master",});If your config file lives somewhere else, pass its path:
const client = new ContismoClient({ config: "./config/contismo.config.ts",});Introspection
Section titled “Introspection”Use introspect to read the GraphQL schema programmatically. It uses the same credentials as content queries: a GraphQL API key (gql_ or gqlw_) and environment. If the key or environment is wrong, the API returns an authentication error instead of a generic introspection failure.
const schema = await client.introspect();The SDK also exports writeIntrospectionResult if you want to write the result to disk in a custom workflow.
Query Content
Section titled “Query Content”Use fetch to query a list of entries with a Prisma-style select object. fetchOne fetches a single entry by ID.
Model refs
Section titled “Model refs”After contismo generate, import a model ref from contismo-models.ts. The return type is inferred — no explicit generic:
import { ContismoClient } from "@contismo/sdk";import { BlogPost } from "./generated/contismo-models";
const client = new ContismoClient();
const { items: posts } = await client.fetch(BlogPost, { select: { _id: true, title: true, author: { name: true, }, }, limit: 10,});
const post = await client.fetchOne(BlogPost, { id: "entry-id-here", select: { _id: true, title: true, },});Union Fields
Section titled “Union Fields”For fields that return a GraphQL union, group each selection under its generated member type name. The SDK turns these keys into inline fragments:
import { ContismoClient } from "@contismo/sdk";import { Guide } from "./generated/contismo-models";
const client = new ContismoClient();
const guide = await client.fetchOne(Guide, { id: "guide-id-here", select: { title: true, modularContent: { Component_Accordion: { type: true, items: { heading: true, content: { asHtml: true }, }, }, Component_Content: { content: { asHtml: true }, }, }, },});Use member names from the generated schema types, such as Component_Accordion, Component_Content, or Entry_Guide. Union selections work with both fetch and fetchOne.
Assets & CDN
Section titled “Assets & CDN”Asset fields on entries return CDN URLs. Select url and thumbnailUrl, then use buildCdnUrl to append image transforms:
import { ContismoClient, buildCdnUrl } from "@contismo/sdk";import { BlogPost } from "./generated/contismo-models";
const client = new ContismoClient();
const { items: posts } = await client.fetch(BlogPost, { select: { _id: true, title: true, cover: { url: true, thumbnailUrl: true, }, }, limit: 10,});
const cover = posts[0]?.cover;const previewUrl = cover?.thumbnailUrl ?? cover?.url;const heroUrl = cover?.url ? buildCdnUrl(cover.url, { w: 1200, fmt: "webp", q: 80, }) : null;CDN delivery is public — GET requests do not need an API key. Prefer thumbnailUrl for list and card previews when it is present. Use the full url with transforms for the main image.
For the full transform parameter reference, see the Image CDN guide.
Raw GraphQL
Section titled “Raw GraphQL”Use query when you want to provide the GraphQL document yourself:
const data = await client.query( ` query BlogPost($id: ID!) { blogPost(id: $id) { _id title } }`, { id: "entry-id-here" },);This is useful when you want full control over the operation or when copying a query from the GraphQL Explorer.
Mutations
Section titled “Mutations”Mutations require a read/write API key with the gqlw_ prefix. The SDK blocks client.mutate() calls before making a network request when the client is configured with a read-only gql_ key. Content entry mutations use {ModelApiId}Input (for example BlogPostInput) for both create and update—not {ModelApiId}CreateInput.
const client = new ContismoClient({ apiKey: "gqlw_...", endpoint: "https://graphql.contismo.com", environment: "master",});
await client.mutate( ` mutation CreatePost($input: BlogPostInput!) { createBlogPost(input: $input) { _id _status title } }`, { input: { title: "Hello world", }, },);For mutation shapes and generated operation names, see the GraphQL API reference.
Error Handling
Section titled “Error Handling”Missing entries do not throw. Singular reads such as blogPost(id: …) and client.fetchOne() return null when no entry matches (wrong id, locale, or status filters). Check the result instead of using try/catch:
const client = new ContismoClient();
const post = await client.fetchOne("BlogPost", { id: entryId, select: { _id: true, title: true },});
if (post == null) { // Entry does not exist or does not match filters}GraphQL, HTTP, and SDK failures throw. Configuration errors, validation errors, auth failures, rate limits, and other API errors reject the promise as ContismoError (often ContismoGraphQLError). Use isContismoError to handle them:
import { ContismoClient, ContismoGraphQLError, isContismoError,} from "@contismo/sdk";
const client = new ContismoClient();
try { await client.query(`query { blogPostCollection { items { _id } } }`);} catch (error) { if (isContismoError(error) && error instanceof ContismoGraphQLError) { console.error(error.code, error.message); }}This catches request failures from the API—not a null singular field when an id is missing.