Agent: Settings
Section titled “Agent: Settings”Get and patch the agent’s effective settings, manage model-fusion composites, and configure BYOA / ACP backend agents and their secrets. This page covers the read/write surface of settings.json, the persisted fusion.json, and the per-backend acp configuration that arms a delegated-session backend.
Settings, fusion, and ACP per-agent secret routes have no realm dimension; sending any realm or container scope header to them returns 400 realm_scope_unsupported. The ACP status, enablement, and model routes accept the X-Hoody-Realm header (or its ?realm= alias); on those routes realm_scope_unsupported fires only when the agent is pinned to a different realm.
Settings (read and patch)
Section titled “Settings (read and patch)”GET /api/v1/agent/settings
Section titled “GET /api/v1/agent/settings”Returns the effective merged settings (home, project, and settings.local.json combined by a top-level merge) plus the home-layer object that patchSettings mutates.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Hoody-Cwd | header | string | No | Per-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. |
X-Hoody-Config-Dir | header | string | No | Per-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves against. |
curl "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/settings" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.settings.get();{ "status": "ok", "settings": {}, "home": {}}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
{ "code": "forbidden", "message": "request must arrive through the Hoody proxy"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
PATCH /api/v1/agent/settings
Section titled “PATCH /api/v1/agent/settings”Applies a shallow top-level merge into the home settings.json. A null value deletes a key. The merge is top-level only: sending {"features":{...}} replaces the whole features object. Returns the resulting home object.
This endpoint takes no path, query, or header parameters.
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
patch | object | Yes | Top-level keys to merge into the home settings.json (a null value deletes the key). |
curl -X PATCH "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/settings" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"patch":{"locale":"en-US","theme":"dark"}}'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.settings.update({ patch: { locale: 'en-US', theme: 'dark' } });{ "locale": "en-US", "theme": "dark"}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
{ "code": "settings_key_protected", "message": "settings key 'deny_list' is security-load-bearing and cannot be modified over HTTP", "details": { "key": "deny_list" }}| Error Code | Title | Description | Resolution |
|---|---|---|---|
settings_key_protected | Settings key protected | The patch targets a security-load-bearing top-level settings key. These guardrail keys cannot be modified over HTTP. | Edit settings.json at the host to change a guardrail key; omit it from the HTTP patch. |
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "payload_too_large", "message": "request body exceeds the configured size limit"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
payload_too_large | Payload too large | The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
BYOA / ACP backends
Section titled “BYOA / ACP backends”These routes configure the BYOA delegated-session backend (claude). The status route folds X-Hoody-Config-Dir and X-Hoody-Cwd; for REMOTE BYOA, a bound X-Hoody-Container switches the report to on-container detection/login probing, and X-Hoody-Realm scopes that probe.
GET /api/v1/agent/acp/agents
Section titled “GET /api/v1/agent/acp/agents”Reports the BYOA delegated-session backend availability. A fixed status object, not a paginated collection.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
X-Hoody-Cwd | header | string | No | Per-request working-directory scope. |
X-Hoody-Config-Dir | header | string | No | Per-request --config-dir override. |
X-Hoody-Container | header | string | No | Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. |
X-Hoody-Realm | header | string | No | Per-request realm selector: global or a 24-hex id (also accepted as ?realm=). |
realm | query | string | No | In-query alias of the X-Hoody-Realm header. |
curl "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/acp/agents" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.acp.getStatus();{ "status": "ok", "report": { "agents": [ { "name": "claude", "enabled": true, "installed": true, "logged_in": "unknown", "startable": true } ] }}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
invalid_realm | Invalid realm selector | The realm selector is malformed (not ""/“global”/a 24-hex id). | Pass a valid realm selector. |
{ "code": "forbidden", "message": "request must arrive through the Hoody proxy"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "not_found", "message": "resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
restriction_unknown | Login restriction unknown | The agent cannot read yet which realms its login may serve (GET /hoody/auth/status reports restriction unknown), so it refuses realm-scoped requests until it can. Nothing was read or changed. | Retry after the restriction is readable. |
PUT /api/v1/agent/acp/agents/{agent}/enabled
Section titled “PUT /api/v1/agent/acp/agents/{agent}/enabled”Arms or disarms a BYOA ACP backend for delegated sessions. A delegated session (POST /api/v1/agent/sessions with backend:"acp") is refused by the daemon while its backend is disabled, so this is the prerequisite for the whole delegated-session capability on a host configured over HTTP. Writes tools.acp_agents.<agent>.enabled in settings.json. 404 unknown_agent for anything that is not a known BYOA backend (claude).
The SDK reaches this same operation through 2 named methods:
client.agent.acp.enable(agent)sets bodyenabled=true.client.agent.acp.disable(agent)sets bodyenabled=false.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
agent | path | string | Yes | The agent. |
X-Hoody-Realm | header | string | No | Per-request realm selector: “global” (not tied to a realm) or a 24-hex realm id (also accepted as ?realm=). On a session route it names the realm the session is looked up in: a session in another realm, or in a realm this login does not serve, is 404 not_found. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes, and for any other realm on an agent pinned to one realm. |
realm | query | string | No | Per-request realm selector, the in:query alias of the X-Hoody-Realm header (read only when the header is absent): “global” (not tied to a realm) or a 24-hex realm id. On a session route it names the realm the session is looked up in: a session in another realm, or in a realm this login does not serve, is 404 not_found. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes, and for any other realm on an agent pinned to one realm. |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
enabled | boolean | No | true arms the backend; false disarms it. Defaults to true when omitted. |
curl -X PUT "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/acp/agents/claude/enabled" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"enabled":true}'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.acp.enable('claude');// or, to disarm:// await client.agent.acp.disable('claude');{ "agent": "claude", "enabled": true}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
invalid_realm | Invalid realm selector | The realm selector is malformed (not ""/“global”/a 24-hex id). | Pass a valid realm selector. |
{ "code": "admin_unauthorized", "message": "memory administration requires a valid admin token"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
admin_unauthorized | Rejected by the daemon’s own admin gate | The daemon’s own administrator check refused the request. When started with a separate administrator token, the daemon refuses these operations because an HTTP request cannot supply that token. In the standard HTTP deployment the daemon has no such token and this code is not returned. | Run the daemon in the standard HTTP deployment, or perform the operation from the agent’s terminal interface inside the container. |
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "unknown_agent", "message": "unknown ACP agent: evilbot (known: claude)"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
unknown_agent | Unknown ACP agent | The named ACP agent is not a known BYOA backend, so a per-agent secret reference would be dead. | Use claude, the only BYOA backend. |
{ "code": "payload_too_large", "message": "request body exceeds the configured size limit"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
payload_too_large | Payload too large | The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
restriction_unknown | Login restriction unknown | The agent cannot read yet which realms its login may serve (GET /hoody/auth/status reports restriction unknown), so it refuses realm-scoped requests until it can. Nothing was read or changed. | Retry after the restriction is readable. |
PUT /api/v1/agent/acp/agents/{agent}/model
Section titled “PUT /api/v1/agent/acp/agents/{agent}/model”Sets the default model (and reasoning effort) a BYOA ACP backend runs on. These are the values the daemon passes to the backend at connect; a delegated session started without an explicit model inherits them. An empty value clears the pin and returns the backend to its own default. 404 unknown_agent for anything that is not a known BYOA backend (claude).
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
agent | path | string | Yes | The agent. |
X-Hoody-Realm | header | string | No | Per-request realm selector: “global” (not tied to a realm) or a 24-hex realm id (also accepted as ?realm=). On a session route it names the realm the session is looked up in: a session in another realm, or in a realm this login does not serve, is 404 not_found. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes, and for any other realm on an agent pinned to one realm. |
realm | query | string | No | Per-request realm selector, the in:query alias of the X-Hoody-Realm header (read only when the header is absent): “global” (not tied to a realm) or a 24-hex realm id. On a session route it names the realm the session is looked up in: a session in another realm, or in a realm this login does not serve, is 404 not_found. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes, and for any other realm on an agent pinned to one realm. |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
model | string | No | Backend model id or alias. Empty clears the pin. |
effort | string | No | Reasoning effort (backend-specific; empty clears). |
curl -X PUT "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/acp/agents/claude/model" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"model":"claude-sonnet-4-5","effort":"high"}'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.acp.setModel('claude', { model: 'claude-sonnet-4-5', effort: 'high' });{ "agent": "claude", "model": "claude-sonnet-4-5", "effort": "high"}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
invalid_realm | Invalid realm selector | The realm selector is malformed (not ""/“global”/a 24-hex id). | Pass a valid realm selector. |
{ "code": "admin_unauthorized", "message": "memory administration requires a valid admin token"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
admin_unauthorized | Rejected by the daemon’s own admin gate | The daemon’s own administrator check refused the request. When started with a separate administrator token, the daemon refuses these operations because an HTTP request cannot supply that token. In the standard HTTP deployment the daemon has no such token and this code is not returned. | Run the daemon in the standard HTTP deployment, or perform the operation from the agent’s terminal interface inside the container. |
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "unknown_agent", "message": "unknown ACP agent: evilbot (known: claude)"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
unknown_agent | Unknown ACP agent | The named ACP agent is not a known BYOA backend, so a per-agent secret reference would be dead. | Use claude, the only BYOA backend. |
{ "code": "payload_too_large", "message": "request body exceeds the configured size limit"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
payload_too_large | Payload too large | The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
restriction_unknown | Login restriction unknown | The agent cannot read yet which realms its login may serve (GET /hoody/auth/status reports restriction unknown), so it refuses realm-scoped requests until it can. Nothing was read or changed. | Retry after the restriction is readable. |
PUT /api/v1/agent/acp/agents/{agent}/secrets/{key}
Section titled “PUT /api/v1/agent/acp/agents/{agent}/secrets/{key}”Stores (or clears) one per-backend env value for a BYOA ACP agent in a dedicated owner-only secrets file inside the container. The agent settings hold only the env key names; the value lives only in that secrets file. An empty value deletes (unsets) the reference. Access is decided by the container’s proxy permission policy.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
agent | path | string | Yes | The agent. |
key | path | string | Yes | The key. |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
value | string | No | The env secret value. Empty string clears (unsets) the reference. Stored only in the agent’s owner-only secrets file. |
curl -X PUT "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/acp/agents/claude/secrets/ANTHROPIC_API_KEY" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"value":"sk-ant-EXAMPLE-redacted"}'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.acp.setSecret('claude', 'ANTHROPIC_API_KEY', { value: 'sk-ant-EXAMPLE-redacted' });{ "agent": "claude", "key": "ANTHROPIC_API_KEY", "stored": true, "cleared": false}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
{ "code": "admin_unauthorized", "message": "memory administration requires a valid admin token"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
admin_unauthorized | Rejected by the daemon’s own admin gate | The daemon’s own administrator check refused the request. When started with a separate administrator token, the daemon refuses these operations because an HTTP request cannot supply that token. In the standard HTTP deployment the daemon has no such token and this code is not returned. | Run the daemon in the standard HTTP deployment, or perform the operation from the agent’s terminal interface inside the container. |
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "unknown_agent", "message": "unknown ACP agent: evilbot (known: claude)"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
unknown_agent | Unknown ACP agent | The named ACP agent is not a known BYOA backend, so a per-agent secret reference would be dead. | Use claude, the only BYOA backend. |
{ "code": "payload_too_large", "message": "request body exceeds the configured size limit"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
payload_too_large | Payload too large | The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
Fusion composites
Section titled “Fusion composites”The fusion routes manage model-fusion composites persisted to fusion.json. Composites are addressed by slug. A composite with no usable slug, or one of two entries sharing a slug, cannot be deleted or repaired through this API: fix or remove those entries by editing fusion.json inside the container.
GET /api/v1/agent/settings/fusion
Section titled “GET /api/v1/agent/settings/fusion”Lists the persisted model-fusion composites. Pass ?include_invalid=true to also receive the entries that failed validation as a top-level invalid array beside items (each with the failure reason and its stable raw-file index; never mixed into or paginated with the selectable items) so a broken composite is diagnosable.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
include_invalid | query | boolean | No | When true, also return composites that failed validation as a top-level invalid array beside items. An entry with no usable slug, or a duplicate slug, cannot be deleted through this API. |
page | query | integer | No | 1-based page number for pagination. |
limit | query | integer | No | Maximum items per page (0 = no pagination). |
X-Hoody-Cwd | header | string | No | Per-request working-directory scope. |
X-Hoody-Config-Dir | header | string | No | Per-request --config-dir override. |
curl "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/settings/fusion?page=1&limit=50" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const item of client.agent.fusions.listIterator({ page: 1, limit: 50 })) { // process item}{ "items": [ { "name": "Balanced Ensemble", "method": "weighted", "members": [], "params": {} } ], "meta": { "total": 1, "page": 1, "limit": 50 }}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
{ "code": "forbidden", "message": "request must arrive through the Hoody proxy"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "not_found", "message": "resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
PUT /api/v1/agent/settings/fusion/{slug}
Section titled “PUT /api/v1/agent/settings/fusion/{slug}”Creates or updates a model-fusion composite keyed by slug. The composite is described by the spec object in the body. The persisted key is derived from spec.name (lowercased, separators collapsed to -); the path {slug} must normalize to the same slug or the request is rejected (400 slug_mismatch): the path cannot rename what the body describes. Structural invariants (name/method/members, cycle guard, non-zero context window) are validated server-side.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | Yes | The slug. |
X-Hoody-Cwd | header | string | No | Per-request working-directory scope. |
X-Hoody-Config-Dir | header | string | No | Per-request --config-dir override. |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
spec | object | Yes | The fusion definition (name, method, members, …). |
curl -X PUT "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/settings/fusion/balanced-ensemble" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "spec": { "name": "Balanced Ensemble", "method": "weighted", "members": [] } }'import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.fusions.set('balanced-ensemble', { spec: { name: 'Balanced Ensemble', method: 'weighted', members: [], },});{ "status": "ok", "fusion": { "name": "Balanced Ensemble", "method": "weighted", "members": [], "params": {} }}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
slug_mismatch | Path slug does not match spec.name | The path {slug} and the slug derived from body spec.name normalize to different values; the daemon persists by the spec.name-derived slug, so honoring the request would write a composite the URL does not name. | Use the spec.name-derived slug in the path (lowercase, separators collapsed to -), or change spec.name. |
{ "code": "forbidden", "message": "request must arrive through the Hoody proxy"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "not_found", "message": "resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
{ "code": "payload_too_large", "message": "request body exceeds the configured size limit"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
payload_too_large | Payload too large | The request body exceeds the configured size cap (MaxBodyBytes). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |
DELETE /api/v1/agent/settings/fusion/{slug}
Section titled “DELETE /api/v1/agent/settings/fusion/{slug}”Removes a model-fusion composite by slug.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | Yes | The slug. |
X-Hoody-Cwd | header | string | No | Per-request working-directory scope. |
X-Hoody-Config-Dir | header | string | No | Per-request --config-dir override. |
curl -X DELETE "https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/settings/fusion/balanced-ensemble" \ -H "Authorization: Bearer <token>"import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.agent.fusions.delete('balanced-ensemble');{ "status": "ok", "removed": true}| Error Code | Title | Description | Resolution |
|---|
{ "code": "bad_request", "message": "invalid request"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
bad_request | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
realm_scope_unsupported | Realm scope unsupported | A per-request scope header this route does not take: a realm or container header on a route without that dimension, or, on an agent pinned to one realm, a different realm. | Omit the header, or name the realm the agent is pinned to. |
{ "code": "forbidden", "message": "request must arrive through the Hoody proxy"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
forbidden | Forbidden (Source IP Guard) | The request did not come through the program’s URL. Hoody Kit programs are reached through their URLs only. | Call the agent through its URL, for example with hoody agent …. |
{ "code": "not_found", "message": "resource not found"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
not_found | Not found | The requested resource does not exist. | Verify the path and identifier. |
{ "code": "rate_limited", "message": "request rate limit exceeded"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
rate_limited | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the Retry-After header and retry; reduce the request rate. |
{ "code": "internal_error", "message": "internal server error"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
internal_error | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |
store_failed | Agent store failed | One of the agent’s own stores could not be read, parsed, locked, or written, so the operation did not complete. A damaged store is left as it was rather than rewritten. | Retry once; if it persists, repair the named store inside the container. The agent’s log (GET /logs) records a “store failure” entry with the store and failure kind. |
{ "code": "service_unavailable", "message": "service unavailable"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
service_unavailable | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor Retry-After and retry. |