Introduction

Getting Started

This guide walks you through creating your CellCMS account, setting up your first project, creating content, and querying it from a frontend application.

1. Create Your Account

Sign up at cellcms.com and create your first project. You'll get:

  • A Content Studio at studio.cellcms.com for editing content
  • An API at api.cellcms.com for querying and managing content

2. Log In to the Studio

Open studio.cellcms.com and sign in with your account credentials.

The Studio is a three-panel editor where you can:

  • Browse and search your content
  • Create and edit documents
  • Upload images and files
  • Manage schemas, tokens, and settings

Create Your First Schema

CellCMS uses Sanity-compatible schema definitions. Create a file for your content model:

// schemas/post.ts
import { defineType, defineField } from '@cellcms/schema'

export const post = defineType({
  name: 'post',
  title: 'Blog Post',
  type: 'document',
  fields: [
    defineField({
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: (Rule) => Rule.required().max(200),
    }),
    defineField({
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: { source: 'title' },
      validation: (Rule) => Rule.required(),
    }),
    defineField({
      name: 'body',
      title: 'Body',
      type: 'block',
    }),
    defineField({
      name: 'coverImage',
      title: 'Cover Image',
      type: 'image',
      options: { hotspot: true },
    }),
    defineField({
      name: 'publishedAt',
      title: 'Published At',
      type: 'datetime',
    }),
  ],
  preview: {
    select: { title: 'title', media: 'coverImage' },
  },
})

Register it with your Studio configuration so it appears in the editor. See the Schema Definition guide for all field types and options.


Create Your First Document

  1. Open the Studio at studio.cellcms.com
  2. Click Blog Post in the left sidebar
  3. Click Create new
  4. Fill in the title, slug, and body
  5. Click Save (or press Cmd+S / Ctrl+S)
  6. Click Publish to make it publicly queryable

Query with GROQ

GROQ (Graph-Relational Object Queries) is the query language for fetching content. You can test queries directly against the API:

# Fetch all published blog posts
curl -X POST https://api.cellcms.com/api/v1/data/query/production \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "*[_type == \"post\"]{title, slug, publishedAt}"}'

Response:

{
  "query": "*[_type == \"post\"]{title, slug, publishedAt}",
  "ms": 12,
  "result": [
    {
      "title": "Hello World",
      "slug": { "current": "hello-world" },
      "publishedAt": "2025-01-15T10:00:00Z"
    }
  ]
}

See the GROQ Reference for the complete query language.


Query from Your Frontend

Install the CellCMS client SDK in your Next.js or frontend project:

npm install @cellcms/client

Create a client instance:

import { createClient } from '@cellcms/client'

const client = createClient({
  apiUrl: 'https://api.cellcms.com',
  project: 'my-project',
  dataset: 'production',
  token: 'cell_your-api-token-here', // Create one in Studio → Settings → API Tokens
})

Fetch your blog posts:

// Fetch all posts
const posts = await client.fetch('*[_type == "post"]{title, slug, publishedAt}')

// Fetch a single post by slug
const post = await client.fetch(
  '*[_type == "post" && slug.current == $slug][0]',
  { slug: 'hello-world' }
)

// Create a new post
await client.create({
  _type: 'post',
  title: 'My New Post',
  slug: { current: 'my-new-post' },
})

See the Client SDK reference for all available methods.


Create an API Token

For frontend access, create a read-only API token:

  1. Log in to the Studio as an admin
  2. Navigate to Settings → API Tokens
  3. Click Create Token
  4. Give it a name (e.g., "Frontend read-only")
  5. Set permissions to read
  6. Copy the token — it's shown only once

Or via the API:

curl -X POST https://api.cellcms.com/api/v1/tokens/default \
  -H "Authorization: Bearer YOUR_JWT" \
  -H "Content-Type: application/json" \
  -d '{"name": "Frontend", "permissions": ["read"]}'

The response includes the token (prefixed with cell_) which you'll use in your client configuration.


Next Steps