HTTP API

The daemon exposes the same surface over HTTP that it does over the Unix socket. The HTTP gateway is suitable for browser-facing UIs and third-party tooling that cannot speak length-prefixed JSON IPC. Listening address is 127.0.0.1:8421 (loopback only) by default; override the port with the COVENANT_HTTP_PORT environment variable.

Conventions

  • Request bodies are JSON; responses are JSON.
  • Validation-level conditions (missing capability, no agent matched) return 200 OK with { "kind": "error", "message": "…" }, matching IPC behavior so that callers parse a single response shape.
  • Internal errors (panic, I/O fault) return 500 Internal Server Error with { "error": "…" }.
  • CORS uses an explicit origin allow-list. Default is http://localhost:3000; override with COVENANT_HTTP_ORIGINS.

Routes

Health

GET /health
→ 200 { "status": "ok" }

GET /version
→ 200 {
    "kind": "protocol_info",
    "info": {
      "protocol": "covenant.ipc",
      "version": 1,
      "min_supported": 1,
      "max_supported": 1
    }
  }

/version mirrors the unauthenticated protocol_info IPC probe. The response is intentionally minimal and stable for protocol version 1; adding required fields implies a protocol version bump.

Intents

POST /intent
Content-Type: application/json
Body: { "text": "summarise recent work on agent memory" }

→ 200 {
    "kind": "intent_result",
    "intent_id": "…",
    "status": "ok",
    "text": "…",
    "sources": ["…"],
    "settlement": null
  }

Memory

GET /memory/recent?tier=working&limit=10
GET /memory/search?q=agent+memory&tier=longterm&limit=5
POST /memory/purge
  Body: { "tier": "working", "before_ms": 1714938000000 }

→ 200 { "kind": "memories", "records": [ ... ] }
   or  { "kind": "memory_purged", "purged": 42 }

Receipts

GET /receipts/recent?limit=10
→ 200 { "kind": "receipts", "receipts": [ ... ] }

Capabilities

GET /capabilities/recent?limit=10
POST /capabilities/grant
  Body: {
    "action": "tool.web_search",
    "scope": null,
    "expires_at": null
  }
POST /capabilities/revoke
  Body: { "signature_b58": "4qXP…" }

→ 200 {
    "kind": "capability_granted",
    "signature_b58": "…",
    "subject_display": "user@local",
    "action": "tool.web_search"
  }
   or  { "kind": "capability_revoked", "signature_b58": "…", "removed": true }

Verify

GET /verify?window=100
→ 200 {
    "kind": "verify_report",
    "window": 100,
    "checks": [
      { "name": "memory ↔ audit",     "passed": true,  "message": "…" },
      { "name": "memory parent references", "passed": true, "message": "…" },
      { "name": "capability ↔ audit", "passed": true,  "message": "…" },
      { "name": "memory ↔ receipts",  "passed": true,  "message": "…" }
    ],
    "drift": [
      {
        "kind": "memory_stale_parent",
        "id": "uuid",
        "message": "…",
        "repair": "…"
      }
    ],
    "orphans_total": 0
  }

Tools

GET /tools
POST /tools/call
  Body: { "name": "echo", "arguments": { "text": "hi" } }

→ 200 { "kind": "tool_list", "tools": [ ... ] }
   or  { "kind": "tool_result", "content": [ ... ], "is_error": false }

Audit

GET /audit/recent?limit=20
→ 200 { "kind": "audit_events", "events": [ ... ] }

GET /audit/verify
→ 200 {
    "kind": "audit_integrity",
    "report": {
      "events": 42,
      "anchors": 42,
      "valid": true,
      "root_hash_hex": "…",
      "failures": []
    }
  }

Agent-to-agent

POST /a2a/tasks                   # body: A2ATask JSON
GET  /a2a/tasks/next              # leases the next queued task
GET  /a2a/tasks/recent?limit=N    # non-consuming snapshot

POST /a2a/results                 # body: A2ATaskResult JSON
GET  /a2a/results/next            # drains the next queued result
GET  /a2a/results/recent?limit=N  # non-consuming snapshot
GET  /a2a/queue?limit=N           # queued tasks, in-flight leases, pending results

Write paths (POST) require capability tokens — see Agent-to-agent for the exact actions.

Authentication

Every route except /health and /version requires Authorization: Bearer <token>. The token must resolve to a live peer in the daemon registry, matching the Unix-socket authentication model. The gateway still binds to loopback by default and should not be exposed directly to an untrusted network.

Related

  • CLI — same surface, but talking to the Unix socket.
  • Local IPC — the wire protocol on the Unix socket.
  • Security model — what the loopback-only assumption costs you.