Skip to content

Branches 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.

Content operations in Studio create cr/* feature branches. These branches can be reviewed and merged (in review workflow) or are auto-merged (in auto-merge workflow).

All branch endpoints are project-scoped:

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

Git Architecture

Studio uses a two-branch strategy:

  1. contentrain -- the SSOT (Single Source of Truth) branch for content
  2. cr/* -- feature branches for individual operations (e.g., cr/content/blog-post/en/1774800862-27c1)

The merge flow is: cr/* -> contentrain -> main


List Branches

List all pending cr/* content branches.

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

Response

json
{
  "branches": [
    {
      "name": "cr/content/blog-post/en/1774800862-27c1",
      "sha": "abc123def456",
      "protected": false
    }
  ]
}

Get Branch Diff

Get the file-level diff for a branch compared to the contentrain base branch.

GET /api/workspaces/:workspaceId/projects/:projectId/branches/:branch/diff

URL Encoding

Branch names contain / characters. Encode them in the URL:

/branches/cr%2Fcontent%2Fblog-post%2Fen%2F1774800862-27c1/diff

Response

json
{
  "diff": [
    {
      "path": ".contentrain/content/blog/blog-post/en.json",
      "status": "modified",
      "before": "{\"a1b2c3d4e5f6\":{\"title\":\"Old Title\"}}",
      "after": "{\"a1b2c3d4e5f6\":{\"title\":\"New Title\"}}"
    }
  ]
}

Merge Branch

Merge a cr/* branch. Two-step process: merges into contentrain, then advances contentrain to main.

POST /api/workspaces/:workspaceId/projects/:projectId/branches/:branch/merge

Response

json
{
  "merged": true,
  "sha": "abc123def456",
  "pullRequestUrl": null
}

Branch Protection

If the main branch has protection rules requiring pull requests, Studio creates a PR and attempts to merge it. The pullRequestUrl field contains the PR URL.

Auth

Requires reviewer, admin, or owner role.


Reject Branch

Reject and delete a cr/* branch, discarding all changes.

POST /api/workspaces/:workspaceId/projects/:projectId/branches/:branch/reject

Response

json
{
  "rejected": true
}

Auth

Requires reviewer, admin, or owner role. The permanent contentrain branch cannot be rejected.


Branch Health

Get branch health metrics for the project.

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

Branch Cleanup

Clean up merged cr/* branches that are no longer needed.

POST /api/workspaces/:workspaceId/projects/:projectId/branches/cleanup

Released under the AGPL-3.0 License.