# File System Watchers

**Page:** api/watch

[Download Raw Markdown](./api/watch.md)

---

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



The File System Watchers API lets you create and manage file system watchers that monitor paths for changes and stream events in real time via Server-Sent Events (SSE) or WebSocket connections. Use these endpoints to configure watchers, retrieve event history, and subscribe to live event streams.

## Health

### `GET /api/v1/watch/health`

Check the health status of the watch service.

This endpoint takes no parameters.



```bash
curl https://api.hoody.com/api/v1/watch/health
```


```typescript
const health = await client.watch.health.check();
```


Service is healthy.
```json
{
  "status": "ok",
  "service": "watch",
  "started": "2026-02-11T08:00:00Z",
  "pid": 12345,
  "ip": "10.0.0.1",
  "built": "2026-02-10T12:00:00Z",
  "fds": 128,
  "memory": {
    "rss": 52428800,
    "heap": 31457280
  },
  "userAgent": "hoody-sdk/1.0"
}
```



## Watchers

### `GET /watchers`

List all configured file system watchers with pagination.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `page` | query | integer | No | Page number (1-based). |
| `limit` | query | integer | No | Items per page (1-200). |



```bash
curl "https://api.hoody.com/watchers?page=1&limit=20"
```


```typescript
const watchers = await client.watch.watchers.listIterator({
  page: 1,
  limit: 20
});
```


Watcher list.
```json
{
  "items": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "created_at": "2026-02-11T08:00:00Z",
      "config": {
        "paths": ["/home/user/documents"],
        "recursive": true,
        "include": ["*.txt", "*.md"],
        "exclude": ["*.tmp"],
        "ignore_dirs": ["node_modules", ".git"],
        "kinds": ["created", "modified", "removed"],
        "coalesce_ms": 100,
        "history_size": 1000,
        "history_limit_bytes": 10485760
      },
      "stats": {
        "events_seen": 42,
        "events_broadcast": 38,
        "events_dropped": 0,
        "stream_errors": 0,
        "active_clients": 1
      }
    }
  ],
  "page": 1,
  "limit": 20,
  "total": 1
}
```


Invalid pagination.
```json
{
  "code": "INVALID_PAGINATION",
  "message": "Limit must be between 1 and 200",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INVALID_REQUEST` | Invalid request | Request payload failed validation | Check request fields and retry |
| `INVALID_PAGINATION` | Invalid pagination | Page or limit is out of range | Use page &ge; 1 and limit between 1 and 200 |



### `POST /watchers`

Create a new file system watcher.

The request body is defined by the `watch_CreateWatcherRequest` schema.



```bash
curl -X POST https://api.hoody.com/watchers \
  -H "Content-Type: application/json" \
  -d '{
    "paths": ["/home/user/documents"],
    "recursive": true,
    "include": ["*.txt", "*.md"],
    "exclude": ["*.tmp"],
    "ignore_dirs": ["node_modules"],
    "kinds": ["created", "modified", "removed"],
    "coalesce_ms": 100,
    "history_size": 1000
  }'
```


```typescript
const watcher = await client.watch.watchers.create({
  paths: ["/home/user/documents"],
  recursive: true,
  include: ["*.txt", "*.md"],
  exclude: ["*.tmp"],
  ignore_dirs: ["node_modules"],
  kinds: ["created", "modified", "removed"],
  coalesce_ms: 100,
  history_size: 1000
});
```


Watcher created.
```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "created_at": "2026-02-11T08:00:00Z",
  "config": {
    "paths": ["/home/user/documents"],
    "recursive": true,
    "include": ["*.txt", "*.md"],
    "exclude": ["*.tmp"],
    "ignore_dirs": ["node_modules"],
    "kinds": ["created", "modified", "removed"],
    "coalesce_ms": 100,
    "history_size": 1000,
    "history_limit_bytes": 10485760
  },
  "stats": {
    "events_seen": 0,
    "events_broadcast": 0,
    "events_dropped": 0,
    "stream_errors": 0,
    "active_clients": 0
  }
}
```


Invalid request.
```json
{
  "code": "INVALID_REQUEST",
  "message": "path list cannot be empty",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INVALID_REQUEST` | Invalid request | Request payload failed validation | Check request fields and retry |
| `INVALID_PAGINATION` | Invalid pagination | Page or limit is out of range | Use page &ge; 1 and limit between 1 and 200 |


Watcher or path limits exceeded.
```json
{
  "code": "LIMIT_EXCEEDED",
  "message": "watcher limit reached",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `LIMIT_EXCEEDED` | Resource limit exceeded | Watcher or path limits exceeded | Reduce paths or delete unused watchers |
| `HISTORY_GAP` | Replay history gap | Requested since_id is older than retained replay history | Reconnect without since_id or increase history_memory_limit_bytes |


Internal server error.
```json
{
  "code": "WATCHER_START_FAILED",
  "message": "failed to start watcher: inotify watch limit reached",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_START_FAILED` | Watcher startup failed | Backend failed to initialize file watcher | Check path permissions and kernel watch limits |



### `GET /watchers/{id}`

Get details for a specific watcher.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Watcher id |



```bash
curl https://api.hoody.com/watchers/a1b2c3d4-e5f6-7890-abcd-ef1234567890
```


```typescript
const watcher = await client.watch.watchers.get({
  id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
});
```


Watcher details.
```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "created_at": "2026-02-11T08:00:00Z",
  "config": {
    "paths": ["/home/user/documents"],
    "recursive": true,
    "include": ["*.txt", "*.md"],
    "exclude": ["*.tmp"],
    "ignore_dirs": ["node_modules", ".git"],
    "kinds": ["created", "modified", "removed"],
    "coalesce_ms": 100,
    "history_size": 1000,
    "history_limit_bytes": 10485760
  },
  "stats": {
    "events_seen": 42,
    "events_broadcast": 38,
    "events_dropped": 0,
    "stream_errors": 0,
    "active_clients": 1
  }
}
```


Watcher not found.
```json
{
  "code": "WATCHER_NOT_FOUND",
  "message": "Watcher not found",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_NOT_FOUND` | Watcher not found | No watcher exists for provided id | List watchers and use a valid watcher id |



### `DELETE /watchers/{id}`

Delete a file system watcher and stop all associated streams.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Watcher id |



```bash
curl -X DELETE https://api.hoody.com/watchers/a1b2c3d4-e5f6-7890-abcd-ef1234567890
```


```typescript
await client.watch.watchers.delete({
  id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
});
```


Watcher deleted.
```json
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "deleted": true
}
```


Watcher not found.
```json
{
  "code": "WATCHER_NOT_FOUND",
  "message": "Watcher not found",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_NOT_FOUND` | Watcher not found | No watcher exists for provided id | List watchers and use a valid watcher id |



## Event Streaming

### `GET /watchers/{id}/events`

Retrieve paginated event history for a watcher. Use `since_id` or `since_timestamp` to replay events from a specific point.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Watcher id |
| `since_id` | query | integer | No | Replay events strictly after this event id. |
| `since_timestamp` | query | string | No | Replay events strictly after this timestamp. Accepted formats: RFC3339 (e.g. `2026-02-11T15:30:00Z`), Unix seconds (e.g. `1739287800`), Unix milliseconds (e.g. `1739287800123`). |
| `page` | query | integer | No | Page number (1-based). |
| `limit` | query | integer | No | Items per page (1-200). |



```bash
curl "https://api.hoody.com/watchers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/events?page=1&limit=50"
```


```typescript
const events = await client.watch.streams.listEventsIterator({
  id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  page: 1,
  limit: 50
});
```


Watcher event history.
```json
{
  "items": [
    {
      "id": 1739287800001,
      "watcher_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "kind": "modified",
      "path": "/home/user/documents/notes.txt",
      "timestamp": "2026-02-11T15:30:00Z",
      "is_dir": false,
      "new_size_bytes": 2048,
      "old_size_bytes": 1024,
      "old_path": null,
      "details": null
    }
  ],
  "page": 1,
  "limit": 50,
  "total": 1,
  "newest_available_id": 1739287800001,
  "newest_available_timestamp": "2026-02-11T15:30:00Z",
  "oldest_available_id": 1739287800001,
  "oldest_available_timestamp": "2026-02-11T15:30:00Z"
}
```


Invalid query.
```json
{
  "code": "INVALID_PAGINATION",
  "message": "Limit must be between 1 and 200",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INVALID_REQUEST` | Invalid request | Request payload failed validation | Check request fields and retry |
| `INVALID_PAGINATION` | Invalid pagination | Page or limit is out of range | Use page &ge; 1 and limit between 1 and 200 |


Watcher not found.
```json
{
  "code": "WATCHER_NOT_FOUND",
  "message": "Watcher not found",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_NOT_FOUND` | Watcher not found | No watcher exists for provided id | List watchers and use a valid watcher id |


Replay history gap.
```json
{
  "code": "HISTORY_GAP",
  "message": "Requested since_id is older than available replay history",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `LIMIT_EXCEEDED` | Resource limit exceeded | Watcher or path limits exceeded | Reduce paths or delete unused watchers |
| `HISTORY_GAP` | Replay history gap | Requested since_id is older than retained replay history | Reconnect without since_id or increase history_memory_limit_bytes |



### `GET /watchers/{id}/events/sse`

Stream watcher events in real time via Server-Sent Events (SSE). The connection remains open and emits events as they occur. Use `since_id` or `since_timestamp` to replay missed events before live streaming begins.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Watcher id |
| `since_id` | query | integer | No | Replay events strictly after this event id. |
| `since_timestamp` | query | string | No | Replay events strictly after this timestamp. Accepted formats: RFC3339 (e.g. `2026-02-11T15:30:00Z`), Unix seconds (e.g. `1739287800`), Unix milliseconds (e.g. `1739287800123`). |



```bash
curl -N "https://api.hoody.com/watchers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/events/sse?since_id=1739287800000"
```


```typescript
const stream = await client.watch.streams.streamSse({
  id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  since_id: 1739287800000
});
```


SSE stream established. The connection remains open and emits events as they occur.


Watcher not found.
```json
{
  "code": "WATCHER_NOT_FOUND",
  "message": "Watcher not found",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_NOT_FOUND` | Watcher not found | No watcher exists for provided id | List watchers and use a valid watcher id |


Replay history gap.
```json
{
  "code": "HISTORY_GAP",
  "message": "Requested since_id is older than available replay history",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `LIMIT_EXCEEDED` | Resource limit exceeded | Watcher or path limits exceeded | Reduce paths or delete unused watchers |
| `HISTORY_GAP` | Replay history gap | Requested since_id is older than retained replay history | Reconnect without since_id or increase history_memory_limit_bytes |


Too many stream clients.
```json
{
  "code": "MAX_CLIENTS_REACHED",
  "message": "Watcher has reached max stream clients",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MAX_CLIENTS_REACHED` | Too many clients | Watcher stream client limit reached | Disconnect idle clients or increase max_clients_per_watcher |



### `GET /watchers/{id}/events/ws`

Stream watcher events in real time via WebSocket. The connection is upgraded to a WebSocket and remains open, emitting events as they occur. Use `since_id` or `since_timestamp` to replay missed events before live streaming begins.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `id` | path | string | Yes | Watcher id |
| `since_id` | query | integer | No | Replay events strictly after this event id. |
| `since_timestamp` | query | string | No | Replay events strictly after this timestamp. Accepted formats: RFC3339 (e.g. `2026-02-11T15:30:00Z`), Unix seconds (e.g. `1739287800`), Unix milliseconds (e.g. `1739287800123`). |



```bash
curl -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  "https://api.hoody.com/watchers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/events/ws?since_id=1739287800000"
```


```typescript
const stream = await client.watch.streams.streamWs({
  id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  since_id: 1739287800000
});
```


WebSocket connection upgraded. The connection remains open and emits events as they occur.


Watcher not found.
```json
{
  "code": "WATCHER_NOT_FOUND",
  "message": "Watcher not found",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `WATCHER_NOT_FOUND` | Watcher not found | No watcher exists for provided id | List watchers and use a valid watcher id |


Replay history gap.
```json
{
  "code": "HISTORY_GAP",
  "message": "Requested since_id is older than available replay history",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `LIMIT_EXCEEDED` | Resource limit exceeded | Watcher or path limits exceeded | Reduce paths or delete unused watchers |
| `HISTORY_GAP` | Replay history gap | Requested since_id is older than retained replay history | Reconnect without since_id or increase history_memory_limit_bytes |


Too many stream clients.
```json
{
  "code": "MAX_CLIENTS_REACHED",
  "message": "Watcher has reached max stream clients",
  "details": null
}
```
| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MAX_CLIENTS_REACHED` | Too many clients | Watcher stream client limit reached | Disconnect idle clients or increase max_clients_per_watcher |