Agent loops are scheduled, self-prompting recurrences attached to an agent session. Each loop fires a prompt on a configured interval with optional cost and wall-clock ceilings, and runs off a dedicated loop lane rather than the regular command channel. Use the endpoints on this page to list, create, immediately fire, update, or delete loops scoped to a single session. Per-request realm headers are rejected on these routes because loops are session-frozen; open a realm-scoped session instead.
Lists the recurring loops scheduled for a session (loops.list). The response is the standard kit list envelope { items, meta: { total } }, with optional page / limit pagination applied gateway-side (the underlying snapshot is session-scoped, so the page window is applied after the daemon returns).
Per-request working-directory scope for 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.
X-Hoody-Container
header
string
No
Per-request bound remote container (omit for 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=). Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realm
query
string
No
Query-string alias of the X-Hoody-Realm header (read only when the header is absent). Same accepted values and rejection rules.
Creates a recurring loop on a session (loops.create). Configure the interval, an optional stop_when predicate, a run cap (max_runs), and optional cost / wall-clock ceilings. Loop fires use the dedicated loop lane, not the command channel.
"prompt":"Summarize the last 24 hours of GitHub issues and post a digest",
"interval":"30m",
"maxRuns":0,
"stopWhen":"all_issues_acknowledged",
"maxCostUsd":5,
"maxWallMs":120000,
"paused":false,
"runCount":0,
"nextRunAt":"2026-03-04T14:00:00Z"
}
{
"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 realm header was supplied to an active-only / global-no-realm RPC.
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 reach the service through the public endpoint.
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.
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).
Fires a loop’s next run immediately (loops.run_now) on the dedicated loop lane. The session id and loop id come from the path; the body is optional and forwarded to the daemon as-is (reserved _-prefixed keys are ignored, and the per-request cwd / config-dir scope is applied automatically).
This endpoint accepts an optional JSON object. No specific fields are defined — any non-reserved keys are forwarded to the daemon loops.run_now RPC as pass-through.
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.
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 reach the service through the public endpoint.
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.
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).
Updates a loop by body shape. Set exactly one intent per request — the server dispatches to one of three underlying RPCs and rejects requests that mix intents with 400:
Run state (paused) — dispatches loops.set_state (true pauses, false resumes).
Expiry (expires_in) — dispatches loops.set_expiry (duration-from-now token, e.g. "2h"; "" or "never" clears).
Budget (max_cost_usd and/or max_wall_ms) — dispatches loops.update to set / revive the cost and wall-clock ceilings only. interval and prompt are not changeable in v1.
The request was malformed or carried invalid parameters (including mixing more than one update intent).
Correct the request body or query parameters; send only one of paused, expires_in, max_cost_usd, max_wall_ms.
realm_scope_unsupported
Realm scope unsupported
A per-request realm header was supplied to an active-only / global-no-realm RPC.
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 reach the service through the public endpoint.
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.
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).
Deletes a recurring loop from a session (loops.delete). The session id and loop id come from the path; the body is optional and forwarded to the daemon as-is (reserved _-prefixed keys are ignored, and the per-request cwd / config-dir scope is applied automatically).
This endpoint accepts an optional JSON object. No specific fields are defined — any non-reserved keys are forwarded to the daemon loops.delete RPC as pass-through.