The public API is served by the control plane under:Documentation Index
Fetch the complete documentation index at: https://docs.acornops.dev/llms.txt
Use this file to discover all available pages before exploring further.
/api to the control plane so browser auth callbacks and session cookies stay on https://console.acornops.dev. Runtime traffic between platform services uses separate internal credentials and should stay on private network paths.
If you are building a bot, workflow adapter, or custom client, start with Integrations for the supported auth and event patterns before wiring endpoint calls.
Auth model
The browser API uses aSameSite=Lax session cookie. Mutating requests that carry a session cookie must also send the CSRF token in x-csrf-token; password login, signup, email verification, verification resend, forgot password, and reset password require the same CSRF token before a session exists. Runtime service-to-service calls use separate bearer tokens and are not part of the public browser API.
Default production installs support OIDC plus username/password login, with self-service signup disabled and password reset enabled. When self-service password signup is enabled, email verification is required unless an operator explicitly allows unverified signup for a private deployment. The management console reads runtime auth configuration before rendering sign-in controls.
Auth
| Flow | Endpoint |
|---|---|
| Runtime auth config | GET /api/v1/auth/config |
| CSRF token | GET /api/v1/auth/csrf |
| OIDC login | GET /api/v1/auth/oidc/login?return_to=<management-console-url> |
| OIDC callback | GET /api/v1/auth/oidc/callback |
| Link OIDC method | POST /api/v1/auth/oidc/link/start |
| Password login | POST /api/v1/auth/password/login |
| Password signup | POST /api/v1/auth/password/signup |
| Password email verification | POST /api/v1/auth/password/verify-email |
| Password verification resend | POST /api/v1/auth/password/resend-verification |
| Password reset request | POST /api/v1/auth/password/forgot |
| Password reset completion | POST /api/v1/auth/password/reset |
| Password change | POST /api/v1/auth/password/change |
| Logout | POST /api/v1/auth/logout |
| Current user | GET /api/v1/me |
| Current auth methods | GET /api/v1/auth/methods |
| JWKS for gateway validation | GET /api/v1/auth/jwks.json |
GET /api/v1/auth/config returns oidcEnabled, oidcProviderName, passwordAuthEnabled, passwordSignupEnabled, passwordEmailVerificationRequired, and passwordResetEnabled. Password signup returns either an immediate session or verification_required; pending password accounts cannot sign in until POST /api/v1/auth/password/verify-email consumes a valid single-use token. Expired or invalid verification links can request POST /api/v1/auth/password/resend-verification, which returns enumeration-safe copy for unknown, verified, and pending accounts. Forgot password uses POST /api/v1/auth/password/forgot with the same enumeration-safe response shape for syntactically valid email addresses; POST /api/v1/auth/password/reset consumes a valid single-use reset token, updates the password, verifies the email, revokes existing sessions, and does not create a new session. Dev-login is mounted only outside production.
For default production settings, the OIDC callback URL registered with the provider is https://console.acornops.dev/api/v1/auth/oidc/callback. If the deployment overrides the redirect URI, register the exact override value.
Workspaces and members
Workspaces group members, targets, Kubernetes clusters, VMs, sessions, runs, tools, MCP servers, and webhooks. Common workspace endpoints:GET /api/v1/workspacesPOST /api/v1/workspacesGET /api/v1/workspaces/{workspaceId}DELETE /api/v1/workspaces/{workspaceId}GET /api/v1/workspaces/{workspaceId}/rolesGET /api/v1/workspaces/{workspaceId}/membersGET /api/v1/workspaces/{workspaceId}/audit-logPOST /api/v1/workspaces/{workspaceId}/membersPATCH /api/v1/workspaces/{workspaceId}/members/{userId}DELETE /api/v1/workspaces/{workspaceId}/members/{userId}GET /api/v1/workspaces/{workspaceId}/invitationsPOST /api/v1/workspaces/{workspaceId}/invitationsDELETE /api/v1/workspaces/{workspaceId}/invitations/{invitationId}GET /api/v1/workspace-invitations/{token}POST /api/v1/workspace-invitations/{token}/accept
GET /api/v1/workspaces/{workspaceId}/audit-log requires audit-log read permission and returns cursor-paged workspace audit events. Each event includes operation, with value read or write, so consumers can distinguish retained read events from mutating events. The endpoint accepts optional category, eventType, actorUserId, targetType, from, and to filters; invalid category, blank string filters, invalid date filters, or inverted date ranges return 400 VALIDATION_ERROR instead of widening the result set. Audit metadata is sanitized before persistence and must not expose raw tokens, secrets, message bodies, pod logs, auth headers, or full tool arguments.
Workspace summary responses redact operational counts when the role lacks workspace-data read permission. Auditors can see member context, but receive clusterCount: 0.
Roles
The deployment owns the supported workspace role templates.owner is always supported, protected, and required for every workspace. Operators may enable or disable other built-in templates and add custom templates with supported workspace capabilities.
Built-in templates include owner, admin, operator, viewer, and auditor. Custom role keys are lowercase snake_case API identifiers. Membership and invitation role keys must exist in the deployment-supported catalog. Unsupported role keys return ROLE_NOT_SUPPORTED; attempts by non-owners to assign protected roles return PROTECTED_ROLE_REQUIRES_OWNER; owner removal or demotion that would leave no owner returns LAST_OWNER.
GET /api/v1/workspaces/{workspaceId}/roles returns a read-only catalog with key, displayName, description, kind, capabilities, protected, and sortOrder. Workspace summaries may include currentUserRoleTemplate; member and invitation payloads may include roleTemplate.
Workspace and catalog responses include server-owned permission fields. Clients should use those fields rather than copying role or capability logic.
Targets, clusters, VMs, and inventory
Target, cluster, and VM endpoints:GET /api/v1/workspaces/{workspaceId}/targetsGET /api/v1/workspaces/{workspaceId}/targets/{targetId}GET /api/v1/workspaces/{workspaceId}/kubernetes-clustersGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}POST /api/v1/workspaces/{workspaceId}/kubernetes-clustersPATCH /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}DELETE /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}POST /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/rotate-agent-keyGET /api/v1/workspaces/{workspaceId}/investigationsGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/resourcesGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/findingsGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/metrics/history?clusterIds=<comma-separated-cluster-ids>GET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/metrics/historyGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/pods/{namespace}/{podName}/logsGET /api/v1/workspaces/{workspaceId}/virtual-machinesPOST /api/v1/workspaces/{workspaceId}/virtual-machinesGET /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}PATCH /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}DELETE /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}POST /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}/rotate-agent-keyGET /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}/resourcesGET /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}/findingsGET /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}/metrics/historyGET /api/v1/workspaces/{workspaceId}/virtual-machines/{vmId}/logs
GET /api/v1/workspaces/{workspaceId}/targets accepts optional q, limit, cursor, and targetType query parameters. targetType must be kubernetes or virtual_machine; invalid values return 400 VALIDATION_ERROR.
Registration returns the cluster or VM, a one-time agent key, and install instructions. Agent-key rotation returns a replacement key and updated install instructions.
Cluster list responses are summary-only. Historical CPU and memory telemetry is fetched lazily through the single-cluster or bounded batch metric-history endpoints. VM snapshots populate host resources, findings, and metrics history; VM logs are fetched live through the connected VM agent.
Sessions and runs
Session and run endpoints:POST /api/v1/workspaces/{workspaceId}/targets/{targetId}/sessionsGET /api/v1/workspaces/{workspaceId}/targets/{targetId}/sessionsGET /api/v1/workspaces/{workspaceId}/targets/{targetId}/chat-activityPOST /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/sessionsGET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/sessionsGET /api/v1/sessions/{sessionId}DELETE /api/v1/sessions/{sessionId}GET /api/v1/sessions/{sessionId}/messagesPOST /api/v1/sessions/{sessionId}/messagesGET /api/v1/runs/{runId}GET /api/v1/runs/{runId}/eventsGET /api/v1/runs/{runId}/streamGET /api/v1/runs/{runId}/approvalsPOST /api/v1/runs/{runId}/approvals/{approvalId}/decisionPOST /api/v1/runs/{runId}/cancel
content, toolAccessMode, and clientMessageId, then returns message_id and run_id.
Only the user who created a conversation can post follow-up messages in that conversation. Other users with target read access can read the conversation and watch active runs, but POST /api/v1/sessions/{sessionId}/messages returns 403 CONVERSATION_OWNER_REQUIRED for non-owners.
Run creation is available for Kubernetes and virtual machine targets. VM runs must be read-only.
Session payloads include targetId, targetType, createdBy, and optional createdByUser.{id,displayName}. Kubernetes session payloads also include clusterId, which is the same backing target ID.
Run details and approval replay payloads include targetId and targetType. Kubernetes payloads also include clusterId; non-Kubernetes targets do not receive a synthetic cluster alias.
GET /api/v1/workspaces/{workspaceId}/targets/{targetId}/chat-activity?windowSeconds=300 returns recent target chat activity for non-deleted, non-expired sessions. It requires target read access, not session creation permission. The response includes target metadata, windowSeconds, generatedAt, and recentActivity[] rows with owner display metadata, last activity time, latest run metadata, active run metadata, and a hasRecentWriteCapableRun flag.
Run events are replayable through the events endpoint and streamable through server-sent events. Events include a sequence number, timestamp, type, and payload. Current event types include run lifecycle, assistant message, token delta, tool-call, write approval, failure, cancellation, and completion events.
Write approval decisions use:
Tools and MCP servers
Tool catalog endpoints:GET /api/v1/workspaces/{workspaceId}/targets/{targetId}/tools/catalogPATCH /api/v1/workspaces/{workspaceId}/targets/{targetId}/tools/{toolName}GET /api/v1/workspaces/{workspaceId}/kubernetes-clusters/{clusterId}/tools/catalog
GET /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/serversGET /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/servers/{serverId}/toolsPOST /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/serversPATCH /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/servers/{serverId}DELETE /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/servers/{serverId}POST /api/v1/workspaces/{workspaceId}/targets/{targetId}/mcp/servers/{serverId}/test-connection
tools/list, then calls tools with tools/call during authorized runs.
Create and update requests use top-level publicHeaders for non-secret metadata:
staticHeaders has been removed from the public API. Credential-like public headers are rejected, and platform headers such as x-workspace-id, x-target-id, x-target-type, x-run-id, and x-tool-name are reserved. See MCP and tools for the full header policy.
Webhooks
Webhook management endpoints:GET /api/v1/workspaces/{workspaceId}/webhooksPOST /api/v1/workspaces/{workspaceId}/webhooksGET /api/v1/workspaces/{workspaceId}/webhooks/{webhookId}PATCH /api/v1/workspaces/{workspaceId}/webhooks/{webhookId}DELETE /api/v1/workspaces/{workspaceId}/webhooks/{webhookId}GET /api/v1/workspaces/{workspaceId}/webhooks/{webhookId}/history(requirespermissions.manage_webhooks)
AcornOps-Event-IdAcornOps-Event-TypeAcornOps-TimestampAcornOps-Signature
targetId for target-scoped subscriptions. Omit it or send null for workspace-wide delivery.
Target-scoped deliveries include targetId and targetType. Kubernetes-scoped deliveries also include clusterId, which is the same backing target ID for Kubernetes clusters.
The signature input is timestamp + "." + raw_json_body, signed with HMAC-SHA256 and encoded as v1=<hex>.
Write approval webhook events include:
run.tool_approval_requested.v1run.tool_approval_decided.v1