# File Journal & Audit Log

**Page:** api/files/journal

[Download Raw Markdown](./api/files/journal.md)

---

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



## File Journal & Audit Log

Use these endpoints to query the file mutation journal, view journal storage statistics, and force pending entries to be flushed to disk. The journal records every file change event — including create, write, delete, move, copy, chmod, and chown operations — and supports cursor-based pagination for large result sets.

### Query journal entries

`GET /api/v1/journal`

Returns a paginated list of file mutation journal entries, filtered by path prefix, operation type, and timestamp. Use the `after_id` cursor to fetch subsequent pages when `has_more` is `true`.

### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `path` | query | string | No | Filter entries by path prefix |
| `op` | query | string | No | Filter by operation type(s), comma-separated (e.g. `write,delete`) |
| `since` | query | string | No | Filter entries since timestamp (RFC3339 or Unix ms) |
| `limit` | query | integer | No | Max entries to return |
| `after_id` | query | integer | No | Cursor: return entries with id > after_id |



```bash
curl -G "https://api.hoody.com/api/v1/journal" \
  -H "Authorization: Bearer &lt;token&gt;" \
  --data-urlencode "path=/workspace/data" \
  --data-urlencode "op=write,delete" \
  --data-urlencode "limit=50"
```


```typescript
const result = await client.files.journal.query({
  path: "/workspace/data",
  op: "write,delete",
  since: "2024-01-15T00:00:00Z",
  limit: 50
});
```


```json
{
  "count": 2,
  "entries": [
    {
      "id": 1042,
      "ts": 1705305600000,
      "op": "write",
      "path": "/workspace/data/config.json",
      "before": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "after": "d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2",
      "blob": true,
      "blob_before": false,
      "blob_after": true,
      "size_before": 0,
      "size_after": 128,
      "seq": 7
    },
    {
      "id": 1043,
      "ts": 1705305660000,
      "op": "delete",
      "path": "/workspace/data/old.log",
      "before": "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1",
      "after": null,
      "blob": true,
      "blob_before": true,
      "blob_after": false,
      "size_before": 4096,
      "size_after": 0,
      "seq": 3
    }
  ],
  "has_more": false,
  "next_after_id": null
}
```


```json
{
  "error": "Journal not enabled",
  "message": "The file journal is not enabled on this workspace"
}
```


```json
{
  "error": "Too Many Requests",
  "message": "Too many concurrent journal queries"
}
```



### Get journal statistics

`GET /api/v1/journal/stats`

Returns storage statistics for the journal system, including entry counts, blob storage usage, writer health, and pruning information. Use this to monitor journal health and detect completeness degradation.

This endpoint takes no parameters.



```bash
curl "https://api.hoody.com/api/v1/journal/stats" \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const stats = await client.files.journal.getStats();
```


```json
{
  "total_entries": 158472,
  "total_blobs": 42180,
  "total_blob_bytes": 268435456,
  "total_storage_bytes": 312345678,
  "writer_healthy": true,
  "entries_skipped_total": 0,
  "parse_failures": 0,
  "skipped_overflow": 0,
  "newest_entry_ts": 1705305660000,
  "pruned_before_date": "2024-01-01"
}
```


```json
{
  "error": "Journal not enabled",
  "message": "The file journal is not enabled on this workspace"
}
```


```json
{
  "error": "Too Many Requests",
  "message": "Too many concurrent journal queries"
}
```



#### Response fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `entries_skipped_total` | integer | Yes | Number of paths with entries that were dropped (writer outage) |
| `newest_entry_ts` | integer | No | Timestamp (Unix ms) of the most recent entry, or null if no entries |
| `parse_failures` | integer | Yes | Count of corrupted/malformed JSONL lines encountered during scans |
| `pruned_before_date` | string | No | ISO date (YYYY-MM-DD) before which all day files have been pruned, or null if no pruning |
| `skipped_overflow` | integer | Yes | Count of dropped paths that exceeded the tracking cap. Non-zero means completeness detection is degraded |
| `total_blob_bytes` | integer | Yes | Total bytes used by content blobs |
| `total_blobs` | integer | Yes | Total number of content blobs stored |
| `total_entries` | integer | Yes | Total number of journal entries across all day files |
| `total_storage_bytes` | integer | Yes | Total bytes used by journal (entries + blobs) |
| `writer_healthy` | boolean | Yes | Whether the background JSONL writer task is healthy |


A non-zero `skipped_overflow` indicates that path tracking has exceeded its cap, which degrades the ability to detect completeness gaps in the journal. Consider investigating writer health and storage capacity.


### Flush journal to disk

`POST /api/v1/journal/flush`

Forces all pending journal entries to be written and `fsync`ed to disk. Returns `200` with `flushed=true` if all entries were durably persisted, or `503` with `flushed=false` if the flush failed or entries were lost.

This endpoint takes no parameters.



```bash
curl -X POST "https://api.hoody.com/api/v1/journal/flush" \
  -H "Authorization: Bearer &lt;token&gt;"
```


```typescript
const result = await client.files.journal.flush();
if (result.flushed) {
  console.log("All entries persisted to disk");
}
```


```json
{
  "flushed": true
}
```


```json
{
  "error": "Journal not enabled",
  "message": "The file journal is not enabled on this workspace"
}
```


```json
{
  "flushed": false
}
```




Call this endpoint before taking a snapshot, cloning the workspace, or any operation that requires a known-durable journal state. It guarantees that all in-memory journal entries have been written and synced to underlying storage.