Agent Workflows let you define, manage, and run multi-step automations on a live session. A workflow definition is the static recipe (an ordered set of steps with an entry point); a workflow run is a live execution of that recipe against a particular session. Use these endpoints to list, read, create, replace, delete, or hide workflow definitions, to dispatch a workflow onto a session, and to inspect or cancel in-flight runs.
All routes are realm-scoped to the GATEWAY’s own realm and resolve definitions and runs through the per-request X-Hoody-Cwd / X-Hoody-Config-Dir headers. A client-supplied X-Hoody-Realm / ?realm= is accepted on read-only listing routes but rejected on the routing tables that have no realm dimension to scope.
List the workflow definitions visible to the requesting cwd / config_dir (name, summary, step briefs, system flag). Read one with GET /workflows/{name}; create or replace with PUT /workflows/{name}; delete with DELETE /workflows/{name}; hide with POST /workflows/{name}/hide.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
"summary": "Build the project and run smoke tests",
"system": false,
"steps": [
{ "id": "compile", "summary": "Run the build" },
{ "id": "test", "summary": "Run smoke tests" }
]
},
{
"name": "deploy",
"summary": "Deploy the built artifact to staging",
"system": true,
"steps": [
{ "id": "upload", "summary": "Upload artifact" },
{ "id": "promote", "summary": "Promote to staging" }
]
}
],
"meta": {
"total": 12,
"page": 1,
"limit": 50
}
}
{
"code": "realm_scope_unsupported",
"message": "realm scope not supported on this route"
}
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 realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"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.
Read one workflow definition as JSON. The result rides the {output, is_error} tool envelope; is_error: true with output"workflow X not found" for an unknown name.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
include_revision
query
boolean
No
If “true”, the tool output’s first line is revision: <opaque>“ — pass that value as putWorkflow’s expected_revision to guard against concurrent edits; the JSON below it is unchanged. Strictly parsed: exactly one value, “true” or “false”; anything else (empty, “TRUE”, “1”, repeated) is a 400 bad_request.
"summary": "Build the project and run smoke tests",
"system": false,
"entry_point": "compile",
"steps": [
{ "id": "compile", "summary": "Run the build" },
{ "id": "test", "summary": "Run smoke tests" }
]
},
"is_error": false
}
{
"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.
tool_mutation_refused
Tool mutation refused
A sessionless tool run resolved to a mutating tool with no confirmation posture. Sessionless runs are read-only by default.
Open a session and run the tool there, or supply allow_mutations:true / confirm:true on the sessionless run.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"code": "tool_not_found",
"message": "no tool with that name"
}
Error Code
Title
Description
Resolution
tool_not_found
Tool not found
No tool with the given name exists in the catalogue or in the session’s effective tool list.
List the catalogue (GET /tools) or the session’s tools (GET /sessions/{id}/tools) and use a valid name.
{
"code": "tool_needs_confirmation",
"message": "tool requires confirmation before execution"
}
Error Code
Title
Description
Resolution
tool_needs_confirmation
Tool needs confirmation
The tool was NOT executed: the gate chain (write-permission / dangerous-shape / outside-dir) requires confirmation first. The echoed tool+params let the caller re-issue the run with confirm:true.
Re-issue the run with confirm:true (or ?confirm=true), preserving the echoed params.
{
"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.
Create or replace one workflow definition. The body carries the definition object; the {name} path value is authoritative. The daemon validates the definition strictly before writing atomically (unknown fields rejected, the loader’s structural gate enforced), so a malformed definition is refused (is_error: true) rather than corrupting workflow.json. The system flag is authoritative from the embedded defaults — a caller cannot forge it.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
tool_mutation_refused
Tool mutation refused
A sessionless tool run resolved to a mutating tool with no confirmation posture. Sessionless runs are read-only by default.
Open a session and run the tool there, or supply allow_mutations:true / confirm:true on the sessionless run.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"code": "tool_not_found",
"message": "no tool with that name"
}
Error Code
Title
Description
Resolution
tool_not_found
Tool not found
No tool with the given name exists in the catalogue or in the session’s effective tool list.
List the catalogue (GET /tools) or the session’s tools (GET /sessions/{id}/tools) and use a valid name.
{
"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 (http.MaxBytesReader) before the handler reads it — a well-formed-but-large body is a size violation, not a JSON syntax error.
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.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
tool_mutation_refused
Tool mutation refused
A sessionless tool run resolved to a mutating tool with no confirmation posture. Sessionless runs are read-only by default.
Open a session and run the tool there, or supply allow_mutations:true / confirm:true on the sessionless run.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"code": "tool_not_found",
"message": "no tool with that name"
}
Error Code
Title
Description
Resolution
tool_not_found
Tool not found
No tool with the given name exists in the catalogue or in the session’s effective tool list.
List the catalogue (GET /tools) or the session’s tools (GET /sessions/{id}/tools) and use a valid name.
{
"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.
Hide or un-hide a workflow from the Workflows tab. Hiding is the only way to remove a SYSTEM workflow from view — system workflows are re-seeded on every boot and can never be deleted. User workflows can be hidden too. Pass hidden: false in the body to un-hide. The hide stays realm-private (the gateway’s own realm only); a client-supplied X-Hoody-Realm / ?realm= is ignored.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"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 (http.MaxBytesReader) before the handler reads it — a well-formed-but-large body is a size violation, not a JSON syntax error.
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.
{
"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).
Dispatch a workflow run onto a live session. The daemon returns no RunID synchronously, so the gateway mints its own job_id and correlates the daemon RunID lazily — job.run_id is null during the brief dispatch window and is populated once the workflow loop registers the run (observe workflow_start on the session’s stream). Run events flow on the owning session’s WS/SSE attach; there is no per-run event bus.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"code": "workflow_not_found",
"message": "no workflow named build"
}
Error Code
Title
Description
Resolution
not_found
Not found
The requested resource does not exist.
Verify the path and identifier.
workflow_not_found
Workflow not found
No workflow definition with the requested name is visible to this cwd/config_dir.
List the available workflows (GET /workflows) and use an existing name.
{
"code": "gate_parked",
"message": "a gate is parked on this session",
"details": {
"pending_gate": {
"generation": 3,
"id": "gate-3",
"type": "confirm"
}
}
}
Error Code
Title
Description
Resolution
turn_in_flight
Turn in flight
A turn is already running on this session; the single serial turn slot is occupied, so a new turn/workflow run is refused.
Wait for the running turn to finish (observe agent_done on the session stream), then retry.
gate_parked
Gate parked
A confirm/question gate is parked on this session, so a new turn/workflow run is refused until it is answered. The parked gate is surfaced under details.pending_gate.
Answer the parked gate (/confirm or /answer) and retry; read it via GET /sessions/{id} or details.pending_gate.
{
"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 (http.MaxBytesReader) before the handler reads it — a well-formed-but-large body is a size violation, not a JSON syntax error.
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.
{
"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).
Snapshot of in-flight and recently-finished workflow runs. The registry exposes Snapshot(), not Subscribe(), so poll this endpoint to track a run’s progress. Live events also flow on the owning session’s stream.
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
"message": "realm scope not supported on this route"
}
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 realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"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.
Get a single workflow run row by run id from the registry snapshot. Returns 404 not_found when the run id is no longer in the snapshot (evicted or never existed).
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"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).
Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-Dir
header
string
No
Per-request --config-dir override (§6.1) selecting which on-disk .hoody install a stateless read/write resolves (HoodyPaths).
X-Hoody-Container
header
string
No
Per-request bound remote container (§6.1; omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-Realm
header
string
No
Per-request realm selector (§6.1): "global" or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Per-request realm selector (§6.1) — 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.
The request was malformed or carried invalid parameters.
Correct the request body or query parameters.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC, which has no realm dimension to scope.
Omit the realm header on this route, or open a session to scope by realm.
{
"code": "forbidden",
"message": "request must arrive through the Hoody proxy"
}
Error Code
Title
Description
Resolution
forbidden
Forbidden (not via the Hoody proxy)
The request did not arrive through hoody-proxy: its source IP is private/local (in-container loopback, the bridge, the host, or a sibling container). The gateway has no service-level auth — authorization is owned by hoody-proxy, which is the only party that can reach it (TPROXY preserves the real public client IP).
Reach the agent through hoody-proxy (e.g. hoody agent … → platform → proxy), not by connecting to the container directly.
{
"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 (http.MaxBytesReader) before the handler reads it — a well-formed-but-large body is a size violation, not a JSON syntax error.
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.
{
"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).