The agent’s log API exposes a redacted, cursor-paginated log stream plus stats, sources, and a download endpoint. Use these routes to surface logs in dashboards, build alerts, or back the Logs tab.
All routes are active-only : supplying X-Hoody-Realm or ?realm= returns 400 realm_scope_unsupported because logs have no realm dimension. Log entries are always redacted at the source. Read endpoints return the verbatim daemon action’s own object — treat the response shape as free-form.
Queries the active log stream (logs.query). Filters ride as query params (source, level, host, since, until). ?limit=N caps the result set (daemon default 200) and is forwarded; the stream paginates by cursor (since_seq/before_seq), not by page. For the live tail, use GET /api/v1/agent/logs/stream .
Name In Type Required Description sourcequery string No Filter to a log source/facet (see logsSources). levelquery string No Filter to a minimum log level. hostquery string No Filter to a host. sincequery string No Lower time/cursor bound (since_seq cursor passes through verbatim). untilquery string No Upper time bound. limitquery integer No Caps the result set (daemon default 200). A non-numeric value is rejected 400. X-Hoody-Cwdheader string No Per-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd. X-Hoody-Config-Dirheader string No Per-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector: global or a 24-hex id (also accepted as ?realm=). Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs " \
-H " Authorization: Bearer $HOODY_TOKEN " \
--data-urlencode " source=daemon " \
--data-urlencode " level=info " \
--data-urlencode " limit=50 "
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 . logs . queryLogs ({ source : ' daemon ' , level : ' info ' , limit : 50 });
" ts " : " 2025-03-14T19:02:11.482Z " ,
" message " : " served 47 entries since_seq=48905 "
" ts " : " 2025-03-14T19:02:10.001Z " ,
" session_id " : " sess_8a7c " ,
" message " : " permission prompt required "
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (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 … then platform then proxy), not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal error An unexpected error occurred while handling the request. Retry; if persistent, inspect the daemon logs.
Reads one log entry by ref, always redacted (logs.read_entry). The entry ref is the seq returned by queryLogs or carried in the SSE entry frame’s id field.
Name In Type Required Description refpath string Yes Entry reference (seq id). X-Hoody-Cwdheader string No Per-request working-directory scope. X-Hoody-Config-Dirheader string No Per-request --config-dir override. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector. Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs/entries/48911 " \
-H " Authorization: Bearer $HOODY_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 . logs . readLogEntry ( ' 48911 ' );
" ts " : " 2025-03-14T19:02:10.001Z " ,
" session_id " : " sess_8a7c " ,
" path " : " /srv/work/.hoody/state.json " ,
" message " : " permission prompt required "
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (not via the Hoody proxy) The request did not reach the service through the public endpoint. Reach the agent through hoody-proxy, not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal error An unexpected error occurred while handling the request. Retry; if persistent, inspect the daemon logs.
Lists the available log sources/facets (logs.sources). Use this to populate filter dropdowns.
Name In Type Required Description X-Hoody-Cwdheader string No Per-request working-directory scope. X-Hoody-Config-Dirheader string No Per-request --config-dir override. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector. Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs/sources " \
-H " Authorization: Bearer $HOODY_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 . logs . logsSources ();
{ " name " : " daemon " , " count " : 184233 },
{ " name " : " session " , " count " : 12044 },
{ " name " : " tool " , " count " : 88412 },
{ " name " : " llm " , " count " : 23011 },
{ " name " : " activity " , " count " : 14902 },
{ " name " : " events " , " count " : 2104 },
{ " name " : " proxy " , " count " : 8744 }
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (not via the Hoody proxy) The request did not reach the service through the public endpoint. Reach the agent through hoody-proxy, not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal error An unexpected error occurred while handling the request. Retry; if persistent, inspect the daemon logs.
Returns log volume and level statistics (logs.stats).
Name In Type Required Description X-Hoody-Cwdheader string No Per-request working-directory scope. X-Hoody-Config-Dirheader string No Per-request --config-dir override. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector. Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs/stats " \
-H " Authorization: Bearer $HOODY_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 . logs . logsStats ();
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (not via the Hoody proxy) The request did not reach the service through the public endpoint. Reach the agent through hoody-proxy, not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal error An unexpected error occurred while handling the request. Retry; if persistent, inspect the daemon logs.
Tails the active log stream over Server-Sent Events (logs.tail). The tail paginates with a cursor it advances each round (since_seq is the previous reply’s next_seq), so no row is skipped under load. The tail rides the same seq/replay convention the session stream uses:
an entry frame per redacted row carrying id: <seq> (a reconnecting client resumes via the Last-Event-ID header, which overrides ?since_seq);
a lagged frame with {code: "replay_gap"} when the caller’s cursor fell behind the ring;
periodic heartbeats (comment lines beginning :);
end on disconnect.
Filters ride query params (source, level, host, since_seq); ?limit caps each poll batch. Local sources only.
Name In Type Required Description sourcequery string No Filter the tail to a log source/facet. levelquery string No Filter to a minimum log level. hostquery string No Filter to a host. since_seqquery integer No Initial resume cursor (the Last-Event-ID header overrides it). A non-numeric value is rejected 400. limitquery integer No Caps each poll batch. A non-numeric value is rejected 400. Last-Event-IDheader string No SSE resume cursor: the gateway int64 seq to resume from; OVERRIDES the ?since_seq query param. Sent automatically by an SSE client on reconnect. X-Hoody-Cwdheader string No Per-request working-directory scope. X-Hoody-Config-Dirheader string No Per-request --config-dir override. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector. Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs/stream?source=daemon&level=info&limit=100 " \
-H " Authorization: Bearer $HOODY_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 . logs . streamLogs ({ source : ' daemon ' , level : ' info ' , limit : 100 });
data: {"seq":48912,"ts":"2025-03-14T19:02:11.482Z","level":"info","source":"daemon","host":"node-us","message":"served 47 entries since_seq=48905"}
data: {"seq":48913,"ts":"2025-03-14T19:02:13.014Z","level":"debug","source":"daemon","host":"node-us","message":"ringbuf snapshot taken"}
data: {"code":"replay_gap","since_seq":48913,"replay_seq":49001}
data: {"reason":"client_disconnect"}
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (not via the Hoody proxy) The request did not reach the service through the public endpoint. Reach the agent through hoody-proxy, not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal 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_unavailableService unavailable The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). Honor Retry-After and retry.
Streams the filtered, always-redacted log set as a download (Content-Disposition: attachment). format=jsonl (default, one wire row per line) or txt (human-readable).
Local sources export a point-in-time-consistent snapshot of the in-daemon ring, bounded at the seq observed when the export starts. source=activity|events|proxy exports one platform query page (default limit 2000) and marks the export partial when more remained. Every export ends with an in-band terminator:
jsonl: a final {"_hoody_export":{...}} line carrying rows/gap/partial — its absence means the download was truncated.
txt: a trailing # export: ... comment carrying the same fields.
Filters mirror the Logs tab exactly (source, min_level, comp, session_id, text, since, until, event, tool, model, status, method, min_status, max_status, errors_only, event_type, resource_type, container, kind, host); ?since_seq exports incrementally; ?limit caps total rows; ?filename overrides the download name (reduced to a safe basename).
Name In Type Required Description sourcequery string No Log source to export (see logsSources; one local source, one platform source, or omitted for all local sources). min_levelquery string No Minimum log level (debug|info|warn|error). compquery string No Component filter (daemon source). session_idquery string No Session id filter. textquery string No Case-insensitive substring filter over message+attrs. sincequery string No Lower time bound (RFC3339 or relative like 1h/7d). untilquery string No Upper time bound (RFC3339 or relative). eventquery string No Session lifecycle event filter (session source). toolquery string No Tool name filter (tool source). modelquery string No Model filter (llm source). statusquery string No Tool outcome filter: ok|error|cancelled (tool source). methodquery string No HTTP method filter (activity source). min_statusquery integer No Minimum HTTP status (activity source). max_statusquery integer No Maximum HTTP status (activity source). errors_onlyquery boolean No Only error rows (activity source; true/false). event_typequery string No Event type filter (events source). resource_typequery string No Resource type filter (events source). containerquery string No Container filter (proxy source; empty = all running realm containers). Maps to the daemon’s container_id filter. kindquery string No Proxy row kind: request|response|event (proxy source). hostquery string No Proxy URL host filter (exact or dot-aligned suffix). since_seqquery integer No Exclusive lower seq bound for incremental exports (local sources). limitquery integer No TOTAL row cap across the export (default: everything the snapshot matches; platform default 2000). formatquery string No Export format: jsonl (default) or txt. filenamequery string No Download filename override (reduced to a safe basename). X-Hoody-Cwdheader string No Per-request working-directory scope. X-Hoody-Config-Dirheader string No Per-request --config-dir override. X-Hoody-Containerheader string No Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. X-Hoody-Realmheader string No Per-request realm selector. Rejected (400 realm_scope_unsupported) on active-only routes. realmquery string No In-query alias of X-Hoody-Realm, read only when the header is absent. Same rejection semantics.
" https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.com/api/v1/agent/logs/export " \
-H " Authorization: Bearer $HOODY_TOKEN " \
-o logs-tool-2025-03-14.jsonl \
--data-urlencode " source=tool " \
--data-urlencode " min_level=warn " \
--data-urlencode " since=2025-03-14T00:00:00Z " \
--data-urlencode " format=jsonl " \
--data-urlencode " filename=tool-warnings.jsonl "
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 . exportLogs ({
since : ' 2025-03-14T00:00:00Z ' ,
filename : ' tool-warnings.jsonl '
{"seq":48912,"ts":"2025-03-14T19:02:11.482Z","level":"info","source":"daemon","host":"node-us","message":"served 47 entries since_seq=48905"}
{"seq":48911,"ts":"2025-03-14T19:02:10.001Z","level":"warn","source":"tool","host":"node-us","tool":"fs.write","session_id":"sess_8a7c","message":"permission prompt required"}
{"seq":48910,"ts":"2025-03-14T19:02:08.770Z","level":"error","source":"tool","host":"node-us","tool":"net.fetch","status":"error","message":"dial tcp: lookup api.example.com: no such host"}
{"_hoody_export":{"rows":3,"gap":false,"partial":false}}
" message " : " invalid request "
Error Code Title Description Resolution bad_requestBad request The request was malformed or carried invalid parameters. Correct the request body or query parameters. realm_scope_unsupportedRealm 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.
" message " : " request must arrive through the Hoody proxy "
Error Code Title Description Resolution forbiddenForbidden (not via the Hoody proxy) The request did not reach the service through the public endpoint. Reach the agent through hoody-proxy, not by connecting to the container directly.
" message " : " request rate limit exceeded "
Error Code Title Description Resolution rate_limitedToo 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_errorInternal 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_unavailableService unavailable The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). Honor Retry-After and retry.