API & CLI reference

Everything the REST server exposes, the shapes it returns, and the CLI commands. The server listens on port 8080 by default.

Authentication

Set API_AUTH_TOKEN and the server requires Authorization: Bearer <token> on POST /tasks, GET /tasks/history, GET /metrics, and all /approvals endpoints. Health, skills, and interoperability endpoints stay open. When the token is unset the server runs open and logs a warning — acceptable only for local development.

Endpoints

MethodPathAuthDescription
GET/healthopenStatus, version, skills loaded, LLM provider.
GET/readyzopenReadiness: true once skills are loaded.
GET/skillsopenLoaded skill details.
GET/skills/portableopenPortable manifests for all enabled skills.
GET/skills/portable/{name}openFull portable manifest for one skill (includes prompts).
GET/interopopenAgent interoperability manifest.
GET/.well-known/agent-manifest.jsonopenSame manifest at a discoverable path.
GET/metricsbearerPrometheus metrics.
GET/tasks/history?limit=bearerRecent task summaries (in-memory, capped at 1000).
POST/tasksbearerSubmit a task.
GET/approvals?status=bearerList approval requests, optionally filtered by status.
POST/approvals/{id}/approvebearerApprove a pending request.
POST/approvals/{id}/denybearerDeny a pending request.
POST/webhookHMACSubmit a task from an external system; requires a valid signature.

POST /tasks

curl -s -X POST localhost:8080/tasks \
  -H "Authorization: Bearer $API_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Why is the checkout deployment crash-looping?",
    "namespace": "shop",
    "user": "alice",
    "reflect": false,
    "metadata": {}
  }'

Only prompt is required. The response:

{
  "task_id": "0b0e7f6a-…",
  "answer": "…",
  "risk_level": "low",
  "elapsed_ms": 12874,
  "attempts": 1
}

risk_level is the highest safety-assessed risk of any command the task attempted — low, medium, high, or critical — whether or not the command was executed. Requests beyond the concurrency limit (SAFETY_MAX_CONCURRENT_TASKS, default 5) receive 429.

Approvals

curl -s -H "Authorization: Bearer $API_AUTH_TOKEN" \
  "localhost:8080/approvals?status=pending"

Each request has an id, the exact command, the tool, a reason, a risk level, a status (pending, approved, denied, consumed, expired), and decision metadata. Decide with:

curl -s -X POST "localhost:8080/approvals/<approval-id>/approve" \
  -H "Authorization: Bearer $API_AUTH_TOKEN" \
  -H "X-Kopilot-Operator: alice"

The optional X-Kopilot-Operator header records who decided, in both the approval record and the audit log. Approvals are single-use, match the exact (whitespace-normalized) command, and expire 10 minutes after creation or approval. The store is in-memory and per-replica.

POST /webhook

Webhooks let external systems (alerting, ticketing) submit tasks. The endpoint is disabled (403) until API_WEBHOOK_SECRET is set, and every request must carry an HMAC-SHA256 signature of the raw body in X-Kopilot-Signature:

BODY='{"source":"alertmanager","payload":{"prompt":"Investigate failing pods in team-a"}}'
SIG="sha256=$(printf '%s' "$BODY" \
  | openssl dgst -sha256 -hmac "$API_WEBHOOK_SECRET" \
  | awk '{print $NF}')"

curl -s -X POST localhost:8080/webhook \
  -H "Content-Type: application/json" \
  -H "X-Kopilot-Signature: $SIG" \
  -d "$BODY"

The payload needs a source and a payload object containing a prompt (or description).

GET /metrics

Prometheus metrics exposed (gauges and counters; there are no histograms):

CLI

CommandDescription
kopilot serveFull agent: REST API + operator + event watcher + Slack bot. Flags: --host, --port.
kopilot apiREST API only. Flags: --host, --port.
kopilot operatorKopf operator only.
kopilot ask "<prompt>"One-shot task from the terminal.
kopilot mcpMCP server. Flags: --transport stdio|sse|streamable-http, --host, --port.

kubedevaiops is an alias for kopilot; both entry points are installed.