Guides

SDK Quickstart

Install the Monospace SDK, generate types from your schema, and query your data with generated types and full autocomplete.

This walkthrough generates a typed client for a workspace, queries fields and relations across two databases, and renames a field to show the build catching it.

Monospace SDK Quickstart6:35

Install the SDK

Add the Monospace SDK to your project, and the Monospace CLI as a development dependency.

npm install @monospace/sdk
npm install -D @monospace/cli

The SDK is the client you query with; the CLI generates its types.

Examples use TypeScript. Enable strict mode so nullable fields keep their | null annotations:

tsconfig.json
{
  "compilerOptions": {
    "strict": true
  }
}

In a JavaScript project, skip the CLI, configuration, and generation. Import createClient from @monospace/sdk and continue to Read Your Data; every query below runs unchanged. See Use the SDK from JavaScript.


Initialize Configuration

Run the interactive setup wizard to create a config file.

npx @monospace/cli sdk init

The wizard prompts for your Monospace instance URL, workspace identifier, and output directory, then writes a monospace.config.ts file equivalent to:

monospace.config.ts
import { defineConfig } from '@monospace/sdk/config'

export default defineConfig({
  url: 'https://example.monospace.io',
  workspace: 'blog',
  output: './src/generated/monospace',
})

output sets the directory for the generated client. It defaults to ./src/generated/monospace.


Generate Types

Run the generator to read your Monospace schema and produce a typed client:

npx @monospace/cli sdk generate

The generator connects to your instance, reads your workspace's schema through the OpenAPI endpoint, and writes a single index.ts file:

your-project/
├── src/
│   └── generated/
│       └── monospace/
│           └── index.ts      ← generated typed client
├── monospace.config.ts
├── package.json
└── tsconfig.json

The generated file contains:

  • TypeScript types for every collection, including field types, filter inputs, and relation shapes
  • A typed createClient factory that uses your Schema without manual generic parameters
  • Type aliases for each collection, including ArticlesKey, ArticlesCreateOneInput, and ArticlesReadManyResult
Tip
The generator needs schema access. Set MONOSPACE_API_KEY in a .env file, or authenticate via the OS keychain with the login command.

Create the Client

Import createClient from the generated output to use your schema's types:

src/client.ts
import { createClient } from './generated/monospace';

const client = createClient({
  url: 'https://example.monospace.io',
  workspace: 'blog',
  apiKey: process.env.MONOSPACE_API_KEY,
});

The client exposes each collection in your schema (e.g., client.Articles, client.Authors, client.Tags) with autocomplete for CRUD methods and field names. The types come from your schema, without manual type definitions or runtime validation.

Type client. in your editor to see the collections. Select one, then type .readMany({ fields: [ to see field name suggestions.


Read Your Data

Fetch articles with typed field selection.

src/index.ts
const articles = await client.Articles.readMany({
  fields: ['id', 'title', 'status'],
});

// TypeScript knows the exact shape:
// {
//   id: string | null;
//   title: string | null;
//   status: string | null;
// }[]

for (const article of articles) {
  console.log(article.title);
}

The return type includes exactly the fields in your fields array and updates when you add one. Remove a field, and TypeScript flags code that references it.

readMany returns up to 100 items by default. Use limit and offset for pagination:

SDK
const page = await client.Articles.readMany({
  fields: ['id', 'title'],
  limit: 20,
  offset: 40,
});

Fetch a single item by key:

SDK
const article = await client.Articles.readOne({
  key: 1,
  fields: ['id', 'title', 'status'],
});

// TypeScript infers a single object (not an array):
// {
//   id: string | null;
//   title: string | null;
//   status: string | null;
// }

Create and Update Items

Create an article with input types checked by TypeScript:

SDK
const created = await client.Articles.createOne({
  data: {
    title: 'Getting Started with Monospace',
    status: 'draft',
  },
  fields: ['id', 'title', 'status'],
});

console.log(created.id); // typed as string | null

TypeScript checks data against your schema, enforcing required fields and rejecting unknown fields.

Update an existing article by key. Fields are typed | null by default and key does not accept null, so narrow created.id first:

SDK
if (created.id === null) {
  throw new Error('The created article has no id.');
}

const updated = await client.Articles.updateOne({
  key: created.id,
  data: {
    status: 'published',
  },
  fields: ['id', 'status'],
});

console.log(updated.status); // typed as string | null

Update inputs make every field optional — include only the fields you want to change.


Next Steps

  • Filtering — narrow results with typed filter operators like _eq, _contains, and _in
  • Field Selection — control which fields are returned for each item
  • Relational Data — fetch and write nested relations in a single request
  • Type System — extract result types for component props, reusable queries with satisfies, and more

MonospaceThe governed API layer for every app, person, and agent.

Copyright © 2026 Monospace Inc.