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:
curl -H "Authorization: Bearer $CCR_CLOUD_TOKEN" http://127.0.0.1:8787/api/sessionsThe 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
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):
| Field | Description |
|---|---|
prompt | First message. The title defaults to its first line. |
title | Task title. |
projectId | A saved project to work in. |
repo | Clone URL, when not using a project. Work happens on branch ccr/SESSION_ID. |
baseBranch | Branch to start from. |
model | Claude model name. Omit to use the default (or CCR's routing). |
permissionMode | default, acceptEdits, auto, plan, dontAsk or bypassPermissions. Omit for the host default. See Permissions. |
outputStyle | default or concise. Omit to use the server's own setting. See Response style. |
It returns the task record with status 201.
#Sessions
| Route | Description |
|---|---|
GET /api/sessions | All tasks. |
GET /api/sessions/:id | One task, including state, openPermissions, permissionMode and outputStyle. |
GET /api/sessions/:id/events?from=N | The 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/messages | Send a follow-up: {"text": "..."}. Returns 409 if the task is stopped. |
POST /api/sessions/:id/permissions/:requestId | Answer an approval: {"behavior": "allow" \| "deny", "message"?: "..."}. |
POST /api/sessions/:id/interrupt | Interrupt the current turn. |
POST /api/sessions/:id/stop | Stop the task, keeping its workspace. |
POST /api/sessions/:id/start | Resume a stopped task. |
DELETE /api/sessions/:id | Delete 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
| Route | Description |
|---|---|
GET /api/projects | Saved projects. |
POST /api/projects | Check a clone URL and save it: {"name": "...", "repo": "URL"}. Returns 422 with the check if the repository isn't readable. |
POST /api/projects/check | Check a clone URL without saving: {"repo": "URL"}. |
GET /api/local-repositories | Repositories discovered on the server (host mode). |
POST /api/projects/local | Save a discovered checkout: {"path": "...", "name"?: "..."} (host mode). |
GET /api/setup | Which execution mode is in use and how credentials are handled. |
#Notifications
| Route | Description |
|---|---|
GET /api/push/key | The server's public push key. |
GET /api/push/subscriptions | Registered devices. |
POST /api/push/subscriptions | Register a device: {"subscription": {...}, "label"?: "..."}. |
DELETE /api/push/subscriptions | Remove a device: {"endpoint": "..."}. |
POST /api/push/test | Send 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.