HTTP API

The web app uses this API, and you can too: start tasks from scripts, follow their events or answer approvals from other tools. The API is served by the control plane, http://127.0.0.1:8787 by default.

#Authentication

Send your owner token on every request:

SHELL
curl -H "Authorization: Bearer $CCR_CLOUD_TOKEN" http://127.0.0.1:8787/api/sessions

The event stream also accepts ?token= because browsers' EventSource can't set headers. GET /api/health and the web app's static files need no token.

Errors return JSON, {"error": "..."}, with a matching status code: 400 for invalid input, 401 without a valid token, 404 for an unknown task or request, and 409 when the request conflicts with the task's state.

#Start a task

SHELL
curl -X POST http://127.0.0.1:8787/api/sessions \
  -H "Authorization: Bearer $CCR_CLOUD_TOKEN" -H "Content-Type: application/json" \
  -d '{"prompt": "Reply OK", "permissionMode": "default", "outputStyle": "concise"}'

POST /api/sessions body (all fields optional):

FieldDescription
promptFirst message. The title defaults to its first line.
titleTask title.
projectIdA saved project to work in.
repoClone URL, when not using a project. Work happens on branch ccr/SESSION_ID.
baseBranchBranch to start from.
modelClaude model name. Omit to use the default (or CCR's routing).
permissionModedefault, acceptEdits, auto, plan, dontAsk or bypassPermissions. Omit for the host default. See Permissions.
outputStyledefault or concise. Omit to use the server's own setting. See Response style.

It returns the task record with status 201.

#Sessions

RouteDescription
GET /api/sessionsAll tasks.
GET /api/sessions/:idOne task, including state, openPermissions, permissionMode and outputStyle.
GET /api/sessions/:id/events?from=NThe task's event log from offset N. Send Accept: text/event-stream for live server-sent events; reconnects resume from Last-Event-ID.
POST /api/sessions/:id/messagesSend a follow-up: {"text": "..."}. Returns 409 if the task is stopped.
POST /api/sessions/:id/permissions/:requestIdAnswer an approval: {"behavior": "allow" \| "deny", "message"?: "..."}.
POST /api/sessions/:id/interruptInterrupt the current turn.
POST /api/sessions/:id/stopStop the task, keeping its workspace.
POST /api/sessions/:id/startResume a stopped task.
DELETE /api/sessions/:idDelete the task, its workspace and its log.

A task's state is one of pending, cloning, idle, running, waiting (approval needed), exited or failed.

#Projects

RouteDescription
GET /api/projectsSaved projects.
POST /api/projectsCheck a clone URL and save it: {"name": "...", "repo": "URL"}. Returns 422 with the check if the repository isn't readable.
POST /api/projects/checkCheck a clone URL without saving: {"repo": "URL"}.
GET /api/local-repositoriesRepositories discovered on the server (host mode).
POST /api/projects/localSave a discovered checkout: {"path": "...", "name"?: "..."} (host mode).
GET /api/setupWhich execution mode is in use and how credentials are handled.

#Notifications

RouteDescription
GET /api/push/keyThe server's public push key.
GET /api/push/subscriptionsRegistered devices.
POST /api/push/subscriptionsRegister a device: {"subscription": {...}, "label"?: "..."}.
DELETE /api/push/subscriptionsRemove a device: {"endpoint": "..."}.
POST /api/push/testSend a test notification to every device.

#Health

GET /api/health returns {"service": "ccr-cloud", "status": "ok", "apiVersion": 2} without authentication. If apiVersion is missing, an older control plane is running; see Troubleshooting.

Edit this page on GitHub ↗