Skip to content

Projects 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. For external integrations, use the Public API.

Projects represent connected Git repositories within a workspace. Each project maps to one repository and contains content models, entries, media, and conversations.

All project endpoints are scoped under a workspace:

/api/workspaces/:workspaceId/projects/...

List Projects

List all projects in a workspace.

GET /api/workspaces/:workspaceId/projects

Response

json
[
  {
    "id": "uuid",
    "name": "my-website",
    "repo_full_name": "org/my-website",
    "default_branch": "main",
    "content_root": "",
    "status": "active",
    "created_at": "2026-01-01T00:00:00Z"
  }
]

Create Project

Connect a GitHub repository as a new project.

POST /api/workspaces/:workspaceId/projects

Request Body

FieldTypeRequiredDescription
repoFullNamestringYesGitHub owner/repo full name
namestringYesDisplay name for the project
defaultBranchstringNoDefault branch name (auto-detected if omitted)
contentRootstringNoSub-path for .contentrain/ directory (e.g., apps/web)

Response

json
{
  "id": "uuid",
  "name": "my-website",
  "repo_full_name": "org/my-website",
  "default_branch": "main",
  "content_root": "",
  "status": "active"
}

Error Codes

StatusCondition
403Plan does not support project creation (projects.create)
409Repository already connected in this workspace

Get Project

Get project details with member information.

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

Delete Project

Delete a project (does not delete the GitHub repository).

DELETE /api/workspaces/:workspaceId/projects/:projectId

Auth

Requires workspace owner or admin role.


Update Project Configuration

Update the Contentrain configuration for a project (workflow, locales, etc.).

PATCH /api/workspaces/:workspaceId/projects/:projectId/config

Request Body

FieldTypeRequiredDescription
workflow'auto-merge' | 'review'NoContent workflow mode
localesobjectNoLocale configuration with default and supported
domainsstring[]NoContent domains

Project Health

Get project health status including branch health and GitHub connectivity.

GET /api/workspaces/:workspaceId/projects/:projectId/health

Brain Sync

Refresh the project brain cache from Git.

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

Returns the full project snapshot: models, content, meta, and schema validation results.


Update Vocabulary

Update the project vocabulary (shared terminology across locales).

PATCH /api/workspaces/:workspaceId/projects/:projectId/vocabulary

Request Body

json
{
  "terms": {
    "brand_name": {
      "en": "Contentrain",
      "tr": "Contentrain"
    }
  }
}

Update Model Metadata

Update model-level settings (e.g., form configuration).

PATCH /api/workspaces/:workspaceId/projects/:projectId/models/:modelId

Project Members

List Members

GET /api/workspaces/:workspaceId/projects/:projectId/members

Add Member

POST /api/workspaces/:workspaceId/projects/:projectId/members
FieldTypeRequiredDescription
userIdstringYesUser ID (must be a workspace member)
role'editor' | 'reviewer' | 'viewer'YesProject role
specificModelsbooleanNoRestrict access to specific models (Pro+)
allowedModelsstring[]NoModel IDs the member can access

Remove Member

DELETE /api/workspaces/:workspaceId/projects/:projectId/members/:memberId

Auth

Requires workspace owner or admin role to manage project members.


Project Activity

Paginated activity feed for a project, sourced from the workspace audit log.

GET /api/workspaces/:workspaceId/projects/:projectId/activity

Query Parameters

ParamTypeDefaultDescription
pagenumber1Page number
limitnumber20Items per page (max 100)
actionstring--Filter by action name (e.g. delete_project)
sort'newest' | 'oldest'newestSort order

Response

json
{
  "data": [
    {
      "id": "uuid",
      "action": "save_content",
      "actor": "uuid",
      "entity": "content_entries",
      "recordId": "uuid",
      "origin": "chat",
      "createdAt": "2026-01-01T00:00:00Z"
    }
  ],
  "total": 128,
  "page": 1,
  "limit": 20
}

actor is the acting user's ID; entity is the affected table name. The feed is currently workspace-scoped (the audit log carries workspace_id).

Auth

Requires workspace owner, admin, or member role. Returns 404 if the project is not found in the workspace.


GitHub Routes

These endpoints are used during the repository connection flow.

Get Installation

GET /api/github/installation

Returns the GitHub App installation details for the current workspace.

List Repositories

GET /api/github/repos

Lists repositories accessible through the GitHub App installation.

Scan Repository

GET /api/github/scan?repo=owner/repo

Scans a repository for .contentrain/ directory and detects the framework stack.

Create from Template

POST /api/github/create-from-template

Creates a new repository from a starter kit template.

GitHub App Setup

GET /api/github/setup

Handles the GitHub App installation callback redirect.

List Available Installations

Enumerate GitHub App installations visible to the authenticated user, each annotated with whether it is already bound to a workspace (so the picker can disable in-use installations).

GET /api/github/installations/available?workspaceId=<id>

Response

json
{
  "installations": [
    {
      "id": 12345,
      "account": "my-org",
      "repositorySelection": "selected",
      "targetType": "Organization",
      "boundWorkspace": { "id": "uuid", "name": "Other Workspace", "slug": "other-workspace" }
    }
  ]
}

boundWorkspace is null when the installation is not yet connected to any workspace.

Auth

Requires workspace owner or admin role, and a valid GitHub user token.

Error Codes

StatusCondition
400Missing workspaceId
401No usable GitHub user token -- response data.code is GITHUB_REAUTH_REQUIRED (user must reconnect GitHub)
404Workspace not found or caller is not an owner/admin of it

Connect Installation

Bind an existing GitHub App installation to a workspace -- the "Connect existing installation" counterpart to the install-callback flow. On success the workspace's github_installation_id is set and its status flips to active.

POST /api/github/installations/connect

Request Body

FieldTypeRequiredDescription
workspaceIdstringYesTarget workspace
installationIdnumberYesGitHub App installation ID

Response

json
{ "connected": true, "installationId": 12345, "workspaceId": "uuid" }

Auth

Requires workspace owner or admin role, and a valid GitHub user token. The caller's GitHub-side access to the installation is verified before binding.

Error Codes

StatusCondition
400Missing workspaceId or invalid installationId
401No usable GitHub user token (data.code = GITHUB_REAUTH_REQUIRED)
403Caller lacks GitHub-side access to the installation
404Workspace not found or caller is not an owner/admin of it
409Installation is already bound to a different workspace

Released under the AGPL-3.0 License.