Skip to content
Hoody.com

These endpoints read and mutate the agent’s process-wide settings, manage model-fusion composites, and configure BYOA (bring-your-own-agent) ACP backend delegates (currently claude) and their per-backend secrets. Use them when you need to inspect the effective merged settings, edit the home ~/.hoody/settings.json via a shallow patch, manage custom fusion models, or arm/disarm a delegated ACP backend and pin its default model or per-agent env secrets.

Returns the effective merged settings (home → project → settings.local.json, top-level merge) plus the home-layer object that settings.patch mutates. Process-wide config (global/no-realm): settings have no realm dimension at any layer, so a per-request realm header returns 400 realm_scope_unsupported.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
{
"settings": {
"model": "claude-sonnet-4.5",
"theme": "dark",
"verbose": true
},
"home": {
"model": "claude-sonnet-4.5",
"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.getSettings();

Applies a SHALLOW top-level merge into the home ~/.hoody/settings.json (a null value deletes a key). Top-level only: sending {"features":{...}} REPLACES the whole features object. Process-wide config (global/no-realm): settings have no realm dimension, so a per-request realm header returns 400 realm_scope_unsupported.

SECURITY: security-load-bearing keys (deny_list, deny_urls, features, allowed_directories, hooks, disableAllHooks, mcp_servers, tools) cannot be modified over HTTP and return 403 settings_key_protected — edit settings.json at the host to change a guardrail (except mcp_servers, which is managed via the /api/v1/agent/mcp/* routes). A non-null top-level model is rejected 400: nothing consumes it (pin a model on the chat agent via PATCH /agents/{name}/model, or switch a live session via PATCH /sessions/{id}/model); {"model": null} still deletes a previously-persisted value. Returns the resulting home object.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
FieldTypeRequiredDescription
patchobjectYesTop-level keys to merge into the home settings.json (a null value deletes the key).
{
"patch": {
"theme": "dark",
"verbose": false,
"model": null
}
}
{
"model": "claude-sonnet-4.5",
"theme": "dark",
"verbose": false
}
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.patchSettings({ patch: { theme: 'dark', verbose: false, model: null } });

Lists the persisted model-fusion composites (fusion.list). 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 editable/deletable. Global/no-realm: composites are process-wide config with no realm dimension, so a per-request realm header returns 400 realm_scope_unsupported.

NameInTypeRequiredDescription
include_invalidquerybooleanNoWhen true, also return composites that failed validation as a top-level invalid array beside items (each with a reason + raw-file index) so a broken composite is editable/deletable.
pagequeryintegerNo1-based page number for pagination.
limitqueryintegerNoMaximum items per page (0 = no pagination).
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
{
"items": [
{
"slug": "balanced-ensemble",
"name": "Balanced Ensemble",
"method": "weighted-vote",
"members": [
{ "model": "claude-sonnet-4.5", "weight": 0.6 },
{ "model": "o1-mini", "weight": 0.4 }
],
"context_window": 200000
}
],
"meta": {
"total": 1,
"page": 1,
"limit": 20
}
}
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.listFusionIterator({ page: 1, limit: 20 });

Creates or updates a model-fusion composite keyed by slug (fusion.upsert). The body is the daemon FusionSpec under spec. 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.

NameInTypeRequiredDescription
slugpathstringYesPath identifier.
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
FieldTypeRequiredDescription
specobjectYesThe FusionSpec object (name, method, members, …).
{
"spec": {
"name": "Balanced Ensemble",
"method": "weighted-vote",
"members": [
{ "model": "claude-sonnet-4.5", "weight": 0.6 },
{ "model": "o1-mini", "weight": 0.4 }
],
"context_window": 200000
}
}
{
"slug": "balanced-ensemble",
"saved": 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.settings.upsertFusion('balanced-ensemble', {
spec: {
name: 'Balanced Ensemble',
method: 'weighted-vote',
members: [
{ model: 'claude-sonnet-4.5', weight: 0.6 },
{ model: 'o1-mini', weight: 0.4 }
],
context_window: 200000
}
});

DELETE /api/v1/agent/settings/fusion/{slug}

Section titled “DELETE /api/v1/agent/settings/fusion/{slug}”

Removes a model-fusion composite by slug (fusion.delete).

NameInTypeRequiredDescription
slugpathstringYesPath identifier.
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
{
"slug": "balanced-ensemble",
"removed": 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.settings.deleteFusion('balanced-ensemble');

Reports the BYOA delegated-session backend availability (claude) — enabled flag, on-PATH status, trust posture (acp.status). A fixed status object, NOT a paginated collection.

The report is resolved through the layered settings the delegated session would use, so X-Hoody-Config-Dir (override) and X-Hoody-Cwd (project layer) are folded. For remote BYOA, a bound X-Hoody-Container switches the report to on-container detection/login probing, and X-Hoody-Realm scopes that probe (threaded as realm_selector). A realm header WITHOUT a container returns 400 realm_scope_unsupported (the local report has no realm dimension).

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
{
"agent": "claude",
"enabled": true,
"on_path": true,
"trust": "verified",
"version": "1.0.27"
}
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.getACPStatus();

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 (acp.set_enabled). A delegated session — POST /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. Returns 404 unknown_agent for anything that is not a known BYOA backend (claude).

NameInTypeRequiredDescription
agentpathstringYesPath identifier.
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
FieldTypeRequiredDescription
enabledbooleanNotrue arms the backend; false disarms it. Defaults to true when omitted.
{
"enabled": true
}
{
"agent": "claude",
"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.settings.setACPEnabled('claude', { enabled: true });

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 (acp.set_agent_model). 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. Returns 404 unknown_agent for anything that is not a known BYOA backend (claude).

NameInTypeRequiredDescription
agentpathstringYesPath identifier.
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
FieldTypeRequiredDescription
modelstringNoBackend model id or alias. Empty clears the pin.
effortstringNoReasoning effort (backend-specific; empty clears).
{
"model": "claude-sonnet-4.5",
"effort": "high"
}
{
"agent": "claude",
"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.settings.setACPAgentModel('claude', { model: 'claude-sonnet-4.5', effort: 'high' });

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 (acp.set_secret) in the dedicated 0600 ~/.hoody/acp-secrets.env store under acp/<agent>/<ENVKEY> (atomic temp+rename, flock). settings.json holds only the env KEY NAMES; the VALUE lives ONLY in the 0600 store. An empty value DELETES (unsets) the reference.

SECURITY: the value is NEVER returned — the reply confirms only (agent, key, stored|cleared). Returns 404 unknown_agent for an agent that is not a known BYOA backend (claude).

NameInTypeRequiredDescription
agentpathstringYesPath identifier.
keypathstringYesPath identifier.
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a cwd (e.g. POST /todos; createTodo also accepts a body cwd).
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header (read only when the header is absent): "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
FieldTypeRequiredDescription
valuestringNoThe env secret value. Empty string clears (unsets) the reference. Stored only in the 0600 acp-secrets.env store.
{
"value": "sk-ant-api03-replace-me"
}
{
"agent": "claude",
"key": "ANTHROPIC_API_KEY",
"stored": true,
"cleared": false
}
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.setACPSecret('claude', 'ANTHROPIC_API_KEY', { value: 'sk-ant-api03-replace-me' });