Skip to main content

HTTP API

All endpoints listen on 127.0.0.1:<port> only. The port is normally 7777, falling back to the next free port if taken — read ~/.local/state/ccmon/port for the current value.

MethodPathUsed byNotes
GET/healthzdoctor / liveness{ok, version, uptime_s}
POST/eventccmon-event hookfire-and-forget; returns 204
POST/approvalccmon-approve hookblocks ≤540 s, returns decision JSON
GET/sessions[?include_ended=1]CLI / UIsnapshot of all sessions
GET/events?after_id=N&limit=M&order=desc&session_id=…CLI tailevent log
GET/approvalsCLI / UIlist pending
POST/approvals/{request_id}/decisionCLI / UIresolve a pending approval
GET/sessions/{id}/summaryCLIcached summary read
POST/sessions/{id}/summary[?force=1]CLIrefresh long summary
GET/wsdesktop UIWebSocket — see WebSocket

Hook endpoints

The daemon exposes two endpoints that only the hook scripts call:

  • POST /event — non-blocking. The ccmon-event script POSTs hook payloads (SessionStart, PreToolUse, …) and returns immediately.
  • POST /approval — blocking. The ccmon-approve script POSTs a permission request and blocks for up to 540 s (9 minutes) waiting for a decision. If no decision arrives, the daemon returns ask so the in-terminal prompt fires.

You don't normally call these yourself.

Reading sessions

curl http://127.0.0.1:7777/sessions | jq
curl 'http://127.0.0.1:7777/sessions?include_ended=1' | jq

Returns a snapshot of every session ccmon is tracking, with state, project, branch, last activity, and counts.

Reading events

curl 'http://127.0.0.1:7777/events?limit=20&order=desc' | jq
curl 'http://127.0.0.1:7777/events?session_id=abc12345&after_id=1000' | jq

/events is the source of truth for the timeline — every hook event the daemon has seen, in insertion order.

Approvals

# List pending:
curl http://127.0.0.1:7777/approvals | jq

# Approve:
curl -X POST -H 'content-type: application/json' \
-d '{"decision":"allow"}' \
http://127.0.0.1:7777/approvals/abc12345/decision

# Deny with message:
curl -X POST -H 'content-type: application/json' \
-d '{"decision":"deny","message":"writes outside project","interrupt":true}' \
http://127.0.0.1:7777/approvals/abc12345/decision

Summaries

GET /sessions/{id}/summary returns the cached summary, if any. POST /sessions/{id}/summary?force=1 triggers a fresh claude -p call (rate-limited to 2 concurrent across the daemon).

WebSocket vs. HTTP

The HTTP read endpoints stay around for the CLI and curl-style debugging. The desktop UI talks only the WebSocket protocol — see WebSocket.