Skip to content

Content API

Internal Application API

These are internal SPA routes (cookie/session authenticated, used by the Studio app), not a versioned public contract — they may change between releases. To read published content externally, use the CDN Delivery API.

Content operations in Studio are performed through the chat agent (SSE endpoint) or through direct API calls for programmatic use. The direct API provides content save and status management.

All content endpoints are project-scoped:

/api/workspaces/:workspaceId/projects/:projectId/content/...

Save Content

Save content entries to a model. Creates a cr/* branch, commits the changes, and optionally auto-merges based on workflow configuration.

POST /api/workspaces/:workspaceId/projects/:projectId/content/:modelId

Request Body

FieldTypeRequiredDescription
localestringNoLocale code (default: en)
dataobjectYesContent data (format depends on model kind)
slugstringConditionalDocument slug (required for document kind)
bodystringNoMarkdown body (document kind only)

Data Format by Kind

Collection:

json
{
  "data": {
    "a1b2c3d4e5f6": {
      "title": "My Blog Post",
      "excerpt": "A brief summary"
    }
  }
}

Singleton:

json
{
  "data": {
    "headline": "Welcome to Studio",
    "tagline": "Conversation-first CMS"
  }
}

Dictionary:

json
{
  "data": {
    "auth.sign_in_title": "Sign in to your account",
    "auth.sign_in_button": "Sign In"
  }
}

Response

json
{
  "branch": "cr/content/blog-post/en/1774800862-27c1",
  "commitSha": "abc123def456",
  "filesChanged": 2,
  "valid": true,
  "errors": [],
  "merged": true,
  "workflow": "auto-merge"
}

Auth

Requires editor, admin, or owner role.


Update Entry Status

Change the publish status of content entries.

PATCH /api/workspaces/:workspaceId/projects/:projectId/content/:modelId/status

Request Body

FieldTypeRequiredDescription
localestringNoLocale code (default: en)
entryIdsstring[]YesEntry IDs to update
status'draft' | 'published' | 'archived'YesTarget status

Response

json
{
  "branch": "cr/status/blog-post/en/...",
  "commitSha": "abc123",
  "merged": true
}

Brain Sync

Refresh the project brain cache. Returns the full content snapshot used by the chat agent and context panel.

GET /api/workspaces/:workspaceId/projects/:projectId/brain/sync

Response

json
{
  "models": [
    {
      "id": "blog-post",
      "name": "Blog Post",
      "kind": "collection",
      "domain": "blog",
      "i18n": true,
      "fields": { ... }
    }
  ],
  "content": {
    "blog-post:en": {
      "a1b2c3d4e5f6": {
        "title": "My Post",
        "status": "published"
      }
    }
  },
  "meta": {
    "blog-post:en": {
      "a1b2c3d4e5f6": {
        "createdAt": "2026-01-01T00:00:00Z",
        "updatedAt": "2026-01-15T00:00:00Z",
        "createdBy": "[email protected]"
      }
    }
  },
  "config": {
    "stack": "nuxt",
    "locales": { "default": "en", "supported": ["en", "tr"] },
    "domains": ["marketing", "blog"],
    "workflow": "auto-merge"
  },
  "schemaValidation": {
    "healthScore": 95,
    "modelCount": 5,
    "validModels": 5,
    "warnings": []
  }
}

Brain Cache

The brain cache is an in-memory representation of the project content, built from Git on first access and invalidated after any write operation. It is used by the chat agent for fast content reads.

Content Engine

Behind the scenes, all content operations go through the Content Engine (server/utils/content-engine/). The engine orchestrates:

  1. Validation -- schema-based content validation using model field definitions
  2. Serialization -- canonical JSON output (sorted keys, 2-space indent, trailing newline)
  3. Branching -- creates a cr/* feature branch from the contentrain SSOT branch
  4. Commit -- commits file changes via the GitProvider
  5. Auto-merge -- merges the branch back if workflow and permissions allow

See Content Engine for full internals.

Released under the AGPL-3.0 License.