CovenDocs

Coven local API

The supported HTTP contract over same-user local IPC.

6 min read

The daemon serves /api/v1 over same-user local IPC: $COVEN_HOME/coven.sock on Unix-like hosts or an owner-only named pipe selected by COVEN_HOME on Windows. Use the endpoint reported by health or coven daemon status; do not construct a Windows pipe name from the Unix convention.

Use the API from a same-user local client when the CLI does not fit your workflow. Start with the health response, branch on its advertised capabilities, and treat structured errors as product behavior. Capabilities advertise availability, not authorization.

These details describe the current versioned source contract. Older installed builds may omit newer optional capabilities; negotiate with the running daemon rather than treating this page as proof that an upgrade has reached it.

Supported flow

  1. GET /api/v1/health — verify reachability and API compatibility.
  2. GET /api/v1/capabilities — discover available route families and action ids.
  3. POST /api/v1/sessions — launch a validated harness session.
  4. GET /api/v1/sessions and GET /api/v1/sessions/{id} — inspect records.
  5. GET /api/v1/events — read ordered session events with a cursor.
  6. POST /api/v1/actions — request a validated control action with the action id in the top-level JSON action field.

Error envelope

The daemon rejects malformed requests, unknown sessions, non-live input, unsupported harnesses, and project-root violations with a structured error envelope:

{
  "error": {
    "code": "invalid_request",
    "message": "cwd is outside the Coven project root"
  }
}

For a working directory outside the project root, the emitted code is invalid_request; project_root_violation is reserved, not the current wire code for that rejection. Do not depend on the message text as a stable subtype.

Use error.code for control flow; display message to people. The complete endpoint schemas and local examples are in the interactive API reference.

Session-policy admission

coven.session-policy.v1 is a separately negotiated contract for restricted launches. This version is refusal-only: no enforcement backend exists, so it never launches a session, issues a receipt, or grants a profile.

  • GET /api/v1/session-policy is inert discovery. It reports "enforcement": "unavailable" and an empty supportedProfiles list.
  • POST /api/v1/sessions/restricted requires local IPC; TCP returns 403 forbidden. A valid request returns HTTP 409 with "decision": "rejected", "code": "enforcement_unavailable", and "admission": "not_started". This closed refusal is not the generic error envelope, and it is never a launch success.
  • Health lists coven.session-policy.v1 in sessionPolicyContracts over local IPC and returns [] over TCP. Older daemons omit the field; treat absence as unavailable.
  • POST /api/v1/sessions rejects any top-level sessionPolicy member, including null, with 400 invalid_request.

Never retry a restricted request as an ordinary launch, and do not infer not_started from a timeout, a disconnect, or a generic error. Other 409 responses are ordinary structured errors, such as session_policy_expired on the restricted route or session_not_live on session input, so the status alone does not identify a policy refusal. The closed request schema, size limits, and digest rules are in the session-policy specification.

A contract name in health establishes availability, not authorization. It is not an enforcement profile, identity proof, or grant.

Ordinary-chat context admission

Ordinary-chat context admission is not enabled. Owner-local POST /api/v1/sessions and POST /api/v1/sessions/{sessionId}/input validate an explicit contextAdmission intent and refuse execution while trusted embodiment verification and native context-profile qualification are absent. Valid unverified requests receive 503 with accepted: false and receiptIssued: false; other mutations reject the member rather than dispatching an unbound session. Requests without it keep their existing behavior.

Do not remove a refused contextAdmission member and retry as an ordinary launch or input. This intent is separate from session-policy admission, executionBinding, and requestAdoption; it advertises no new capability. See the ordinary-chat context contract.

Action router

The action router accepts a top-level action string plus optional origin and intentId correlation fields. Action-specific fields are also top-level; there is no generic args wrapper in the current daemon implementation. Correlation fields do not grant authority.

{
  "action": "coven.automations.health",
  "origin": "local-maintainer-tool",
  "intentId": "inspect-daily-notes-1",
  "id": "daily-notes"
}

Call /capabilities before invoking an action. The currently advertised stable action groups include coven.capabilities.refresh and the coven.automations.* actions documented in Coven automations.

A successful action returns ok: true, accepted: true, and status: "completed", with its data in event.payload or, for versioned automation actions, a top-level result. A failed action returns ok: false, accepted: false, status: "rejected", and the cause in reason; versioned automation actions add a typed error whose code sets the HTTP status. Malformed JSON and missing action ids return HTTP 400. Over the optional loopback TCP listener, every coven.automations.* action outside the diagnostic allowlist returns 403 with AUTHORITY_REQUIRED before action validation, including unknown automation action ids. These actions require the owner-local IPC endpoint. Other unknown action ids return 400.

Control-plane surface map

The generated OpenAPI reference covers the stable public coven.daemon.v1 subset: handshake, capabilities, sessions, events, and actions. The daemon also exposes first-party route families used by OpenCoven applications. Those broader routes can evolve without a named-contract version bump and are intentionally not presented as public stable API.

Treat a route as stable only when it appears in the versioned source contract and the generated API Reference. For every other route, use capability discovery and the owning first-party client's contract instead of copying an implementation detail into an external integration.

Version and privacy rules

GET /api/v1/health advertises the named coven.daemon.v1 contract. Its covenVersion field is an opaque daemon build identity. Source builds may include a git describe distance, commit, or -dirty suffix; an unresolved version is unknown. Negotiate compatibility using apiVersion and the capabilities required for the operation. GET /api/v1/api-version is a legacy route-family diagnostic; its literal v1 value is not sufficient proof that every named-contract capability exists.

Broad event and log responses are redacted by default. Raw sensitive artifacts are available only through the narrow GET /api/v1/sessions/{sessionId}/artifacts/{artifactId}?raw=1 route when raw artifact persistence is explicitly enabled. Otherwise the daemon returns a structured raw_artifact_requires_raw_flag or raw_artifacts_disabled error.

Rust client and peer replacement

For Rust integrations, prefer opencoven-coven-client (library coven_client) to composing HTTP over a hand-built socket or pipe path. Construct the endpoint with DaemonEndpoint::discover(coven_home), then pass it to DaemonClient::new. The public client accepts no arbitrary URLs or endpoint paths, bounds response bodies to 4 MiB, and negotiates health before dependent operations. The crate lives in the OpenCoven/coven workspace; its crates.io release is gated on a signed coven-client-v* tag, so confirm a version is published before you add it as a registry dependency.

Its negotiation is bound to the transport peer. If the daemon endpoint is replaced, the next dependent operation fails before sending request bytes and clears the cached negotiation. Call health again, re-check capabilities, and then decide whether a retry is appropriate. The client never replays a mutation automatically.

Client rules

  • Send requests only to the daemon-reported same-user local IPC endpoint.
  • Do not treat the optional loopback TCP listener as owner access; it refuses owner-only operations with 403. See Optional loopback TCP.
  • Check health and capabilities before assuming a route or action exists.
  • Put action-specific fields at the top level and validate action payload results.
  • Never treat a client-side check as a substitute for daemon validation.
  • Keep provider credentials in the harness, not in API requests or automation definitions.

See Daemon for operating behavior, Safety for the enforcement model, and the versioned source contract for normative request and response shapes.

Was this page helpful?No

Last updated on