Autonomous Agents¶
The Management API exposes 34 operations under /autonomous for provider discovery, gateway lifecycle, channels, skills, model synchronization, messaging, and Hermes administration. The default base URL is http://127.0.0.1:8001/api/v1. Every operation on this page appears in Swagger UI at /api/docs under the Autonomous Agents tag.
Use hermes for new integrations. claw remains a valid provider kind on a desktop runtime, but the old /claw/* routes are a compatibility surface rather than a second autonomous-agent API. See Legacy /claw routes.
Provider model and runtime availability¶
GET /autonomous/providers returns the providers registered in the running process. Each ProviderDescriptor contains:
kind:claworhermes.displayName: the user-facing provider name.capabilities: feature flags and the supported messaging platforms and execution modes.installed:trueonly when environment detection reports no outstanding issue.gateway: the latestGatewayInfo, ornullbefore a gateway has run.
Capability flags are supportsMessagingChannels, supportsSkills, supportsProfiles, supportsMcp, supportsModelBridge, supportsGatewayLogs, supportsChannelHistory, and supportsSkillToggle.
GET /autonomous/availability reports every provider kind known to the build, including providers that are not registered. Each row contains kind, displayName, runtimeRequirement, available, and an optional unavailableReason. runtimeRequirement is universal for Hermes and desktop_only for Claw. The top-level anyAvailable and optional unavailableReason describe the domain as a whole.
Hermes is registered by both the desktop app and aigo-server. Its gateway still needs an accessible Docker or Apple Container runtime and a usable image. Claw is registered only by the desktop app. A headless server therefore reports Hermes as available and Claw as unavailable, while /autonomous/providers contains only Hermes.
Check /autonomous/providers/{kind}/environment before install or start. Its EnvironmentReport contains containerRuntime, image, gatewayRunning, issues, and provider-specific extra data. Issue tags include container_runtime_not_found, container_runtime_unsupported, image_missing, image_outdated, gateway_not_running, port_in_use, persistent_volume_unavailable, and custom.
Authentication and scopes¶
Authenticate with X-API-Key, an Authorization: Bearer token, or the aigo_session cookie returned by the login endpoint.
The route manifest applies three scopes:
| Scope | Operations |
|---|---|
container_read | Provider discovery and availability, capabilities, environment, gateway status and logs, channels and history, skills, the event stream, profile and MCP listings, settings reads, and approval reads. |
container_write | Install, gateway lifecycle mutations, skill toggles, model synchronization, profile and MCP mutations, Hermes settings and approval decisions, platform credentials, connection tests, and migration. |
autonomous_message_send | POST /autonomous/providers/{kind}/messages only. This separate scope prevents container lifecycle access from implicitly granting permission to speak as the operator on a connected platform. |
An Admin key satisfies these checks. A non-admin key needs the exact scope listed in the tables below.
Provider endpoints¶
Paths omit the /api/v1 prefix.
| Method | Path | Scope | Body or query | Returns |
|---|---|---|---|---|
GET | /autonomous/providers | container_read | none | ProviderDescriptor[] |
GET | /autonomous/availability | container_read | none | AutonomousAvailability |
GET | /autonomous/providers/{kind}/capabilities | container_read | none | ProviderCapabilities |
GET | /autonomous/providers/{kind}/environment | container_read | none | EnvironmentReport |
POST | /autonomous/providers/{kind}/install | container_write | none | { "status": "completed" } (202) |
POST | /autonomous/providers/{kind}/gateway/start | container_write | GatewayStartOptions | GatewayInfo |
POST | /autonomous/providers/{kind}/gateway/stop | container_write | none | 204 |
POST | /autonomous/providers/{kind}/gateway/restart | container_write | GatewayStartOptions | GatewayInfo |
GET | /autonomous/providers/{kind}/gateway | container_read | none | GatewayInfo | null |
GET | /autonomous/providers/{kind}/gateway/logs | container_read | ?tail= (default 200, maximum 5000), ?since= (RFC 3339) | GatewayLogs |
GET | /autonomous/providers/{kind}/channels | container_read | none | AgentChannel[] |
GET | /autonomous/providers/{kind}/channels/{id}/messages | container_read | ?limit= (default 50, maximum 500), ?before= | ChannelMessagesPage |
GET | /autonomous/providers/{kind}/skills | container_read | none | AgentSkill[] |
PATCH | /autonomous/providers/{kind}/skills/{id}/enabled | container_write | { "enabled": true } | AgentSkill |
POST | /autonomous/providers/{kind}/models/sync | container_write | { "models": ModelSummary[] } | ModelSyncStatus |
POST | /autonomous/providers/{kind}/messages | autonomous_message_send | SendMessageRequest | MessageReceipt |
GET | /autonomous/events | container_read | SSE stream | ProviderEvent frames |
The URL is the source of truth for {kind}. The gateway and message handlers normalize a mismatched provider field to the URL provider. A gateway start body uses the flattened GatewayStartOptions shape:
{
"provider": "hermes",
"containerConfig": {
"image": "ghcr.io/example/hermes:latest",
"additionalMounts": [],
"timeout": 1800000,
"idleTimeout": null
},
"host": "127.0.0.1",
"port": 39050
}
ModelSummary has modelId, displayName, and contextWindow. SendMessageRequest has provider, channelId, content, and optional idempotencyKey. Message content is limited to 64 KiB and the idempotency key to 256 bytes.
Provider event stream¶
GET /autonomous/events is an authenticated Server-Sent Events stream. The SSE event field is the ProviderEvent.type value and the data field is the complete JSON event. Current variants are:
| SSE event | Payload |
|---|---|
gateway_status_changed | provider, status, optional sanitized error |
channel_updated | provider, channel |
message_received | provider, message |
skill_updated | provider, skill |
model_sync_changed | provider, status |
install_progress | progress with provider, stage, percent, and sanitized message |
governance_event | provider and the pending approval request |
lagged | {}; the subscriber missed broadcast entries and must refetch current state |
The server sends a ping keepalive every 15 seconds. A process-wide subscriber cap protects the event broadcaster; a connection beyond the cap receives 429.
The same provider events are mirrored onto the application event bus. The compatibility envelope is autonomous:provider_event. Typed bus names are autonomous:gateway-status-changed, autonomous:channel-updated, autonomous:message-received, autonomous:skill-updated, autonomous:model-sync-changed, autonomous:install-progress, and autonomous:governance-event. Consumers must tolerate gaps and refetch state after lagged.
Hermes profiles and migration¶
| Method | Path | Scope | Body or query | Returns |
|---|---|---|---|---|
GET | /autonomous/hermes/profiles | container_read | none | HermesProfile[] |
POST | /autonomous/hermes/profiles | container_write | { "name": string, "description"?: string } | HermesProfile |
POST | /autonomous/hermes/profiles/active | container_write | { "name": string } | 204 |
POST | /autonomous/hermes/migrate-claw | container_write | MigrateClawOptions | MigrateClawReport |
Profile names use lowercase letters, digits, underscores, and hyphens, start with a letter or digit, and are at most 64 characters. A profile response contains name, path, isDefault, createdAt, optional lastActiveAt, and optional description.
Migration accepts dryRun, preset (user_data or full), and targetProfile. The report contains dryRun, items, warnings, and optional error. Run a dry run first. Migration never deletes the OpenClaw source directory and never reads raw secret values from it.
Hermes MCP servers¶
| Method | Path | Scope | Body or query | Returns |
|---|---|---|---|---|
GET | /autonomous/hermes/mcp-servers | container_read | none | HermesMcpServer[] |
POST | /autonomous/hermes/mcp-servers | container_write | HermesMcpServer | 204 |
DELETE | /autonomous/hermes/mcp-servers/{id} | container_write | none | 204 |
POST | /autonomous/hermes/mcp-servers/reload | container_write | none | ReloadResult |
HermesMcpServer contains id, name, command, args, env, scope, and enabled. Scope is profile, user, or system. Registration and removal persist first, then request a daemon reload when the gateway supports it. ReloadResult.status is reloaded, gateway_not_running, unsupported, or error.
Treat values in the MCP env map as secrets at the client boundary. Do not print them in logs or command history.
Hermes settings and approvals¶
| Method | Path | Scope | Body or query | Returns |
|---|---|---|---|---|
POST | /autonomous/hermes/settings/folder-permissions | container_write | { "profile": string, "permissions": HermesFolderPermissions } | HermesProfileSettings |
POST | /autonomous/hermes/settings/container-limits | container_write | { "profile": string, "limits": HermesContainerLimits } | HermesProfileSettings |
POST | /autonomous/hermes/settings/approve | container_write | { "requestId": string, "decision": ApprovalDecision } | ApprovalAppliedResponse |
GET | /autonomous/hermes/settings/pending-approvals | container_read | none | PendingApprovalRequest[] |
GET | /autonomous/hermes/settings/approval-history | container_read | ?limit= | ApprovalHistoryEntry[] |
GET | /autonomous/hermes/settings/profiles/{profile} | container_read | none | HermesProfileSettings |
A folder permission contains path, level, recursive, and optional description. A profile accepts at most 64 entries. Container limits are optional cpuShares, memoryMib, and pidsLimit values.
An approval decision is either { "decision": "approve" } or { "decision": "deny", "reason": "..." }. Pending rows include the request id, profile, operation and target ids, description, actor label, creation time, and a redacted payloadSummary. Applied decisions move to history.
Hermes platform credentials¶
| Method | Path | Scope | Body or query | Returns |
|---|---|---|---|---|
POST | /autonomous/hermes/platforms/{platform}/credentials | container_write | SetPlatformCredentialsRequest | HermesPlatformBinding |
DELETE | /autonomous/hermes/platforms/{platform}/credentials | container_write | none | HermesPlatformBinding |
POST | /autonomous/hermes/platforms/{platform}/test | container_write | none | PlatformConnectionTestReport |
Supported platform identifiers are whatsapp, telegram, slack, discord, imessage, signal, teams, matrix, mattermost, email, sms, dingtalk, feishu, wecom, bluebubbles, home_assistant, and google_chat.
Desktop callers pre-store secret values and send a fieldNames map from field names to secure-storage handles. Authenticated headless callers may send a secrets map. The service writes those values immediately to server-side secure storage under server-derived keys. Raw values are never returned, logged, persisted in the Hermes binding, or emitted as an event. Responses contain only binding metadata such as credentialsRef and credentialsSet.
The platform in the JSON body must match {platform} in the URL. A mismatch is rejected with 400.
Walkthroughs¶
Set the base URL and an access key before running the examples:
Detect and install Hermes¶
curl -sS -H "X-API-Key: $AIGO_API_KEY" \
"$AIGO_URL/autonomous/providers/hermes/environment"
curl -sS -X POST -H "X-API-Key: $AIGO_API_KEY" \
"$AIGO_URL/autonomous/providers/hermes/install"
Installation returns 202 after the operation completes. Subscribe to /autonomous/events before the POST when you need install_progress updates.
Start and inspect the gateway¶
curl -sS -X POST \
-H "X-API-Key: $AIGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"provider":"hermes","containerConfig":{"image":"ghcr.io/example/hermes:latest","additionalMounts":[],"timeout":1800000,"idleTimeout":null},"host":"127.0.0.1","port":39050}' \
"$AIGO_URL/autonomous/providers/hermes/gateway/start"
curl -sS -H "X-API-Key: $AIGO_API_KEY" \
"$AIGO_URL/autonomous/providers/hermes/gateway"
Replace the example image with the image configured for your Hermes installation.
Set and test Telegram credentials¶
read -rsp "Telegram bot token: " TELEGRAM_BOT_TOKEN
jq -n --arg token "$TELEGRAM_BOT_TOKEN" \
'{platform:"telegram",fieldNames:{},secrets:{botToken:$token}}' | \
curl -sS -X POST \
-H "X-API-Key: $AIGO_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- \
"$AIGO_URL/autonomous/hermes/platforms/telegram/credentials"
unset TELEGRAM_BOT_TOKEN
curl -sS -X POST -H "X-API-Key: $AIGO_API_KEY" \
"$AIGO_URL/autonomous/hermes/platforms/telegram/test"
This example requires jq and sends the token through standard input instead of a process argument. Use an HTTPS Management API endpoint when sending inline secrets over a non-loopback network.
Decide a pending approval¶
curl -sS -H "X-API-Key: $AIGO_API_KEY" \
"$AIGO_URL/autonomous/hermes/settings/pending-approvals"
curl -sS -X POST \
-H "X-API-Key: $AIGO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"requestId":"replace-with-pending-id","decision":{"decision":"approve"}}' \
"$AIGO_URL/autonomous/hermes/settings/approve"
Legacy /claw routes¶
The server still accepts 36 routes under /claw for older desktop clients. They are deliberately excluded from Swagger and new CLI coverage because they duplicate the canonical provider-neutral API, retain desktop-specific shapes, and cannot work on a headless server. New integrations must use /autonomous/providers/claw/* and /autonomous/hermes/migrate-claw.
The explicit /claw OpenAPI exemption is a compatibility decision, not an undocumented current API. Removing those routes requires a separate compatibility and release decision.
CLI¶
The aigo autonomous command group covers every /autonomous route. See the CLI reference for provider commands, Hermes subcommands, input-file forms, and event following.