> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kiwifs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Versioning

> Git history, diff, and blame endpoints for tracking changes to your knowledge base.

Every write in KiwiFS creates a git commit. The versioning API exposes the full git history for any file, letting you view past versions, compare changes, and trace authorship.

## Version history

Get the git log for a specific file.

<ParamField query="path" type="string" required>
  File path relative to the knowledge root.
</ParamField>

```bash theme={null}
curl 'http://localhost:3333/api/kiwi/versions?path=concepts/auth.md'
```

```json theme={null}
[
  {
    "hash": "e4f5g6h",
    "author": "agent:docs-writer",
    "message": "update concepts/auth.md",
    "timestamp": "2026-04-25T14:30:00Z"
  },
  {
    "hash": "a1b2c3d",
    "author": "agent:importer",
    "message": "create concepts/auth.md",
    "timestamp": "2026-04-24T09:15:00Z"
  }
]
```

## Read a specific version

Retrieve the file content at a specific commit.

<ParamField query="path" type="string" required>
  File path relative to the knowledge root.
</ParamField>

<ParamField query="version" type="string" required>
  Git commit hash (full or abbreviated).
</ParamField>

```bash theme={null}
curl 'http://localhost:3333/api/kiwi/version?path=concepts/auth.md&version=a1b2c3d'
```

```
# Authentication

Original content from the first commit...
```

## Diff between versions

Get a unified diff between two commits for a file.

<ParamField query="path" type="string" required>
  File path relative to the knowledge root.
</ParamField>

<ParamField query="from" type="string" required>
  Starting commit hash.
</ParamField>

<ParamField query="to" type="string" required>
  Ending commit hash.
</ParamField>

```bash theme={null}
curl 'http://localhost:3333/api/kiwi/diff?path=concepts/auth.md&from=a1b2c3d&to=e4f5g6h'
```

```diff theme={null}
--- a/concepts/auth.md
+++ b/concepts/auth.md
@@ -1,3 +1,5 @@
 # Authentication

-Original content from the first commit...
+OAuth2 + JWT based authentication system.
+
+Supports refresh token rotation.
```

## Blame

Get per-line git blame attribution for a file. Each line maps to the commit that last modified it.

<ParamField query="path" type="string" required>
  File path relative to the knowledge root.
</ParamField>

```bash theme={null}
curl 'http://localhost:3333/api/kiwi/blame?path=concepts/auth.md'
```

```json theme={null}
[
  {
    "line": 1,
    "content": "# Authentication",
    "hash": "a1b2c3d",
    "author": "agent:importer",
    "timestamp": "2026-04-24T09:15:00Z"
  },
  {
    "line": 3,
    "content": "OAuth2 + JWT based authentication system.",
    "hash": "e4f5g6h",
    "author": "agent:docs-writer",
    "timestamp": "2026-04-25T14:30:00Z"
  }
]
```

<Tip>
  Use blame to trace which agent or user wrote each section. The `author` field corresponds to the `X-Actor` header set during the write.
</Tip>

## Change feed

Get a paginated feed of all changes across the knowledge base since a given commit. Useful for syncing external systems or building audit logs.

```http theme={null}
GET /api/kiwi/changes
```

<ParamField query="since" type="string">
  Git commit hash to start from. Omit to get the most recent changes.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Max changes to return (capped at 500).
</ParamField>

```bash theme={null}
curl 'http://localhost:3333/api/kiwi/changes?limit=10'
```

```json theme={null}
{
  "changes": [
    {"seq": 1, "path": "concepts/auth.md", "action": "write", "actor": "agent:docs-writer", "timestamp": "2026-05-04T12:00:00Z"},
    {"seq": 2, "path": "concepts/billing.md", "action": "delete", "actor": "agent:cleanup", "timestamp": "2026-05-04T12:01:00Z"}
  ],
  "last_seq": "e4f5g6h..."
}
```

Pass `last_seq` as the `since` parameter on the next request to paginate forward.

***

## Optimistic locking with ETag

The versioning system powers optimistic locking. When you read a file, the response includes an `ETag` header with the current git blob SHA. Pass this value in the `If-Match` header on writes to detect concurrent modifications.

```bash theme={null}
# 1. Read the file and capture the ETag
ETAG=$(curl -sI 'http://localhost:3333/api/kiwi/file?path=concepts/auth.md' \
  | grep -i etag | awk '{print $2}' | tr -d '\r"')

# 2. Write with If-Match to prevent conflicts
curl -X PUT 'http://localhost:3333/api/kiwi/file?path=concepts/auth.md' \
  -H "Content-Type: text/markdown" \
  -H "X-Actor: agent:updater" \
  -H "If-Match: $ETAG" \
  -d '# Authentication (updated)

Revised content.'
```

If another write occurred between your read and write, you receive a `409 Conflict` response:

```json theme={null}
{"error": "conflict: file was modified since your last read"}
```
