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/projectsResponse
[
{
"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/projectsRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
repoFullName | string | Yes | GitHub owner/repo full name |
name | string | Yes | Display name for the project |
defaultBranch | string | No | Default branch name (auto-detected if omitted) |
contentRoot | string | No | Sub-path for .contentrain/ directory (e.g., apps/web) |
Response
{
"id": "uuid",
"name": "my-website",
"repo_full_name": "org/my-website",
"default_branch": "main",
"content_root": "",
"status": "active"
}Error Codes
| Status | Condition |
|---|---|
403 | Plan does not support project creation (projects.create) |
409 | Repository already connected in this workspace |
Get Project
Get project details with member information.
GET /api/workspaces/:workspaceId/projects/:projectIdDelete Project
Delete a project (does not delete the GitHub repository).
DELETE /api/workspaces/:workspaceId/projects/:projectIdAuth
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/configRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
workflow | 'auto-merge' | 'review' | No | Content workflow mode |
locales | object | No | Locale configuration with default and supported |
domains | string[] | No | Content domains |
Project Health
Get project health status including branch health and GitHub connectivity.
GET /api/workspaces/:workspaceId/projects/:projectId/healthBrain Sync
Refresh the project brain cache from Git.
GET /api/workspaces/:workspaceId/projects/:projectId/brain/syncReturns 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/vocabularyRequest Body
{
"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/:modelIdProject Members
List Members
GET /api/workspaces/:workspaceId/projects/:projectId/membersAdd Member
POST /api/workspaces/:workspaceId/projects/:projectId/members| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | User ID (must be a workspace member) |
role | 'editor' | 'reviewer' | 'viewer' | Yes | Project role |
specificModels | boolean | No | Restrict access to specific models (Pro+) |
allowedModels | string[] | No | Model IDs the member can access |
Remove Member
DELETE /api/workspaces/:workspaceId/projects/:projectId/members/:memberIdAuth
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/activityQuery Parameters
| Param | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
limit | number | 20 | Items per page (max 100) |
action | string | -- | Filter by action name (e.g. delete_project) |
sort | 'newest' | 'oldest' | newest | Sort order |
Response
{
"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/installationReturns the GitHub App installation details for the current workspace.
List Repositories
GET /api/github/reposLists repositories accessible through the GitHub App installation.
Scan Repository
GET /api/github/scan?repo=owner/repoScans a repository for .contentrain/ directory and detects the framework stack.
Create from Template
POST /api/github/create-from-templateCreates a new repository from a starter kit template.
GitHub App Setup
GET /api/github/setupHandles 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
{
"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
| Status | Condition |
|---|---|
400 | Missing workspaceId |
401 | No usable GitHub user token -- response data.code is GITHUB_REAUTH_REQUIRED (user must reconnect GitHub) |
404 | Workspace 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/connectRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Yes | Target workspace |
installationId | number | Yes | GitHub App installation ID |
Response
{ "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
| Status | Condition |
|---|---|
400 | Missing workspaceId or invalid installationId |
401 | No usable GitHub user token (data.code = GITHUB_REAUTH_REQUIRED) |
403 | Caller lacks GitHub-side access to the installation |
404 | Workspace not found or caller is not an owner/admin of it |
409 | Installation is already bound to a different workspace |
Related Pages
- Workspaces API -- workspace management
- Content API -- content operations within projects
- Roles & Permissions -- project role definitions