cc-connect Management API Specification

June 4, 2026 · View on GitHub

Version: 1.1-draft
Status: Draft — subject to change before implementation
Last Updated: 2026-03-24


1. Overview

The cc-connect Management API is an HTTP-based REST API that enables external applications (web dashboards, TUI clients, GUI desktop apps, Mac tray apps) to manage and monitor cc-connect instances. It complements the existing internal Unix socket API by providing a network-accessible, token-authenticated interface suitable for remote and local management tools.

1.1 Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                         cc-connect Process                               │
│                                                                          │
│  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  │
│  │  Unix Socket API │    │  Management API   │    │  Bridge Server   │  │
│  │  (internal)      │    │  (HTTP :9820)     │    │  (WebSocket)     │  │
│  └────────┬─────────┘    └────────┬─────────┘    └────────┬─────────┘  │
│           │                       │                       │             │
│           └───────────────────────┼───────────────────────┘             │
│                                   │                                      │
│                          ┌────────┴────────┐                            │
│                          │  Core Engine(s)  │                            │
│                          │  Projects       │                            │
│                          │  Sessions      │                            │
│                          │  Cron/Heartbeat │                            │
│                          └─────────────────┘                            │
└─────────────────────────────────────────────────────────────────────────┘

              ┌─────────────────────┼─────────────────────┐
              │                     │                     │
     ┌────────┴────────┐   ┌───────┴───────┐   ┌─────────┴─────────┐
     │  Web Dashboard  │   │  TUI Client   │   │  Mac Tray App      │
     └─────────────────┘   └───────────────┘   └────────────────────┘

1.2 Design Principles

  • RESTful: Resource-oriented URLs, standard HTTP methods
  • JSON: All request/response bodies use application/json
  • Consistent envelope: Every response uses {"ok": true|false, "data"|"error": ...}
  • Token auth: Bearer token or query parameter for all endpoints

2. Configuration

2.1 Management Block

Add the following to config.toml:

[management]
enabled = true
port = 9820
token = "mgmt-secret"
FieldTypeDefaultDescription
enabledbooleanfalseEnable the Management API server
portinteger9820TCP port to listen on
tokenstring(required)Shared secret for authentication

When enabled is false, the Management API is not started. The token should be a strong, random string (e.g. 32+ characters).

2.2 Base URL

All endpoints are relative to:

http://<host>:<port>/api/v1

Example: http://localhost:9820/api/v1/status


3. Authentication

Every request must include a valid token. Two methods are supported:

Authorization: Bearer <token>

Example:

curl -H "Authorization: Bearer mgmt-secret" http://localhost:9820/api/v1/status

3.2 Query Parameter

GET /api/v1/status?token=mgmt-secret

Note: Query parameter auth is provided for environments where setting headers is difficult. Prefer Bearer token for security (tokens in URLs may be logged).

3.3 Unauthorized Response

If the token is missing or invalid:

  • HTTP Status: 401 Unauthorized
  • Body:
{
  "ok": false,
  "error": "unauthorized: missing or invalid token"
}

4. Response Format

4.1 Success

{
  "ok": true,
  "data": { ... }
}

4.2 Error

{
  "ok": false,
  "error": "human-readable error message"
}

4.3 HTTP Status Codes

CodeMeaning
200Success
400Bad request (invalid body, missing params)
401Unauthorized (missing/invalid token)
404Resource not found (project, session, etc.)
405Method not allowed
500Internal server error

5. Endpoint Reference

5.1 System

GET /api/v1/status

Returns system status and summary.

Response:

{
  "ok": true,
  "data": {
    "version": "v1.2.0",
    "uptime_seconds": 3600,
    "connected_platforms": ["feishu", "telegram"],
    "projects_count": 2,
    "bridge_adapters": [
      {
        "platform": "custom",
        "project": "my-backend",
        "capabilities": ["text", "images"]
      }
    ]
  }
}
FieldTypeDescription
versionstringcc-connect version (e.g. v1.2.0)
uptime_secondsnumberProcess uptime in seconds
connected_platformsstring[]Platform types currently connected
projects_countnumberNumber of configured projects
bridge_adaptersarrayExternal adapters connected via Bridge WebSocket

POST /api/v1/restart

Triggers a graceful restart. The process will shut down cleanly and exec itself. A "restart successful" message may be sent to the session that initiated the restart (if applicable).

Request body (optional):

{
  "session_key": "telegram:123:456",
  "platform": "telegram"
}

If provided, the restart notification will be sent to the specified session after the new process starts.

Response:

{
  "ok": true,
  "data": {
    "message": "restart initiated"
  }
}

POST /api/v1/reload

Reloads configuration from disk without restarting the process. New projects may be added; removed projects are stopped. Changed project settings take effect.

Response:

{
  "ok": true,
  "data": {
    "message": "config reloaded",
    "projects_added": ["new-project"],
    "projects_removed": [],
    "projects_updated": ["my-backend"]
  }
}

GET /api/v1/config

Returns the current configuration with secrets redacted. Useful for debugging and UI display.

Query parameters: None

Response:

{
  "ok": true,
  "data": {
    "data_dir": "/home/user/.cc-connect",
    "language": "en",
    "projects": [
      {
        "name": "my-backend",
        "agent": {
          "type": "claudecode",
          "providers": [
            {
              "name": "anthropic",
              "api_key": "***",
              "base_url": "",
              "model": "claude-sonnet-4-20250514"
            }
          ]
        },
        "platforms": [
          {
            "type": "feishu",
            "options": {
              "app_id": "***",
              "app_secret": "***"
            }
          }
        ]
      }
    ]
  }
}

Secrets (e.g. api_key, token, app_secret, client_secret) are replaced with "***".


GET /api/v1/logs

Returns recent log entries.

Query parameters:

ParamTypeDefaultDescription
levelstringinfoMinimum level: debug, info, warn, error
limitint100Max entries to return (1–1000)

Response:

{
  "ok": true,
  "data": {
    "entries": [
      {
        "time": "2026-03-10T10:30:00Z",
        "level": "info",
        "message": "api server started",
        "attrs": {"socket": "/home/user/.cc-connect/run/api.sock"}
      }
    ]
  }
}

5.2 Projects

GET /api/v1/projects

Lists all projects with a summary.

Response:

{
  "ok": true,
  "data": {
    "projects": [
      {
        "name": "my-backend",
        "agent_type": "claudecode",
        "platforms": ["feishu", "telegram"],
        "sessions_count": 3,
        "heartbeat_enabled": true
      }
    ]
  }
}

GET /api/v1/projects/{name}

Returns detailed information for a single project.

Path parameters:

ParamTypeDescription
namestringProject name

Response:

{
  "ok": true,
  "data": {
    "name": "my-backend",
    "agent_type": "claudecode",
    "platforms": [
      {
        "type": "feishu",
        "connected": true
      },
      {
        "type": "telegram",
        "connected": true
      }
    ],
    "sessions_count": 3,
    "active_session_keys": ["telegram:123:456", "feishu:ou_xxx:chat_xxx"],
    "heartbeat": {
      "enabled": true,
      "paused": false,
      "interval_mins": 30,
      "session_key": "telegram:123:456"
    },
    "settings": {
      "quiet": false,
      "admin_from": "user1,user2",
      "language": "en",
      "disabled_commands": ["restart", "upgrade"]
    }
  }
}

Error (404):

{
  "ok": false,
  "error": "project not found: my-backend"
}

PATCH /api/v1/projects/{name}

Updates project settings. Only provided fields are updated.

Request body:

{
  "quiet": true,
  "admin_from": "user1,user2,user3",
  "language": "zh",
  "disabled_commands": ["restart", "upgrade", "cron"]
}
FieldTypeDescription
quietbooleanSuppress thinking/tool progress messages
admin_fromstringComma-separated user IDs for privileged commands; "*" = all
languagestringUI language: en, zh, zh-TW, ja, es
disabled_commandsstring[]Commands to disable (e.g. restart, upgrade, cron)

Response:

{
  "ok": true,
  "data": {
    "name": "my-backend",
    "settings": {
      "quiet": true,
      "admin_from": "user1,user2,user3",
      "language": "zh",
      "disabled_commands": ["restart", "upgrade", "cron"]
    }
  }
}

5.3 Sessions

Sessions are conversation contexts within a project. A session is identified by a session_key (format: platform:chatId:userId) and optionally by an internal id for named sessions (e.g. /new work creates a named session).

GET /api/v1/projects/{name}/sessions

Lists sessions for a project with summary info including the last message preview.

Response:

{
  "ok": true,
  "data": {
    "sessions": [
      {
        "id": "sess_abc123",
        "session_key": "telegram:123:456",
        "name": "work",
        "platform": "telegram",
        "agent_type": "claudecode",
        "active": true,
        "live": true,
        "history_count": 12,
        "created_at": "2026-03-10T09:00:00Z",
        "updated_at": "2026-03-10T10:30:00Z",
        "last_message": {
          "role": "assistant",
          "content": "Done! The tests are passing now...",
          "timestamp": "2026-03-10T10:30:00Z"
        },
        "user_name": "Alice",
        "chat_name": "dev-channel"
      }
    ],
    "active_keys": {
      "telegram:123:456": "telegram"
    }
  }
}
FieldTypeDescription
activebooleanWhether this is the selected session for its user key
livebooleanWhether there is a running agent process for this session
last_messageobjectPreview of the last message (role, content truncated to 200 chars, timestamp). null if no history.
user_namestringDisplay name of the user (from platform metadata)
chat_namestringName of the chat/channel (from platform metadata)
active_keysobjectMap of session keys with active agent connections → platform name

POST /api/v1/projects/{name}/sessions

Creates a new session.

Request body:

{
  "session_key": "telegram:123:456",
  "name": "work"
}
FieldTypeRequiredDescription
session_keystringyesPlatform routing key (e.g. telegram:123:456)
namestringnoHuman-readable session name

Response:

{
  "ok": true,
  "data": {
    "id": "sess_xyz789",
    "session_key": "telegram:123:456",
    "name": "work",
    "created_at": "2026-03-10T10:35:00Z"
  }
}

GET /api/v1/projects/{name}/sessions/{id}

Returns session detail including message history.

Path parameters:

ParamTypeDescription
namestringProject name
idstringSession ID

Query parameters:

ParamTypeDefaultDescription
history_limitint50Max history entries to return

Response:

{
  "ok": true,
  "data": {
    "id": "sess_abc123",
    "session_key": "telegram:123:456",
    "name": "work",
    "platform": "telegram",
    "agent_type": "claudecode",
    "agent_session_id": "as_xxx",
    "active": true,
    "live": true,
    "history_count": 12,
    "created_at": "2026-03-10T09:00:00Z",
    "updated_at": "2026-03-10T10:30:00Z",
    "history": [
      {
        "role": "user",
        "content": "Hello",
        "timestamp": "2026-03-10T09:00:05Z"
      },
      {
        "role": "assistant",
        "content": "Hi! How can I help?",
        "timestamp": "2026-03-10T09:00:10Z"
      }
    ]
  }
}
FieldTypeDescription
livebooleanWhether the session has an active agent process (can receive messages via /send)

DELETE /api/v1/projects/{name}/sessions/{id}

Deletes a session and its history.

Response:

{
  "ok": true,
  "data": {
    "message": "session deleted"
  }
}

POST /api/v1/projects/{name}/sessions/switch

Switches the active session for a given session_key (e.g. when a user has multiple named sessions).

Request body:

{
  "session_key": "telegram:123:456",
  "session_id": "sess_xyz789"
}
FieldTypeRequiredDescription
session_keystringyesPlatform routing key
session_idstringyesSession ID to make active

Response:

{
  "ok": true,
  "data": {
    "message": "active session switched",
    "active_session_id": "sess_xyz789"
  }
}

POST /api/v1/projects/{name}/send

Sends a message to a session. The message is delivered to the agent as if the user had sent it via the platform. Requires the session to be live (i.e., have an active agent process). Check the live field from session detail to verify before sending.

Request body:

{
  "session_key": "telegram:123:456",
  "message": "Review the latest commit"
}
FieldTypeRequiredDescription
session_keystringyesPlatform routing key
messagestringyesText to send to the agent

Response:

{
  "ok": true,
  "data": {
    "message": "message sent"
  }
}

5.4 Providers

Providers are API backends (e.g. Anthropic, OpenAI, custom endpoints) that supply the AI model for a project's agent.

GET /api/v1/projects/{name}/providers

Lists providers with active indicator.

Response:

{
  "ok": true,
  "data": {
    "providers": [
      {
        "name": "anthropic",
        "active": true,
        "model": "claude-sonnet-4-20250514",
        "base_url": ""
      },
      {
        "name": "relay",
        "active": false,
        "model": "claude-sonnet-4-20250514",
        "base_url": "https://api.relay.example.com"
      }
    ],
    "active_provider": "anthropic"
  }
}

POST /api/v1/projects/{name}/providers

Adds a new provider.

Request body:

{
  "name": "relay",
  "api_key": "sk-xxx",
  "base_url": "https://api.relay.example.com",
  "model": "claude-sonnet-4-20250514",
  "thinking": "disabled",
  "env": {
    "CLAUDE_CODE_USE_BEDROCK": "1",
    "AWS_PROFILE": "bedrock"
  }
}
FieldTypeRequiredDescription
namestringyesProvider identifier
api_keystringno*API key (*required if no env)
base_urlstringnoCustom API endpoint
modelstringnoModel override
thinkingstringno"disabled" for providers without adaptive thinking
envobject (k/v)noExtra environment variables

Response:

{
  "ok": true,
  "data": {
    "name": "relay",
    "message": "provider added"
  }
}

DELETE /api/v1/projects/{name}/providers/{provider}

Removes a provider. The active provider cannot be removed; switch first.

Response:

{
  "ok": true,
  "data": {
    "message": "provider removed"
  }
}

Error (400):

{
  "ok": false,
  "error": "cannot remove active provider; switch to another first"
}

POST /api/v1/projects/{name}/providers/{provider}/activate

Switches the active provider.

Response:

{
  "ok": true,
  "data": {
    "active_provider": "relay",
    "message": "provider activated"
  }
}

GET /api/v1/projects/{name}/models

Lists available models for the project's agent type.

Response:

{
  "ok": true,
  "data": {
    "models": [
      "claude-sonnet-4-20250514",
      "claude-3-5-sonnet-20241022",
      "claude-3-opus-20240229"
    ],
    "current": "claude-sonnet-4-20250514"
  }
}

POST /api/v1/projects/{name}/model

Sets the model for the project.

Request body:

{
  "model": "claude-3-5-sonnet-20241022"
}

Response:

{
  "ok": true,
  "data": {
    "model": "claude-3-5-sonnet-20241022",
    "message": "model updated"
  }
}

5.5 Cron Jobs

GET /api/v1/cron

Lists all cron jobs, optionally filtered by project.

Query parameters:

ParamTypeDescription
projectstringFilter by project

Response:

{
  "ok": true,
  "data": {
    "jobs": [
      {
        "id": "cron_abc123",
        "project": "my-backend",
        "session_key": "telegram:123:456",
        "cron_expr": "0 6 * * *",
        "prompt": "Summarize GitHub trending",
        "exec": "",
        "work_dir": "",
        "description": "Daily GitHub Trending",
        "enabled": true,
        "silent": true,
        "created_at": "2026-03-10T08:00:00Z",
        "last_run": "2026-03-10T06:00:00Z",
        "last_error": ""
      }
    ]
  }
}

POST /api/v1/cron

Adds a cron job. Either prompt or exec must be provided, not both.

Request body (prompt job):

{
  "project": "my-backend",
  "session_key": "telegram:123:456",
  "cron_expr": "0 6 * * *",
  "prompt": "Summarize GitHub trending",
  "description": "Daily GitHub Trending",
  "silent": true
}

Request body (exec job):

{
  "project": "my-backend",
  "session_key": "telegram:123:456",
  "cron_expr": "0 9 * * 1",
  "exec": "npm run weekly-report",
  "work_dir": "/path/to/project",
  "description": "Weekly Report",
  "silent": false
}
FieldTypeRequiredDescription
projectstringno*Project name (*required if multiple projects)
session_keystringyesTarget session for prompt jobs
cron_exprstringyesCron expression (5 or 6 fields)
promptstringno*Prompt to send (*required if no exec)
execstringno*Shell command (*required if no prompt)
work_dirstringnoWorking directory for exec
descriptionstringnoHuman-readable label
silentbooleannoSuppress start notification
session_modestringnoreuse (default) or new_per_run — new agent session each run
timeout_minsintnoScheduler wait per run: omit = 30 min, 0 = no time limit

Response:

{
  "ok": true,
  "data": {
    "id": "cron_xyz789",
    "project": "my-backend",
    "session_key": "telegram:123:456",
    "cron_expr": "0 6 * * *",
    "prompt": "Summarize GitHub trending",
    "description": "Daily GitHub Trending",
    "enabled": true,
    "created_at": "2026-03-10T10:40:00Z"
  }
}

DELETE /api/v1/cron/{id}

Deletes a cron job.

Response:

{
  "ok": true,
  "data": {
    "message": "cron job deleted"
  }
}

POST /api/v1/cron/{id}/exec

Triggers an existing cron job immediately. Disabled jobs can still be triggered manually. /api/v1/cron/{id}/run is accepted as a compatibility alias.

Response:

{
  "ok": true,
  "data": {
    "id": "cron_xyz789",
    "status": "triggered"
  }
}

5.6 Heartbeat

Heartbeat runs periodic prompts in a session (e.g. "check inbox") to keep the agent aware of the environment.

GET /api/v1/projects/{name}/heartbeat

Returns heartbeat status.

Response:

{
  "ok": true,
  "data": {
    "enabled": true,
    "paused": false,
    "interval_mins": 30,
    "only_when_idle": true,
    "session_key": "telegram:123:456",
    "silent": true,
    "run_count": 42,
    "error_count": 0,
    "skipped_busy": 5,
    "last_run": "2026-03-10T10:00:00Z",
    "last_error": ""
  }
}

POST /api/v1/projects/{name}/heartbeat/pause

Pauses heartbeat.

Response:

{
  "ok": true,
  "data": {
    "message": "heartbeat paused"
  }
}

POST /api/v1/projects/{name}/heartbeat/resume

Resumes heartbeat.

Response:

{
  "ok": true,
  "data": {
    "message": "heartbeat resumed"
  }
}

POST /api/v1/projects/{name}/heartbeat/run

Triggers heartbeat immediately (one-shot).

Response:

{
  "ok": true,
  "data": {
    "message": "heartbeat triggered"
  }
}

POST /api/v1/projects/{name}/heartbeat/interval

Sets the heartbeat interval.

Request body:

{
  "minutes": 15
}

Response:

{
  "ok": true,
  "data": {
    "interval_mins": 15,
    "message": "interval updated"
  }
}

5.7 Bridge

GET /api/v1/bridge/adapters

Lists connected bridge adapters (external platforms via WebSocket).

Response:

{
  "ok": true,
  "data": {
    "adapters": [
      {
        "platform": "custom",
        "project": "my-backend",
        "capabilities": ["text", "images", "files"],
        "connected_at": "2026-03-10T09:00:00Z"
      }
    ]
  }
}

6. Error Handling Conventions

6.1 Standard Error Response

All errors use the same envelope:

{
  "ok": false,
  "error": "human-readable message"
}

6.2 Common Errors

HTTPError message exampleCause
400"project is required (multiple projects)"Missing required parameter
400"either prompt or exec is required"Invalid cron job body
401"unauthorized: missing or invalid token"Auth failure
404"project not found: xyz"Unknown project/session/cron
404"session not found"Unknown session ID
405"method not allowed"Wrong HTTP method
500"internal error"Unexpected server error

6.3 Validation Errors

When request body validation fails:

{
  "ok": false,
  "error": "invalid request: session_key is required"
}

7. Session Key Format

The session_key is a composite identifier used to route messages to the correct platform and chat:

<platform>:<chat_id>:<user_id>

Examples:

  • telegram:123456789:123456789 — Telegram user 123456789 in chat 123456789
  • feishu:ou_xxx:chat_yyy — Feishu user in chat
  • slack:C01234:U05678 — Slack channel and user
  • discord:123456789:987654321 — Discord guild and user

For multi-workspace mode, the format may include a workspace prefix:

<workspace>:<platform>:<chat_id>:<user_id>

8. CORS

When the Management API is used by web dashboards, CORS headers should be configurable. A suggested config extension:

[management]
enabled = true
port = 9820
token = "mgmt-secret"
cors_origins = ["http://localhost:3000", "https://dashboard.example.com"]

If not configured, CORS may be disabled or use a default (e.g. * for same-origin only).


9. Changelog

VersionDateChanges
1.1-draft2026-03-24Enrich session list/detail with live, last_message, agent_type, user_name, chat_name, active_keys fields
1.0-draft2026-03-10Initial specification

10. References