# Agent: Loops

**Page:** api/agent/loops

[Download Raw Markdown](./api/agent/loops.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



The Loops API lets you schedule, list, update, delete, and immediately fire recurring self-prompting loops on an agent session. Use these endpoints to give an agent a heartbeat — a prompt that re-fires at a fixed interval with cost, wall-clock, and run-count budgets — or to manually kick off the next iteration. Loop firings run on a dedicated loop lane that is separate from the interactive command channel.

## List a session's loops

Returns every recurring loop scheduled for a session as the standard kit list envelope `{ items, meta: { total } }`. The `page` / `limit` window is applied gateway-side.

`GET /api/v1/agent/sessions/{id}/loops`

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Path identifier. |
| `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 (§6.1): the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a 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. |

### Response



```json
{
  "items": [
    {
      "loop_id": "lp_8c1f2a9d4e0b7c5f",
      "session_id": "sess_3a91e6c2b1d04f87",
      "prompt": "Check the latest CI run and summarize failures.",
      "interval": "30m",
      "max_runs": 0,
      "max_cost_usd": 5.0,
      "max_wall_ms": 0,
      "paused": false,
      "run_count": 14,
      "next_run_at": "2026-01-15T18:30:00Z"
    },
    {
      "loop_id": "lp_2d4e6f8a1c3b5d7e",
      "session_id": "sess_3a91e6c2b1d04f87",
      "prompt": "Poll the staging deploy webhook and post a status update.",
      "interval": "5m",
      "max_runs": 100,
      "max_cost_usd": 0,
      "max_wall_ms": 0,
      "paused": true,
      "run_count": 42,
      "expires_in": "2h"
    }
  ],
  "meta": {
    "total": 2,
    "page": 1,
    "limit": 50
  }
}
```


```json
{
  "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, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |


```json
{
  "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). Kit network-position trust. | Reach the agent through hoody-proxy (e.g. `hoody agent …` → platform → proxy), not by connecting to the container directly. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |



### SDK usage

```ts
const page = await client.agent.loops.listLoopsIterator({ id: "sess_3a91e6c2b1d04f87", page: 1, limit: 50 });
for await (const loop of page) {
  console.log(loop.loop_id, loop.prompt);
}
```

## Create a loop

Creates a recurring loop on a session with a prompt, interval, and optional budgets and stop predicate. Loop firings run on a dedicated loop lane, not the command channel.

`POST /api/v1/agent/sessions/{id}/loops`

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Path identifier. |
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a 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. |

### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `prompt` | string | Yes | The prompt fired each loop run. |
| `interval` | string | No | Run interval (duration token, e.g. `"30m"`). |
| `max_runs` | integer | No | Stop after this many runs (0 = unlimited). |
| `stop_when` | string | No | Optional stop predicate evaluated each run. |
| `max_cost_usd` | number | No | Cost ceiling (0 = unlimited). |
| `max_wall_ms` | integer | No | Wall-clock ceiling in ms (0 = unlimited). |

### Response



```json
{
  "loop_id": "lp_8c1f2a9d4e0b7c5f",
  "session_id": "sess_3a91e6c2b1d04f87",
  "prompt": "Check the latest CI run and summarize failures.",
  "interval": "30m",
  "max_runs": 0,
  "max_cost_usd": 5.0,
  "max_wall_ms": 0,
  "paused": false,
  "created_at": "2026-01-15T18:00:00Z"
}
```


```json
{
  "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, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |


```json
{
  "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). Kit network-position trust. | Reach the agent through hoody-proxy (e.g. `hoody agent …` → platform → proxy), not by connecting to the container directly. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |



### SDK usage

```ts
const created = await client.agent.loops.createLoop({
  id: "sess_3a91e6c2b1d04f87",
  data: {
    prompt: "Check the latest CI run and summarize failures.",
    interval: "30m",
    max_cost_usd: 5.0,
  },
});
console.log(created.loop_id);
```

## Run a loop immediately

Fires the loop's next run immediately on the dedicated loop lane, independent of its scheduled interval.

`POST /api/v1/agent/sessions/{id}/loops/{loopId}/run-now`

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Path identifier. |
| `loopId` | path | string | Yes | Path identifier. |
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a 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. |

### Request body

This endpoint accepts an optional JSON object forwarded to the daemon `loops.run_now` RPC. The session id and loop id come from the path; the body is optional. No fields are required.

### Response



```json
{
  "loop_id": "lp_8c1f2a9d4e0b7c5f",
  "session_id": "sess_3a91e6c2b1d04f87",
  "triggered_at": "2026-01-15T18:05:32Z",
  "run_id": "run_77a2b1f0c9d34e58"
}
```


```json
{
  "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, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |


```json
{
  "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). Kit network-position trust. | Reach the agent through hoody-proxy (e.g. `hoody agent …` → platform → proxy), not by connecting to the container directly. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |



### SDK usage

```ts
const result = await client.agent.loops.runLoopNow({
  id: "sess_3a91e6c2b1d04f87",
  loopId: "lp_8c1f2a9d4e0b7c5f",
});
console.log(result.run_id);
```

## Update a loop

Updates a loop by body shape. Each request must express exactly one intent — mixing more than one is rejected with 400:

- **Run state** — set `paused` (`true` pauses, `false` resumes) → `loops.set_state`.
- **Expiry** — set `expires_in` (a duration-from-now token; `""` / `"never"` clears) → `loops.set_expiry`.
- **Budget revive** — set `max_cost_usd` and/or `max_wall_ms` (revives or updates the budget ceiling) → `loops.update`. This intent does **not** change `interval` or `prompt` in v1.


Loops are session-frozen: a per-request realm header is rejected with 400 `realm_scope_unsupported` on this route.


`PATCH /api/v1/agent/sessions/{id}/loops/{loopId}`

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Path identifier. |
| `loopId` | path | string | Yes | Path identifier. |
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a 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. |

### Request body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `paused` | boolean | No | Run-state intent → `loops.set_state` (true pauses, false resumes). |
| `expires_in` | string | No | Expiry intent → `loops.set_expiry` (duration-from-now token, e.g. `"2h"`; `""`/`"never"` clears). |
| `max_cost_usd` | number | No | Budget intent → `loops.update` (cost ceiling; 0 = unlimited). |
| `max_wall_ms` | integer | No | Budget intent → `loops.update` (wall-clock ceiling in ms, or a duration token; 0 = unlimited). |

### Response



```json
{
  "loop_id": "lp_8c1f2a9d4e0b7c5f",
  "session_id": "sess_3a91e6c2b1d04f87",
  "paused": true,
  "updated_at": "2026-01-15T18:10:00Z"
}
```


```json
{
  "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, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |


```json
{
  "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). Kit network-position trust. | Reach the agent through hoody-proxy (e.g. `hoody agent …` → platform → proxy), not by connecting to the container directly. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |



### SDK usage

```ts
// Pause the loop
await client.agent.loops.updateLoop({
  id: "sess_3a91e6c2b1d04f87",
  loopId: "lp_8c1f2a9d4e0b7c5f",
  data: { paused: true },
});
```

## Delete a loop

Permanently removes a recurring loop from a session.

`DELETE /api/v1/agent/sessions/{id}/loops/{loopId}`

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Path identifier. |
| `loopId` | path | string | Yes | Path identifier. |
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope (§6.1): the .hoody project layer / record cwd / tool+workflow cwd. Required by routes that resolve a 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. |

### Request body

This endpoint accepts an optional JSON object forwarded to the daemon `loops.delete` RPC. The session id and loop id come from the path; the body is optional. No fields are required.

### Response



```json
{
  "loop_id": "lp_8c1f2a9d4e0b7c5f",
  "session_id": "sess_3a91e6c2b1d04f87",
  "deleted": true,
  "deleted_at": "2026-01-15T18:20:00Z"
}
```


```json
{
  "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, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |


```json
{
  "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). Kit network-position trust. | Reach the agent through hoody-proxy (e.g. `hoody agent …` → platform → proxy), not by connecting to the container directly. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |


```json
{
  "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. |



### SDK usage

```ts
await client.agent.loops.deleteLoop({
  id: "sess_3a91e6c2b1d04f87",
  loopId: "lp_8c1f2a9d4e0b7c5f",
});
```