openapi: 3.1.0
info:
title: Harn Agents Protocol API
version: agents-protocol-2026-04-25
summary: OpenAPI description for the Harn Agents Protocol v1 REST surface.
description: |
Machine-readable REST and SSE contract for managed Harn agents. The
narrative protocol requirements live in `spec/AGENTS_PROTOCOL.md`; this
document fixes the v1 paths, request bodies, response envelopes, and
resource schemas used by SDKs and conformance fixtures.
license:
name: Apache-2.0
url: https://www.apache.org/licenses/LICENSE-2.0
contact:
name: Burin Labs
url: https://github.com/burin-labs/harn
externalDocs:
description: Harn Agents Protocol v1 narrative specification.
url: https://harnlang.com/spec/agents-protocol/v1
servers:
- url: https://api.harnlang.com
description: Harn Cloud production API.
- url: http://localhost:8080
description: Local Harness development server.
security:
- bearerAuth: []
tags:
- name: Discovery
- name: Runtime
- name: Tools
- name: Personas
- name: Workspaces
- name: Sessions
- name: Tasks
- name: Branches
- name: Messages
- name: Artifacts
- name: Events
- name: Receipts
- name: Memories
- name: Vaults
- name: Connectors
- name: Skills
- name: Outcomes
- name: Quotas
- name: Permissions
paths:
/health:
get:
tags: [Runtime]
operationId: getHealth
summary: Check local server health.
security: []
responses:
"200":
description: Health status.
content:
application/json:
schema:
$ref: "#/components/schemas/Health"
default:
$ref: "#/components/responses/Error"
/version:
get:
tags: [Runtime]
operationId: getVersion
summary: Read Harn runtime and local API protocol versions.
security: []
responses:
"200":
description: Version metadata.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeVersion"
default:
$ref: "#/components/responses/Error"
/openapi.json:
get:
tags: [Discovery]
operationId: getOpenApiDocument
summary: Retrieve this OpenAPI document as JSON.
security: []
responses:
"200":
description: OpenAPI 3.1 document.
content:
application/json:
schema:
type: object
additionalProperties: true
default:
$ref: "#/components/responses/Error"
/v1:
get:
tags: [Discovery]
operationId: getProtocolDiscovery
summary: Discover supported protocol versions and capabilities.
security: []
responses:
"200":
description: Discovery metadata.
content:
application/json:
schema:
$ref: "#/components/schemas/Discovery"
default:
$ref: "#/components/responses/Error"
/v1/runtime:
get:
tags: [Runtime]
operationId: getRuntime
summary: Inspect the local Harn runtime serving this API.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
responses:
"200":
description: Runtime metadata.
content:
application/json:
schema:
$ref: "#/components/schemas/RuntimeMetadata"
default:
$ref: "#/components/responses/Error"
/v1/capabilities:
get:
tags: [Runtime]
operationId: listCapabilities
summary: List local API capabilities.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
responses:
"200":
description: Capability summary.
content:
application/json:
schema:
$ref: "#/components/schemas/CapabilitySummary"
default:
$ref: "#/components/responses/Error"
/v1/provider-catalog:
get:
tags: [Runtime]
operationId: getProviderCatalog
summary: Read the normalized Harn provider/model catalog.
description: |
Returns the same provider catalog v2 artifact shape generated by
`harn providers export`, using the runtime's effective provider and
capability overlays.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
responses:
"200":
description: Provider/model catalog.
content:
application/json:
schema:
$ref: "#/components/schemas/ProviderCatalog"
default:
$ref: "#/components/responses/Error"
/v1/tools:
get:
tags: [Tools]
operationId: listTools
summary: List local control-plane tools exposed by the server.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Tool list.
content:
application/json:
schema:
$ref: "#/components/schemas/ToolList"
default:
$ref: "#/components/responses/Error"
/v1/tools/{tool_id}:
get:
tags: [Tools]
operationId: getTool
summary: Retrieve a local control-plane tool description.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ToolId"
responses:
"200":
description: Tool.
content:
application/json:
schema:
$ref: "#/components/schemas/Tool"
default:
$ref: "#/components/responses/Error"
/v1/agent-card:
get:
tags: [Discovery]
operationId: getAgentCard
summary: Retrieve the public Harn AgentCard envelope for this Harness.
security: []
responses:
"200":
description: Harn AgentCard envelope.
content:
application/json:
schema:
$ref: "#/components/schemas/HarnAgentCard"
default:
$ref: "#/components/responses/Error"
/v1/personas:
get:
tags: [Personas]
operationId: listPersonas
summary: List Personas visible to the caller.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Persona list.
content:
application/json:
schema:
$ref: "#/components/schemas/PersonaList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Personas]
operationId: createPersona
summary: Create or import a Persona definition.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreatePersonaRequest"
responses:
"201":
description: Created Persona.
content:
application/json:
schema:
$ref: "#/components/schemas/Persona"
default:
$ref: "#/components/responses/Error"
/v1/personas/{persona_id}:
get:
tags: [Personas]
operationId: getPersona
summary: Retrieve a Persona.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/PersonaId"
responses:
"200":
description: Persona.
content:
application/json:
schema:
$ref: "#/components/schemas/Persona"
default:
$ref: "#/components/responses/Error"
patch:
tags: [Personas]
operationId: updatePersona
summary: Update mutable Persona metadata and policy links.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/PersonaId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdatePersonaRequest"
responses:
"200":
description: Updated Persona.
content:
application/json:
schema:
$ref: "#/components/schemas/Persona"
default:
$ref: "#/components/responses/Error"
/v1/workspaces:
get:
tags: [Workspaces]
operationId: listWorkspaces
summary: List Workspaces visible to the caller.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Workspace list.
content:
application/json:
schema:
$ref: "#/components/schemas/WorkspaceList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Workspaces]
operationId: createWorkspace
summary: Create a Workspace isolation boundary.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateWorkspaceRequest"
responses:
"201":
description: Created Workspace.
content:
application/json:
schema:
$ref: "#/components/schemas/Workspace"
default:
$ref: "#/components/responses/Error"
/v1/workspaces/{workspace_id}:
get:
tags: [Workspaces]
operationId: getWorkspace
summary: Retrieve a Workspace.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceId"
responses:
"200":
description: Workspace.
content:
application/json:
schema:
$ref: "#/components/schemas/Workspace"
default:
$ref: "#/components/responses/Error"
patch:
tags: [Workspaces]
operationId: updateWorkspace
summary: Update mutable Workspace metadata and policy links.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateWorkspaceRequest"
responses:
"200":
description: Updated Workspace.
content:
application/json:
schema:
$ref: "#/components/schemas/Workspace"
default:
$ref: "#/components/responses/Error"
/v1/workspaces/{workspace_id}/files:
get:
tags: [Workspaces]
operationId: readWorkspaceFile
summary: Read or list UTF-8 files under a Workspace root.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/FilePathQuery"
responses:
"200":
description: File content or directory listing.
content:
application/json:
schema:
oneOf:
- $ref: "#/components/schemas/WorkspaceFile"
- $ref: "#/components/schemas/WorkspaceFileListing"
default:
$ref: "#/components/responses/Error"
put:
tags: [Workspaces]
operationId: writeWorkspaceFile
summary: Write a UTF-8 file under a Workspace root.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/FilePathQuery"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/WriteWorkspaceFileRequest"
responses:
"200":
description: Written file metadata.
content:
application/json:
schema:
$ref: "#/components/schemas/WorkspaceFile"
default:
$ref: "#/components/responses/Error"
/v1/sessions:
get:
tags: [Sessions]
operationId: listSessions
summary: List Sessions.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Session list.
content:
application/json:
schema:
$ref: "#/components/schemas/SessionList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Sessions]
operationId: createSession
summary: Create a Session bound to a Persona and Workspace.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateSessionRequest"
responses:
"201":
description: Created Session.
content:
application/json:
schema:
$ref: "#/components/schemas/Session"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}:
get:
tags: [Sessions]
operationId: getSession
summary: Retrieve a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
responses:
"200":
description: Session.
content:
application/json:
schema:
$ref: "#/components/schemas/Session"
default:
$ref: "#/components/responses/Error"
patch:
tags: [Sessions]
operationId: updateSession
summary: Update mutable Session metadata.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateSessionRequest"
responses:
"200":
description: Updated Session.
content:
application/json:
schema:
$ref: "#/components/schemas/Session"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/close:
post:
tags: [Sessions]
operationId: closeSession
summary: Close an active Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"200":
description: Closed Session.
content:
application/json:
schema:
$ref: "#/components/schemas/Session"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/live-clients:
get:
tags: [Sessions]
operationId: listSessionLiveClients
summary: List live clients attached to a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
responses:
"200":
description: Attached live clients.
content:
application/json:
schema:
$ref: "#/components/schemas/LiveSessionClientList"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/attach:
post:
tags: [Sessions]
operationId: attachSessionClient
summary: Attach a live client to a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AttachSessionClientRequest"
responses:
"200":
description: Live-client ownership state.
content:
application/json:
schema:
$ref: "#/components/schemas/LiveSessionClientChange"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/takeover:
post:
tags: [Sessions]
operationId: takeoverSessionClient
summary: Attach a client as the active Session controller.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SessionClientRequest"
responses:
"200":
description: Live-client ownership state.
content:
application/json:
schema:
$ref: "#/components/schemas/LiveSessionClientChange"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/detach:
post:
tags: [Sessions]
operationId: detachSessionClient
summary: Detach a live client from a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SessionClientRequest"
responses:
"200":
description: Live-client ownership state.
content:
application/json:
schema:
$ref: "#/components/schemas/LiveSessionClientChange"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/heartbeat:
post:
tags: [Sessions]
operationId: heartbeatSessionClient
summary: Refresh an attached live client's liveness marker.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SessionClientRequest"
responses:
"200":
description: Live-client ownership state.
content:
application/json:
schema:
$ref: "#/components/schemas/LiveSessionClientChange"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/fork:
post:
tags: [Sessions]
operationId: forkSession
summary: Fork a Session transcript into a new Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/ForkSessionRequest"
responses:
"201":
description: Forked Session.
content:
application/json:
schema:
$ref: "#/components/schemas/Session"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/truncate:
post:
tags: [Sessions]
operationId: truncateSession
summary: Truncate a Session transcript in place.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TruncateSessionRequest"
responses:
"200":
description: Truncated Session.
content:
application/json:
schema:
$ref: "#/components/schemas/TruncateSessionResponse"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/messages:
get:
tags: [Messages]
operationId: listSessionMessages
summary: List Messages in a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Message list.
content:
application/json:
schema:
$ref: "#/components/schemas/MessageList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Messages]
operationId: appendSessionMessage
summary: Append a user, tool, or host Message to a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AppendMessageRequest"
responses:
"201":
description: Created Message.
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/tasks:
get:
tags: [Tasks]
operationId: listSessionTasks
summary: List Tasks in a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Task list.
content:
application/json:
schema:
$ref: "#/components/schemas/TaskList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Tasks]
operationId: submitSessionTask
summary: Submit a Task in a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SubmitTaskRequest"
responses:
"202":
description: Accepted Task.
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/branches:
get:
tags: [Branches]
operationId: listSessionBranches
summary: List Branches in a Session.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Branch list.
content:
application/json:
schema:
$ref: "#/components/schemas/BranchList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Branches]
operationId: createSessionBranch
summary: Create a sub-agent or alternate transcript Branch.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateBranchRequest"
responses:
"201":
description: Created Branch.
content:
application/json:
schema:
$ref: "#/components/schemas/Branch"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/events:
get:
tags: [Events]
operationId: listSessionEvents
summary: Read a Session event range.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/AfterEventId"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Event range.
content:
application/json:
schema:
$ref: "#/components/schemas/EventList"
default:
$ref: "#/components/responses/Error"
/v1/sessions/{session_id}/events/stream:
get:
tags: [Events]
operationId: streamSessionEvents
summary: Stream Session Events over Server-Sent Events.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionId"
- $ref: "#/components/parameters/LastEventId"
responses:
"200":
description: SSE stream of Event objects.
content:
text/event-stream:
schema:
$ref: "#/components/schemas/EventStream"
default:
$ref: "#/components/responses/Error"
/v1/tasks:
get:
tags: [Tasks]
operationId: listTasks
summary: List Tasks visible to the caller.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Task list.
content:
application/json:
schema:
$ref: "#/components/schemas/TaskList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Tasks]
operationId: submitTask
summary: Submit a Task when the Session is supplied in the body.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SubmitTaskRequest"
responses:
"202":
description: Accepted Task.
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}:
get:
tags: [Tasks]
operationId: getTask
summary: Retrieve a Task.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
responses:
"200":
description: Task.
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/cancel:
post:
tags: [Tasks]
operationId: cancelTask
summary: Request cooperative Task cancellation.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/CancelTaskRequest"
responses:
"200":
description: Updated Task.
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
default:
$ref: "#/components/responses/Error"
/v1/permission-requests:
get:
tags: [Permissions]
operationId: listPermissionRequests
summary: List pending and resolved local permission requests.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/TaskIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Permission request list.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionRequestList"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/permission-requests:
get:
tags: [Permissions]
operationId: listTaskPermissionRequests
summary: List permission requests attached to a Task.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Permission request list.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionRequestList"
default:
$ref: "#/components/responses/Error"
/v1/permission-requests/{request_id}/respond:
post:
tags: [Permissions]
operationId: respondPermissionRequest
summary: Approve or deny an ACP permission or HITL request.
description: |
The local API forwards responses through the same runtime path as ACP
`session/request_permission` or `harn.hitl.respond`, so decisions are
captured by the active transcript, EventLog, replay, and receipt flows.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/PermissionRequestId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionResponseRequest"
responses:
"200":
description: Updated PermissionRequest.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionRequest"
default:
$ref: "#/components/responses/Error"
/v1/permissions/policy:
get:
tags: [Permissions]
operationId: getPermissionPolicy
summary: Read the currently-installed permission policy.
description: |
Returns the declared permission policy (read/write/exec/net globs,
llm provider allowlist with optional cost ceiling, redaction
patterns, escalation chain) together with its content-hashed
version. Every audit entry pins the version it was decided
against so historical evaluations stay reproducible.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
responses:
"200":
description: Installed permission policy.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionPolicyResponse"
default:
$ref: "#/components/responses/Error"
put:
tags: [Permissions]
operationId: installPermissionPolicy
summary: Replace the active permission policy.
description: |
Validates the supplied policy (rejects empty patterns and invalid
globs at parse time) and installs it. The previous version is
replaced atomically; in-flight requests evaluated against the
old version remain unaffected.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionPolicy"
responses:
"200":
description: Installed permission policy.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionPolicyResponse"
default:
$ref: "#/components/responses/Error"
/v1/permissions/rules:
get:
tags: [Permissions]
operationId: listPermissionRules
summary: List active "remember" rules.
description: |
Returns every non-revoked, non-expired rule the store knows about,
ordered narrowest-scope-first.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
responses:
"200":
description: Rule list.
content:
application/json:
schema:
$ref: "#/components/schemas/RememberRuleList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Permissions]
operationId: createPermissionRule
summary: Install a new "remember" rule.
description: |
Materializes a persistent rule that pins one action+target
glob to a verdict at the chosen scope. Use the
`respond_permission_request` endpoint with `remember: true`
for the in-flight equivalent.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RememberRule"
responses:
"200":
description: Created rule.
content:
application/json:
schema:
$ref: "#/components/schemas/RememberRule"
default:
$ref: "#/components/responses/Error"
/v1/permissions/rules/{rule_id}:
delete:
tags: [Permissions]
operationId: revokePermissionRule
summary: Soft-revoke a "remember" rule.
description: |
Marks the rule as revoked. Subsequent evaluations skip it; the
original row is preserved for audit. Use the audit API to find
the original `created_at`/`created_by` after revocation.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- in: path
name: rule_id
required: true
schema:
type: string
responses:
"204":
description: Rule revoked.
default:
$ref: "#/components/responses/Error"
/v1/permissions/history:
get:
tags: [Permissions]
operationId: getPermissionHistory
summary: Query the permission audit log.
description: |
Returns audit entries (every grant, deny, escalation) in
reverse-chronological order. Filter by session, workspace,
tenant, actor, or outcome. The in-memory store currently
retains the last `audit_capacity` entries; durable backends
(A.5) will eventually replace this with the session-store
event feed.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- in: query
name: session_id
schema: { type: string }
- in: query
name: workspace_id
schema: { type: string }
- in: query
name: tenant_id
schema: { type: string }
- in: query
name: actor
schema: { type: string }
- in: query
name: outcome
schema:
type: string
enum: [granted, denied, escalated]
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Audit entry list.
content:
application/json:
schema:
$ref: "#/components/schemas/AuditEntryList"
default:
$ref: "#/components/responses/Error"
/v1/permissions/check:
post:
tags: [Permissions]
operationId: checkPermission
summary: Evaluate a permission request against policy + rules.
description: |
Stateless evaluation entry-point. The store consults remember
rules (narrowest-scope-first), then the declared policy, then
the auto-deny floor. When nothing matches, returns
`outcome: "suspend"` with the escalation chain — the caller
is expected to hand the request off to the ACP
`session/request_permission` channel for human review.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionCheckRequest"
responses:
"200":
description: Decision and request id.
content:
application/json:
schema:
$ref: "#/components/schemas/PermissionCheckResponse"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/replay:
post:
tags: [Tasks]
operationId: replayTask
summary: Replay a Task from its durable EventLog.
description: |
Creates a new Task by replaying the original Task's durable event log.
The returned Task is the replay Task and MUST set `parent_task_id` to
the source Task id. Overrides substitute recorded nondeterministic
dependencies such as LLM responses, MCP tool returns, secret values,
clock reads, and host facts; every applied substitution MUST be
represented as a replay Receipt delta.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/ReplayTaskRequest"
responses:
"202":
description: Accepted replay Task.
content:
application/json:
schema:
$ref: "#/components/schemas/Task"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/messages:
post:
tags: [Messages]
operationId: appendTaskMessage
summary: Send input, interrupt, or tool-confirmation content to a Task.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AppendTaskMessageRequest"
responses:
"201":
description: Created Message.
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/events:
get:
tags: [Events]
operationId: listTaskEvents
summary: Read a Task event range.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/AfterEventId"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Event range.
content:
application/json:
schema:
$ref: "#/components/schemas/EventList"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/stream:
get:
tags: [Events]
operationId: streamTaskEvents
summary: Stream Task Events over Server-Sent Events.
description: WebSocket upgrades may use the same path for host-mediated interactive flows.
x-websocket-path: true
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/LastEventId"
responses:
"200":
description: SSE stream of Event objects.
content:
text/event-stream:
schema:
$ref: "#/components/schemas/EventStream"
default:
$ref: "#/components/responses/Error"
/v1/tasks/{task_id}/receipts:
get:
tags: [Receipts]
operationId: listTaskReceipts
summary: List Receipts associated with a Task.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskId"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Receipt list.
content:
application/json:
schema:
$ref: "#/components/schemas/ReceiptList"
default:
$ref: "#/components/responses/Error"
/v1/branches/{branch_id}:
get:
tags: [Branches]
operationId: getBranch
summary: Retrieve a Branch.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/BranchId"
responses:
"200":
description: Branch.
content:
application/json:
schema:
$ref: "#/components/schemas/Branch"
default:
$ref: "#/components/responses/Error"
/v1/messages/{message_id}:
get:
tags: [Messages]
operationId: getMessage
summary: Retrieve a Message.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/MessageId"
responses:
"200":
description: Message.
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
default:
$ref: "#/components/responses/Error"
/v1/artifacts:
get:
tags: [Artifacts]
operationId: listArtifacts
summary: List Artifacts.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/TaskIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Artifact list.
content:
application/json:
schema:
$ref: "#/components/schemas/ArtifactList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Artifacts]
operationId: registerArtifact
summary: Register an Artifact or mediated upload URI.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RegisterArtifactRequest"
responses:
"201":
description: Created Artifact.
content:
application/json:
schema:
$ref: "#/components/schemas/Artifact"
default:
$ref: "#/components/responses/Error"
/v1/artifacts/{artifact_id}:
get:
tags: [Artifacts]
operationId: getArtifact
summary: Retrieve Artifact metadata.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ArtifactId"
responses:
"200":
description: Artifact.
content:
application/json:
schema:
$ref: "#/components/schemas/Artifact"
default:
$ref: "#/components/responses/Error"
/v1/artifacts/{artifact_id}/content:
get:
tags: [Artifacts]
operationId: downloadArtifactContent
summary: Download Artifact content when access is mediated by the API.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ArtifactId"
responses:
"200":
description: Artifact bytes.
content:
application/octet-stream:
schema:
type: string
format: binary
default:
$ref: "#/components/responses/Error"
/v1/events:
get:
tags: [Events]
operationId: listEvents
summary: Read a global or filtered Event range.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/TaskIdQuery"
- $ref: "#/components/parameters/AfterEventId"
- $ref: "#/components/parameters/Limit"
responses:
"200":
description: Event range.
content:
application/json:
schema:
$ref: "#/components/schemas/EventList"
default:
$ref: "#/components/responses/Error"
/v1/events/{event_id}:
get:
tags: [Events]
operationId: getEvent
summary: Retrieve an Event.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/EventId"
responses:
"200":
description: Event.
content:
application/json:
schema:
$ref: "#/components/schemas/Event"
default:
$ref: "#/components/responses/Error"
/v1/events/stream:
get:
tags: [Events]
operationId: streamEvents
summary: Stream global or filtered Events over Server-Sent Events.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/TaskIdQuery"
- $ref: "#/components/parameters/LastEventId"
responses:
"200":
description: SSE stream of Event objects.
content:
text/event-stream:
schema:
$ref: "#/components/schemas/EventStream"
default:
$ref: "#/components/responses/Error"
/v1/receipts/{receipt_id}:
get:
tags: [Receipts]
operationId: getReceipt
summary: Retrieve a Receipt resource.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ReceiptId"
responses:
"200":
description: Receipt.
content:
application/json:
schema:
$ref: "#/components/schemas/Receipt"
default:
$ref: "#/components/responses/Error"
/v1/receipts/{receipt_id}/verify:
post:
tags: [Receipts]
operationId: verifyReceipt
summary: Verify a Receipt.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ReceiptId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: false
content:
application/json:
schema:
$ref: "#/components/schemas/VerifyReceiptRequest"
responses:
"200":
description: Receipt verification result.
content:
application/json:
schema:
$ref: "#/components/schemas/ReceiptVerification"
default:
$ref: "#/components/responses/Error"
/v1/memories:
get:
tags: [Memories]
operationId: listMemories
summary: List Memory records.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/SessionIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Memory list.
content:
application/json:
schema:
$ref: "#/components/schemas/MemoryList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Memories]
operationId: createMemory
summary: Create a durable Memory record.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateMemoryRequest"
responses:
"201":
description: Created Memory.
content:
application/json:
schema:
$ref: "#/components/schemas/Memory"
default:
$ref: "#/components/responses/Error"
/v1/memories/{memory_id}:
get:
tags: [Memories]
operationId: getMemory
summary: Retrieve a Memory record.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/MemoryId"
responses:
"200":
description: Memory.
content:
application/json:
schema:
$ref: "#/components/schemas/Memory"
default:
$ref: "#/components/responses/Error"
delete:
tags: [Memories]
operationId: deleteMemory
summary: Delete or tombstone a Memory record.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/MemoryId"
- $ref: "#/components/parameters/IdempotencyKey"
responses:
"204":
description: Memory deleted or tombstoned.
default:
$ref: "#/components/responses/Error"
/v1/vaults:
get:
tags: [Vaults]
operationId: listVaults
summary: List Vault metadata without secret values.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Vault list.
content:
application/json:
schema:
$ref: "#/components/schemas/VaultList"
default:
$ref: "#/components/responses/Error"
post:
tags: [Vaults]
operationId: createVault
summary: Create or register a Vault.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateVaultRequest"
responses:
"201":
description: Created Vault.
content:
application/json:
schema:
$ref: "#/components/schemas/Vault"
default:
$ref: "#/components/responses/Error"
/v1/vaults/{vault_id}:
get:
tags: [Vaults]
operationId: getVault
summary: Retrieve Vault metadata without secret values.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/VaultId"
responses:
"200":
description: Vault.
content:
application/json:
schema:
$ref: "#/components/schemas/Vault"
default:
$ref: "#/components/responses/Error"
/v1/connectors:
get:
tags: [Connectors]
operationId: listConnectors
summary: List Connectors.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/WorkspaceIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Connector list.
content:
application/json:
schema:
$ref: "#/components/schemas/ConnectorList"
default:
$ref: "#/components/responses/Error"
/v1/connectors/{connector_id}:
get:
tags: [Connectors]
operationId: getConnector
summary: Retrieve a Connector.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/ConnectorId"
responses:
"200":
description: Connector.
content:
application/json:
schema:
$ref: "#/components/schemas/Connector"
default:
$ref: "#/components/responses/Error"
/v1/skills:
get:
tags: [Skills]
operationId: listSkills
summary: List Skills.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Skill list.
content:
application/json:
schema:
$ref: "#/components/schemas/SkillList"
default:
$ref: "#/components/responses/Error"
/v1/skills/{skill_id}:
get:
tags: [Skills]
operationId: getSkill
summary: Retrieve a Skill.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/SkillId"
responses:
"200":
description: Skill.
content:
application/json:
schema:
$ref: "#/components/schemas/Skill"
default:
$ref: "#/components/responses/Error"
/v1/outcomes:
get:
tags: [Outcomes]
operationId: listOutcomes
summary: List Outcomes.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/TaskIdQuery"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Outcome list.
content:
application/json:
schema:
$ref: "#/components/schemas/OutcomeList"
default:
$ref: "#/components/responses/Error"
/v1/outcomes/{outcome_id}:
get:
tags: [Outcomes]
operationId: getOutcome
summary: Retrieve an Outcome.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/OutcomeId"
responses:
"200":
description: Outcome.
content:
application/json:
schema:
$ref: "#/components/schemas/Outcome"
default:
$ref: "#/components/responses/Error"
/v1/quotas:
get:
tags: [Quotas]
operationId: listQuotas
summary: List Quotas.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/Limit"
- $ref: "#/components/parameters/Cursor"
responses:
"200":
description: Quota list.
content:
application/json:
schema:
$ref: "#/components/schemas/QuotaList"
default:
$ref: "#/components/responses/Error"
/v1/quotas/{quota_id}:
get:
tags: [Quotas]
operationId: getQuota
summary: Retrieve a Quota.
parameters:
- $ref: "#/components/parameters/ProtocolVersion"
- $ref: "#/components/parameters/QuotaId"
responses:
"200":
description: Quota.
content:
application/json:
schema:
$ref: "#/components/schemas/Quota"
default:
$ref: "#/components/responses/Error"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: API key or OAuth2 access token
oauth2ClientCredentials:
type: oauth2
flows:
clientCredentials:
tokenUrl: https://api.harnlang.com/oauth/token
scopes:
sessions:read: Read Sessions.
sessions:write: Create or mutate Sessions.
tasks:read: Read Tasks.
tasks:write: Submit or cancel Tasks.
events:read: Read or stream Events.
artifacts:read: Read Artifacts.
artifacts:write: Register Artifacts.
receipts:read: Read Receipts.
parameters:
ProtocolVersion:
name: Harn-Agents-Protocol-Version
in: header
required: true
description: Date-stamped Harn Agents Protocol version.
schema:
type: string
enum: [agents-protocol-2026-04-25]
IdempotencyKey:
name: Idempotency-Key
in: header
required: false
description: Client-generated key used to safely retry non-idempotent writes.
schema:
type: string
minLength: 1
maxLength: 255
Limit:
name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 50
Cursor:
name: cursor
in: query
required: false
schema:
type: string
AfterEventId:
name: after_event_id
in: query
required: false
schema:
type: string
LastEventId:
name: Last-Event-ID
in: header
required: false
description: SSE resume cursor.
schema:
type: string
WorkspaceIdQuery:
name: workspace_id
in: query
required: false
schema:
type: string
SessionIdQuery:
name: session_id
in: query
required: false
schema:
type: string
TaskIdQuery:
name: task_id
in: query
required: false
schema:
type: string
FilePathQuery:
name: path
in: query
required: false
description: Workspace-relative path. Omit or use `.` to list the root.
schema:
type: string
PersonaId:
name: persona_id
in: path
required: true
schema:
type: string
WorkspaceId:
name: workspace_id
in: path
required: true
schema:
type: string
SessionId:
name: session_id
in: path
required: true
schema:
type: string
TaskId:
name: task_id
in: path
required: true
schema:
type: string
ToolId:
name: tool_id
in: path
required: true
schema:
type: string
PermissionRequestId:
name: request_id
in: path
required: true
schema:
type: string
BranchId:
name: branch_id
in: path
required: true
schema:
type: string
MessageId:
name: message_id
in: path
required: true
schema:
type: string
ArtifactId:
name: artifact_id
in: path
required: true
schema:
type: string
EventId:
name: event_id
in: path
required: true
schema:
type: string
ReceiptId:
name: receipt_id
in: path
required: true
schema:
type: string
MemoryId:
name: memory_id
in: path
required: true
schema:
type: string
VaultId:
name: vault_id
in: path
required: true
schema:
type: string
ConnectorId:
name: connector_id
in: path
required: true
schema:
type: string
SkillId:
name: skill_id
in: path
required: true
schema:
type: string
OutcomeId:
name: outcome_id
in: path
required: true
schema:
type: string
QuotaId:
name: quota_id
in: path
required: true
schema:
type: string
responses:
Error:
description: Protocol error response.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
schemas:
JsonObject:
type: object
additionalProperties: true
JsonValue:
description: Any JSON value.
Metadata:
type: object
additionalProperties: true
default: {}
Timestamp:
type: string
format: date-time
ResourcePointer:
type: object
required: [object, id]
properties:
object:
type: string
id:
type: string
PageInfo:
type: object
required: [has_more]
properties:
next_cursor:
type: [string, "null"]
has_more:
type: boolean
ResourceEnvelope:
type: object
required: [id, object, created_at, updated_at, metadata]
properties:
id:
type: string
object:
type: string
created_at:
$ref: "#/components/schemas/Timestamp"
updated_at:
$ref: "#/components/schemas/Timestamp"
metadata:
$ref: "#/components/schemas/Metadata"
Discovery:
type: object
required: [object, protocol_family, current_version, supported_versions, capabilities]
properties:
object:
type: string
enum: [protocol_discovery]
protocol_family:
type: string
enum: [harn_agents_protocol]
current_version:
type: string
enum: [agents-protocol-2026-04-25]
supported_versions:
type: array
items:
type: string
capabilities:
type: object
properties:
rest:
type: boolean
sse:
type: boolean
websocket:
type: boolean
receipts:
type: boolean
replay:
type: boolean
Health:
type: object
required: [ok, status, version]
properties:
ok:
type: boolean
status:
type: string
version:
type: string
RuntimeVersion:
type: object
required: [object, version, protocol_version]
properties:
object:
type: string
enum: [version]
version:
type: string
protocol_version:
type: string
RuntimeMetadata:
type: object
required: [object, version, protocol_version, adapter, capabilities]
properties:
object:
type: string
enum: [runtime]
version:
type: string
protocol_version:
type: string
adapter:
type: string
workspace_root:
type: string
session_count:
type: integer
minimum: 0
task_count:
type: integer
minimum: 0
capabilities:
type: array
items:
$ref: "#/components/schemas/Capability"
Capability:
type: object
required: [id, description]
properties:
id:
type: string
description:
type: string
CapabilitySummary:
type: object
required: [object, capabilities]
properties:
object:
type: string
enum: [capability_summary]
capabilities:
type: array
items:
$ref: "#/components/schemas/Capability"
ProviderCatalog:
type: object
required: [schema_version, schema, generated_by, providers, models, aliases, variants, qc_defaults]
additionalProperties: false
properties:
schema_version:
type: integer
enum: [2]
schema:
type: string
enum: ["https://harnlang.com/schemas/provider-catalog.v2.json"]
generated_by:
type: string
providers:
type: array
items:
type: object
additionalProperties: true
models:
type: array
items:
type: object
additionalProperties: true
aliases:
type: array
items:
type: object
additionalProperties: true
variants:
type: array
items:
type: object
additionalProperties: true
qc_defaults:
type: object
additionalProperties:
type: string
Tool:
type: object
required: [id, object, name, description, input_schema, output_schema]
properties:
id:
type: string
object:
type: string
enum: [tool]
name:
type: string
description:
type: string
input_schema:
$ref: "#/components/schemas/JsonObject"
output_schema:
$ref: "#/components/schemas/JsonObject"
ToolList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Tool"
Persona:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, name, version, entry_workflow, description, autonomy_tier, receipt_policy]
properties:
object:
type: string
enum: [persona]
name:
type: string
version:
type: string
entry_workflow:
type: string
description:
type: string
autonomy_tier:
$ref: "#/components/schemas/AutonomyTier"
receipt_policy:
type: string
enum: [required, optional, disabled]
tools:
type: array
items:
type: string
capabilities:
type: array
items:
type: string
triggers:
type: array
items:
$ref: "#/components/schemas/JsonObject"
schedules:
type: array
items:
$ref: "#/components/schemas/JsonObject"
handoffs:
type: array
items:
type: string
context_packs:
type: array
items:
type: string
evals:
type: array
items:
type: string
owner:
type: [string, "null"]
model_policy:
$ref: "#/components/schemas/JsonObject"
rollout_policy:
$ref: "#/components/schemas/JsonObject"
quota_id:
type: [string, "null"]
PersonaList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Persona"
CreatePersonaRequest:
type: object
required: [name, version, entry_workflow, description, autonomy_tier, receipt_policy]
properties:
module_ref:
type: string
description: Optional harn://owner/name@version module reference.
name:
type: string
version:
type: string
entry_workflow:
type: string
description:
type: string
autonomy_tier:
$ref: "#/components/schemas/AutonomyTier"
receipt_policy:
type: string
enum: [required, optional, disabled]
metadata:
$ref: "#/components/schemas/Metadata"
UpdatePersonaRequest:
type: object
properties:
description:
type: string
receipt_policy:
type: string
enum: [required, optional, disabled]
quota_id:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
Workspace:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, name, root, default_branch_id]
properties:
object:
type: string
enum: [workspace]
name:
type: string
root:
type: string
default_branch_id:
type: [string, "null"]
host:
type: [string, "null"]
repository:
type: [string, "null"]
tenant_id:
type: [string, "null"]
capabilities:
type: array
items:
type: string
connectors:
type: array
items:
type: string
quota_id:
type: [string, "null"]
WorkspaceList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Workspace"
WorkspaceFileEntry:
type: object
required: [name, path, kind, size]
properties:
name:
type: string
path:
type: string
kind:
type: string
enum: [file, directory]
size:
type: integer
minimum: 0
WorkspaceFileListing:
type: object
required: [object, workspace_id, path, entries]
properties:
object:
type: string
enum: [file_listing]
workspace_id:
type: string
path:
type: string
entries:
type: array
items:
$ref: "#/components/schemas/WorkspaceFileEntry"
WorkspaceFile:
type: object
required: [object, workspace_id, path, encoding]
properties:
object:
type: string
enum: [file]
workspace_id:
type: string
path:
type: string
encoding:
type: string
enum: [utf-8]
content:
type: string
bytes:
type: integer
minimum: 0
WriteWorkspaceFileRequest:
type: object
required: [content]
properties:
path:
type: string
description: Workspace-relative path; overrides the `path` query parameter when both are supplied.
content:
type: string
metadata:
$ref: "#/components/schemas/Metadata"
CreateWorkspaceRequest:
type: object
required: [name, root]
properties:
name:
type: string
root:
type: string
image:
type: [string, "null"]
packages:
type: array
items:
type: string
network_policy:
$ref: "#/components/schemas/JsonObject"
sandbox_backend:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
UpdateWorkspaceRequest:
type: object
properties:
name:
type: string
capabilities:
type: array
items:
type: string
quota_id:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
Session:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, workspace_id, state, transcript]
properties:
object:
type: string
enum: [session]
workspace_id:
type: string
state:
type: string
enum: [ACTIVE, IDLE, PAUSED, CLOSED, FAILED]
transcript:
oneOf:
- $ref: "#/components/schemas/JsonObject"
- type: string
format: uri-reference
persona_id:
type: [string, "null"]
root_session_id:
type: [string, "null"]
parent_session_id:
type: [string, "null"]
branch_id:
type: [string, "null"]
last_event_id:
type: [string, "null"]
live_clients:
type: array
items:
$ref: "#/components/schemas/LiveSessionClient"
live_controller_id:
type: [string, "null"]
summary:
type: [string, "null"]
expires_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
SessionList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Session"
CreateSessionRequest:
type: object
required: [workspace_id]
properties:
workspace_id:
type: string
persona_id:
type: [string, "null"]
vault_ids:
type: array
items:
type: string
memory_ids:
type: array
items:
type: string
skill_ids:
type: array
items:
type: string
initial_messages:
type: array
items:
$ref: "#/components/schemas/MessageInput"
metadata:
$ref: "#/components/schemas/Metadata"
UpdateSessionRequest:
type: object
properties:
summary:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
ForkSessionRequest:
type: object
properties:
at_event_id:
type: [string, "null"]
branch_id:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
TruncateSessionRequest:
type: object
required: [keep_first]
properties:
keep_first:
type: integer
minimum: 0
description: Number of leading turns to keep in the current Session transcript.
reason:
type: string
description: Optional client-visible reason for the truncation notification.
TruncateSessionResponse:
type: object
required:
- object
- session_id
- kept_turn_count
- removed_turn_count
- new_tip_turn_id
- session
properties:
object:
type: string
enum: [session.truncate_result]
session_id:
type: string
kept_turn_count:
type: integer
minimum: 0
removed_turn_count:
type: integer
minimum: 0
new_tip_turn_id:
type: [string, "null"]
session:
$ref: "#/components/schemas/Session"
LiveSessionClient:
type: object
required:
- client_id
- mode
- attached_at
- last_seen_at
- prompt_injection
- permission_routing
- metadata
properties:
client_id:
type: string
mode:
type: string
enum: [observer, controller]
attached_at:
type: string
description: Runtime liveness marker for when the client first attached.
last_seen_at:
type: string
description: Runtime liveness marker refreshed by attach or heartbeat.
prompt_injection:
type: boolean
permission_routing:
type: boolean
metadata:
$ref: "#/components/schemas/Metadata"
AttachSessionClientRequest:
type: object
required: [client_id]
properties:
client_id:
type: string
mode:
type: string
enum: [observer, controller]
default: observer
takeover:
type: boolean
default: false
prompt_injection:
type: boolean
description: Defaults to true for controllers and false for observers.
permission_routing:
type: boolean
description: Defaults to true for controllers and false for observers.
metadata:
$ref: "#/components/schemas/Metadata"
SessionClientRequest:
type: object
required: [client_id]
properties:
client_id:
type: string
reason:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
LiveSessionClientChange:
type: object
required:
- client
- previous_controller_id
- active_controller_id
- clients
properties:
client:
oneOf:
- $ref: "#/components/schemas/LiveSessionClient"
- type: "null"
previous_controller_id:
type: [string, "null"]
active_controller_id:
type: [string, "null"]
clients:
type: array
items:
$ref: "#/components/schemas/LiveSessionClient"
LiveSessionClientList:
type: object
required: [object, data]
properties:
object:
type: string
enum: [list]
data:
type: array
items:
$ref: "#/components/schemas/LiveSessionClient"
Task:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, session_id, workspace_id, status, input, created_by]
properties:
object:
type: string
enum: [task]
session_id:
type: string
workspace_id:
type: string
status:
$ref: "#/components/schemas/TaskStatus"
input:
oneOf:
- $ref: "#/components/schemas/Message"
- $ref: "#/components/schemas/JsonObject"
created_by:
type: string
persona_id:
type: [string, "null"]
branch_id:
type: [string, "null"]
parent_task_id:
type: [string, "null"]
description: Source Task id for replay and delegated child Tasks, otherwise null.
assigned_agent_id:
type: [string, "null"]
receipt_id:
type: [string, "null"]
outcome_id:
type: [string, "null"]
quota_id:
type: [string, "null"]
started_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
completed_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
canceled_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
failure:
oneOf:
- $ref: "#/components/schemas/Failure"
- type: "null"
TaskStatus:
type: string
enum: [SUBMITTED, WORKING, INPUT_REQUIRED, AUTH_REQUIRED, COMPLETED, FAILED, CANCELED]
TaskList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Task"
SubmitTaskRequest:
type: object
required: [input]
properties:
session_id:
type: string
description: Required on the top-level `/v1/tasks` submit path; inferred on nested Session paths.
workspace_id:
type: string
persona_id:
type: [string, "null"]
branch_id:
type: [string, "null"]
parent_task_id:
type: [string, "null"]
input:
oneOf:
- $ref: "#/components/schemas/MessageInput"
- $ref: "#/components/schemas/JsonObject"
metadata:
$ref: "#/components/schemas/Metadata"
CancelTaskRequest:
type: object
properties:
reason:
type: [string, "null"]
PermissionRequest:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, status, source, request]
properties:
object:
type: string
enum: [permission_request]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
status:
type: string
enum: [pending, approved, denied]
source:
type: string
enum: [acp, hitl]
action:
$ref: "#/components/schemas/JsonValue"
request:
$ref: "#/components/schemas/JsonValue"
response:
$ref: "#/components/schemas/JsonValue"
PermissionRequestList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/PermissionRequest"
PermissionResponseRequest:
type: object
properties:
approved:
type: boolean
description: Preferred boolean approval switch.
outcome:
type: string
enum: [approved, approve, selected, denied, deny, rejected]
description: Compatibility outcome for clients that mirror ACP wording.
answer:
$ref: "#/components/schemas/JsonValue"
reviewer:
type: [string, "null"]
reason:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
scope:
type: [string, "null"]
enum: [session, workspace, user, always, null]
description: |
When the approver wants the verdict remembered, the scope at
which to apply it. Honored only when `remember` is true.
expires_at:
type: [string, "null"]
format: date-time
description: Optional auto-revoke timestamp for time-bound grants.
remember:
type: [boolean, "null"]
description: |
When true and the response approves or denies, materializes a
persistent rule keyed off `scope` + `action_pattern` +
`target_pattern`.
action_pattern:
type: [string, "null"]
description: Glob pattern matched against future `PermissionRequest.action`.
target_pattern:
type: [string, "null"]
description: Glob pattern matched against future `PermissionRequest.target`.
class:
type: [string, "null"]
enum: [read, write, exec, net, llm, custom, null]
PermissionPolicy:
type: object
description: |
Declared permission policy: read/write/exec globs, net host
allowlist, llm provider list + optional cost ceiling,
redaction patterns, escalation chain.
properties:
read:
type: array
items: { type: string }
write:
type: array
items: { type: string }
exec:
type: array
items: { type: string }
net:
type: array
items: { type: string }
llm:
type: object
properties:
providers:
type: array
items: { type: string }
uniqueItems: true
cost_ceiling_usd_cents:
type: [integer, "null"]
minimum: 0
redact:
type: object
properties:
transcript:
type: array
items: { type: string }
logs:
type: array
items: { type: string }
escalate_to:
type: array
items: { type: string }
description: |
Free-form identifiers tried in order (persona URI, the
literal `user`, group name). The first online escalator
receives the request.
PermissionPolicyResponse:
type: object
required: [object, version, policy]
properties:
object:
type: string
enum: [permission_policy]
version:
type: string
description: Content-hashed policy version.
policy:
$ref: "#/components/schemas/PermissionPolicy"
RememberRule:
type: object
required:
- id
- scope
- class
- action_pattern
- target_pattern
- allow
- created_at
- created_by
properties:
id:
type: string
description: UUIDv7-prefixed rule identifier.
tenant_id:
type: [string, "null"]
scope:
type: string
enum: [session, workspace, user, always]
scope_value:
type: [string, "null"]
description: Session id, workspace id, or actor, depending on scope.
class:
type: string
enum: [read, write, exec, net, llm, custom]
action_pattern:
type: string
target_pattern:
type: string
allow:
type: boolean
reason:
type: [string, "null"]
created_at:
type: string
format: date-time
created_by:
type: string
expires_at:
type: [string, "null"]
format: date-time
revoked_at:
type: [string, "null"]
format: date-time
RememberRuleList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/RememberRule"
PermissionCheckRequest:
type: object
required: [session_id, actor, class, action, target]
properties:
id:
type: [string, "null"]
tenant_id:
type: [string, "null"]
session_id:
type: string
workspace_id:
type: [string, "null"]
actor:
type: string
class:
type: string
enum: [read, write, exec, net, llm, custom]
action:
type: string
target:
type: string
risk:
type: [string, "null"]
enum: [low, medium, high, critical, null]
context:
type: object
additionalProperties: true
reason:
type: [string, "null"]
requested_at:
type: string
format: date-time
PermissionCheckResponse:
type: object
required: [object, request_id, decision]
properties:
object:
type: string
enum: [permission_decision]
request_id:
type: string
decision:
oneOf:
- $ref: "#/components/schemas/PermissionDecisionGranted"
- $ref: "#/components/schemas/PermissionDecisionDenied"
- $ref: "#/components/schemas/PermissionDecisionSuspend"
PermissionDecisionGranted:
type: object
required: [outcome, scope, policy_version]
properties:
outcome:
type: string
enum: [granted]
scope:
type: string
enum: [session, workspace, user, always]
policy_version:
type: string
reason:
type: [string, "null"]
expires_at:
type: [string, "null"]
format: date-time
rule_id:
type: [string, "null"]
PermissionDecisionDenied:
type: object
required: [outcome, scope, policy_version]
properties:
outcome:
type: string
enum: [denied]
scope:
type: string
enum: [session, workspace, user, always]
policy_version:
type: string
reason:
type: [string, "null"]
rule_id:
type: [string, "null"]
PermissionDecisionSuspend:
type: object
required: [outcome, policy_version, escalate_to]
properties:
outcome:
type: string
enum: [suspend]
policy_version:
type: string
escalate_to:
type: array
items: { type: string }
reason:
type: [string, "null"]
AuditEntry:
type: object
required: [request, outcome, policy_version, risk, decided_at]
properties:
request:
$ref: "#/components/schemas/PermissionCheckRequest"
outcome:
type: string
enum: [granted, denied, escalated]
scope:
type: [string, "null"]
enum: [session, workspace, user, always, null]
policy_version:
type: string
risk:
type: string
enum: [low, medium, high, critical]
rule_id:
type: [string, "null"]
reason:
type: [string, "null"]
expires_at:
type: [string, "null"]
format: date-time
decided_at:
type: string
format: date-time
decided_by:
type: [string, "null"]
AuditEntryList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/AuditEntry"
ReplayMode:
type: string
enum: [exact, with_overrides, from_checkpoint]
description: |
`exact` reuses only recorded event-log material, `with_overrides`
applies explicit substitutions, and `from_checkpoint` resumes from a
recorded checkpoint before replaying later events.
ReplayTaskRequest:
type: object
properties:
mode:
$ref: "#/components/schemas/ReplayMode"
default: exact
override:
type: object
description: Map from stable override key to replacement replay material.
additionalProperties:
$ref: "#/components/schemas/ReplayOverride"
default: {}
checkpoint_id:
type: [string, "null"]
description: Required when `mode` is `from_checkpoint` unless `checkpoint_event_id` is supplied.
checkpoint_event_id:
type: [string, "null"]
description: Event id of the checkpoint boundary for `from_checkpoint` replay.
reason:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
examples:
- mode: with_overrides
override:
llm:main:1:
kind: llm_provider_response
event_id: event_01JZ7001
value:
id: chatcmpl_fixture_1
choices:
- message:
role: assistant
content: Done.
sha256: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ReplayOverride:
type: object
required: [kind]
properties:
kind:
type: string
enum:
- llm_provider_response
- mcp_tool_return
- secret_value
- time
- host_fact
- tool_result
- event_payload
- checkpoint_value
event_id:
type: [string, "null"]
description: Original EventLog event this override substitutes when known.
target:
type: [string, "null"]
description: Stable dependency key such as a model call id, tool call id, secret name, or clock label.
value:
$ref: "#/components/schemas/JsonValue"
artifact_id:
type: [string, "null"]
description: Artifact containing replacement material when the value is large or receipt-only.
sha256:
type: [string, "null"]
pattern: "^sha256:[0-9a-f]{64}$"
visibility:
type: string
enum: [public, internal, receipt_only]
default: receipt_only
reason:
type: [string, "null"]
ReplayEventMetadata:
type: object
required: [source_task_id, replay_task_id]
properties:
source_task_id:
type: string
replay_task_id:
type: string
original_event_id:
type: [string, "null"]
replay_cursor:
type: [string, "null"]
description: Cursor clients can use when replay remaps event ids.
mode:
$ref: "#/components/schemas/ReplayMode"
override_key:
type: [string, "null"]
description: Override map key applied to produce this replayed event, when any.
receipt_delta_id:
type: [string, "null"]
Branch:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, workspace_id, kind, base_ref]
properties:
object:
type: string
enum: [branch]
workspace_id:
type: string
kind:
type: string
enum: [workspace, session, task, sandbox]
base_ref:
type: string
parent_branch_id:
type: [string, "null"]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
worktree_uri:
type: [string, "null"]
created_by:
type: [string, "null"]
merged_into:
type: [string, "null"]
BranchList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Branch"
CreateBranchRequest:
type: object
required: [kind, base_ref]
properties:
kind:
type: string
enum: [workspace, session, task, sandbox]
base_ref:
type: string
parent_branch_id:
type: [string, "null"]
task_id:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
Message:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, role, parts]
properties:
object:
type: string
enum: [message]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
role:
type: string
enum: [user, assistant, system, tool, agent]
parts:
type: array
items:
$ref: "#/components/schemas/Part"
MessageInput:
type: object
required: [role, parts]
properties:
role:
type: string
enum: [user, assistant, system, tool, agent]
parts:
type: array
items:
$ref: "#/components/schemas/PartInput"
metadata:
$ref: "#/components/schemas/Metadata"
MessageList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Message"
AppendMessageRequest:
type: object
required: [message]
properties:
message:
$ref: "#/components/schemas/MessageInput"
AppendTaskMessageRequest:
type: object
required: [kind, message]
properties:
kind:
type: string
enum: [input, interrupt, tool_confirmation]
message:
$ref: "#/components/schemas/MessageInput"
Part:
oneOf:
- $ref: "#/components/schemas/TextPart"
- $ref: "#/components/schemas/JsonPart"
- $ref: "#/components/schemas/ToolCallPart"
- $ref: "#/components/schemas/ToolResultPart"
- $ref: "#/components/schemas/ArtifactRefPart"
- $ref: "#/components/schemas/FileRefPart"
- $ref: "#/components/schemas/ImageRefPart"
PartInput:
$ref: "#/components/schemas/Part"
PartVisibility:
type: string
enum: [public, internal, receipt_only]
TextPart:
type: object
required: [type, text, visibility]
properties:
type:
type: string
enum: [text]
text:
type: string
visibility:
$ref: "#/components/schemas/PartVisibility"
JsonPart:
type: object
required: [type, value, visibility]
properties:
type:
type: string
enum: [json]
value:
$ref: "#/components/schemas/JsonValue"
visibility:
$ref: "#/components/schemas/PartVisibility"
ToolCallPart:
type: object
required: [type, tool_call_id, name, input, visibility]
properties:
type:
type: string
enum: [tool_call]
tool_call_id:
type: string
name:
type: string
input:
$ref: "#/components/schemas/JsonObject"
visibility:
$ref: "#/components/schemas/PartVisibility"
ToolResultPart:
type: object
required: [type, tool_call_id, output, status, visibility]
properties:
type:
type: string
enum: [tool_result]
tool_call_id:
type: string
output:
$ref: "#/components/schemas/JsonValue"
status:
type: string
enum: [ok, error]
visibility:
$ref: "#/components/schemas/PartVisibility"
ArtifactRefPart:
type: object
required: [type, artifact_id, visibility]
properties:
type:
type: string
enum: [artifact_ref]
artifact_id:
type: string
visibility:
$ref: "#/components/schemas/PartVisibility"
FileRefPart:
type: object
required: [type, uri, mime_type, visibility]
properties:
type:
type: string
enum: [file_ref]
uri:
type: string
mime_type:
type: string
visibility:
$ref: "#/components/schemas/PartVisibility"
ImageRefPart:
type: object
required: [type, artifact_id, mime_type, visibility]
properties:
type:
type: string
enum: [image_ref]
artifact_id:
type: string
mime_type:
type: string
visibility:
$ref: "#/components/schemas/PartVisibility"
Artifact:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, kind, mime_type, uri, visibility, sha256]
properties:
object:
type: string
enum: [artifact]
kind:
type: string
enum: [file, patch, image, log, diff, receipt, snapshot, dataset, other]
mime_type:
type: string
uri:
type: [string, "null"]
format: uri-reference
visibility:
$ref: "#/components/schemas/PartVisibility"
sha256:
type: [string, "null"]
pattern: "^[a-fA-F0-9]{64}$"
workspace_id:
type: [string, "null"]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
receipt_id:
type: [string, "null"]
ArtifactList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Artifact"
RegisterArtifactRequest:
type: object
required: [kind, mime_type, visibility]
properties:
kind:
type: string
enum: [file, patch, image, log, diff, receipt, snapshot, dataset, other]
mime_type:
type: string
uri:
type: [string, "null"]
visibility:
$ref: "#/components/schemas/PartVisibility"
sha256:
type: [string, "null"]
pattern: "^[a-fA-F0-9]{64}$"
workspace_id:
type: [string, "null"]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
metadata:
$ref: "#/components/schemas/Metadata"
HarnAgentCard:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, name, description, protocol_version, a2a_card, skills]
properties:
object:
type: string
enum: [harn_agent_card]
name:
type: string
description:
type: string
protocol_version:
type: string
a2a_card:
$ref: "#/components/schemas/A2aAgentCard"
skills:
type: array
items:
$ref: "#/components/schemas/Skill"
harn_interfaces:
type: array
items:
$ref: "#/components/schemas/HarnAgentInterface"
persona_ids:
type: array
items:
type: string
capabilities:
type: array
items:
type: string
auth_schemes:
type: array
items:
type: string
receipt_policy:
type: [string, "null"]
quotas:
type: array
items:
$ref: "#/components/schemas/Quota"
provider:
$ref: "#/components/schemas/JsonObject"
public_url:
type: [string, "null"]
format: uri
signature:
oneOf:
- $ref: "#/components/schemas/CardSignature"
- type: "null"
A2aAgentCard:
type: object
required:
- name
- description
- supportedInterfaces
- version
- capabilities
- defaultInputModes
- defaultOutputModes
- skills
properties:
name:
type: string
description:
type: string
supportedInterfaces:
type: array
minItems: 1
items:
$ref: "#/components/schemas/A2aAgentInterface"
provider:
$ref: "#/components/schemas/A2aAgentProvider"
version:
type: string
documentationUrl:
type: [string, "null"]
format: uri
capabilities:
$ref: "#/components/schemas/A2aAgentCapabilities"
securitySchemes:
type: object
additionalProperties:
$ref: "#/components/schemas/A2aSecurityScheme"
security:
type: array
items:
type: object
additionalProperties:
type: array
items:
type: string
defaultInputModes:
type: array
items:
type: string
defaultOutputModes:
type: array
items:
type: string
skills:
type: array
items:
$ref: "#/components/schemas/A2aAgentSkill"
signatures:
type: array
items:
$ref: "#/components/schemas/A2aAgentCardSignature"
iconUrl:
type: [string, "null"]
format: uri
A2aAgentInterface:
type: object
required: [url, protocolBinding, protocolVersion]
properties:
url:
type: string
format: uri
protocolBinding:
type: string
examples: [JSONRPC, GRPC, HTTP+JSON]
tenant:
type: [string, "null"]
protocolVersion:
type: string
A2aAgentProvider:
type: object
required: [organization, url]
properties:
organization:
type: string
url:
type: string
format: uri
A2aAgentCapabilities:
type: object
properties:
streaming:
type: boolean
pushNotifications:
type: boolean
extensions:
type: array
items:
$ref: "#/components/schemas/JsonObject"
extendedAgentCard:
type: boolean
A2aAgentSkill:
type: object
required: [id, name, description, tags]
properties:
id:
type: string
name:
type: string
description:
type: string
tags:
type: array
items:
type: string
examples:
type: array
items:
type: string
inputModes:
type: array
items:
type: string
outputModes:
type: array
items:
type: string
security:
type: array
items:
type: object
additionalProperties:
type: array
items:
type: string
inputSchema:
oneOf:
- $ref: "#/components/schemas/JsonObject"
- type: "null"
A2aSecurityScheme:
type: object
description: A2A SecurityScheme union member, following the A2A/OpenAPI security object shape.
additionalProperties: true
A2aAgentCardSignature:
type: object
required: [protected, signature]
properties:
protected:
type: string
signature:
type: string
header:
$ref: "#/components/schemas/JsonObject"
HarnAgentInterface:
type: object
required: [transport, url]
properties:
transport:
type: string
enum: [rest, sse, websocket, a2a, mcp, acp]
url:
type: string
format: uri-reference
CardSignature:
type: object
required: [algorithm, key_id, value]
properties:
algorithm:
type: string
key_id:
type: string
value:
type: string
Event:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, event, resource, sequence, payload]
properties:
object:
type: string
enum: [event]
event:
type: string
resource:
$ref: "#/components/schemas/ResourcePointer"
sequence:
type: integer
minimum: 0
payload:
$ref: "#/components/schemas/JsonObject"
trace_id:
type: [string, "null"]
span_id:
type: [string, "null"]
session_id:
type: [string, "null"]
task_id:
type: [string, "null"]
workspace_id:
type: [string, "null"]
actor:
type: [string, "null"]
idempotency_key:
type: [string, "null"]
previous_event_id:
type: [string, "null"]
receipt_id:
type: [string, "null"]
replayed:
type: boolean
default: false
replay:
oneOf:
- $ref: "#/components/schemas/ReplayEventMetadata"
- type: "null"
EventList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Event"
EventStream:
type: string
description: UTF-8 Server-Sent Events. Each frame `data` field is an Event JSON object.
Receipt:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, subject, format, summary, issued_at, issuer]
properties:
object:
type: string
enum: [receipt]
subject:
$ref: "#/components/schemas/ResourcePointer"
format:
type: string
summary:
type: string
issued_at:
$ref: "#/components/schemas/Timestamp"
issuer:
type: string
wire:
$ref: "#/components/schemas/ReceiptWireEnvelope"
verification:
oneOf:
- $ref: "#/components/schemas/ReceiptVerification"
- type: "null"
externalDocs:
description: Receipt wire format sibling specification.
url: https://github.com/burin-labs/harn/issues/635
ReceiptWireEnvelope:
type: object
description: |
Placeholder OpenAPI projection of the v1 receipt-format envelope. The
sibling receipt-format spec owns canonicalization, signatures, hash
chains, and redaction. Receipt resources reference that envelope here
through `$ref` so generated clients can carry the wire receipt without
treating it as an untyped trace.
required: [schema_version, subject, issued_at]
properties:
schema_version:
type: string
subject:
$ref: "#/components/schemas/ResourcePointer"
issued_at:
$ref: "#/components/schemas/Timestamp"
payload:
$ref: "#/components/schemas/JsonObject"
signature:
oneOf:
- $ref: "#/components/schemas/CardSignature"
- type: "null"
ReceiptList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Receipt"
VerifyReceiptRequest:
type: object
properties:
trust_anchor:
type: [string, "null"]
at_time:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
ReceiptVerification:
type: object
required: [valid, checked_at]
properties:
valid:
type: boolean
checked_at:
$ref: "#/components/schemas/Timestamp"
reason:
type: [string, "null"]
details:
$ref: "#/components/schemas/JsonObject"
Memory:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, scope, owner_id, content, provenance]
properties:
object:
type: string
enum: [memory]
scope:
type: string
enum: [persona, session, workspace, tenant]
owner_id:
type: string
content:
oneOf:
- type: string
- $ref: "#/components/schemas/JsonObject"
- $ref: "#/components/schemas/ArtifactRefPart"
provenance:
$ref: "#/components/schemas/JsonObject"
expires_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
embedding_ref:
type: [string, "null"]
visibility:
$ref: "#/components/schemas/PartVisibility"
redaction_policy:
$ref: "#/components/schemas/JsonObject"
confidence:
type: [number, "null"]
minimum: 0
maximum: 1
MemoryList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Memory"
CreateMemoryRequest:
type: object
required: [scope, owner_id, content, provenance]
properties:
scope:
type: string
enum: [persona, session, workspace, tenant]
owner_id:
type: string
content:
$ref: "#/components/schemas/JsonValue"
provenance:
$ref: "#/components/schemas/JsonObject"
metadata:
$ref: "#/components/schemas/Metadata"
Vault:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, workspace_id, provider, capabilities]
properties:
object:
type: string
enum: [vault]
workspace_id:
type: [string, "null"]
provider:
type: string
capabilities:
type: array
items:
type: string
VaultList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Vault"
CreateVaultRequest:
type: object
required: [provider, capabilities]
properties:
workspace_id:
type: [string, "null"]
provider:
type: string
capabilities:
type: array
items:
type: string
metadata:
$ref: "#/components/schemas/Metadata"
Connector:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, provider, workspace_id, status, event_kinds]
properties:
object:
type: string
enum: [connector]
provider:
type: string
workspace_id:
type: string
status:
type: string
enum: [ACTIVE, PAUSED, FAILED, DISABLED]
event_kinds:
type: array
items:
type: string
dedupe_policy:
$ref: "#/components/schemas/JsonObject"
auth:
$ref: "#/components/schemas/JsonObject"
webhook:
$ref: "#/components/schemas/JsonObject"
polling:
$ref: "#/components/schemas/JsonObject"
target_persona_id:
type: [string, "null"]
target_session_id:
type: [string, "null"]
ConnectorList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Connector"
Skill:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, name, description, input_schema, output_schema]
properties:
object:
type: string
enum: [skill]
name:
type: string
description:
type: string
input_schema:
oneOf:
- $ref: "#/components/schemas/JsonObject"
- type: "null"
output_schema:
oneOf:
- $ref: "#/components/schemas/JsonObject"
- type: "null"
source:
type: [string, "null"]
version:
type: [string, "null"]
capabilities:
type: array
items:
type: string
requires_approval:
type: boolean
default: false
deprecated:
type: boolean
default: false
SkillList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Skill"
Outcome:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, task_id, status, summary]
properties:
object:
type: string
enum: [outcome]
task_id:
type: string
status:
type: string
enum: [SUCCEEDED, FAILED, CANCELED]
summary:
type: string
messages:
type: array
items:
$ref: "#/components/schemas/Message"
artifacts:
type: array
items:
$ref: "#/components/schemas/Artifact"
handoffs:
type: array
items:
$ref: "#/components/schemas/JsonObject"
receipt_id:
type: [string, "null"]
failure:
oneOf:
- $ref: "#/components/schemas/Failure"
- type: "null"
cost:
$ref: "#/components/schemas/JsonObject"
metrics:
$ref: "#/components/schemas/JsonObject"
OutcomeList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Outcome"
Quota:
allOf:
- $ref: "#/components/schemas/ResourceEnvelope"
- type: object
required: [object, scope, limits, usage]
properties:
object:
type: string
enum: [quota]
scope:
type: string
enum: [persona, workspace, tenant, organization]
limits:
type: object
additionalProperties:
type: number
usage:
type: object
additionalProperties:
type: number
reset_at:
oneOf:
- $ref: "#/components/schemas/Timestamp"
- type: "null"
hard_limit:
type: boolean
default: true
soft_limit:
type: boolean
default: false
exhaustion_reason:
type: [string, "null"]
last_receipt_id:
type: [string, "null"]
QuotaList:
allOf:
- $ref: "#/components/schemas/PaginatedList"
- type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Quota"
AutonomyTier:
type: string
enum: [shadow, suggest, act_with_approval, act_auto]
Failure:
type: object
required: [code, message]
properties:
code:
type: string
message:
type: string
details:
$ref: "#/components/schemas/JsonObject"
ErrorResponse:
type: object
required: [error]
properties:
error:
$ref: "#/components/schemas/Error"
Error:
type: object
required: [code, message, type]
properties:
code:
type: string
enum:
- invalid_request
- invalid_state_transition
- unauthenticated
- permission_denied
- resource_not_found
- conflict
- idempotency_key_reused
- cursor_expired
- payload_too_large
- policy_violation
- resource_locked
- unsupported_protocol_version
- rate_limited
- client_closed_request
- internal_error
- upstream_unavailable
- service_unavailable
- deadline_exceeded
message:
type: string
type:
type: string
enum:
- request_error
- auth_error
- permission_error
- not_found_error
- conflict_error
- rate_limit_error
- runtime_error
- upstream_error
- server_error
param:
type: [string, "null"]
request_id:
type: [string, "null"]
details:
$ref: "#/components/schemas/JsonObject"
PaginatedList:
type: object
required: [object, data, page]
properties:
object:
type: string
enum: [list]
data:
type: array
items: {}
page:
$ref: "#/components/schemas/PageInfo"