Conversations
NimbleBrain automatically persists every conversation. Each conversation is stored as a JSONL file, and you can resume, fork, rename, delete, and search conversations through the CLI, API, or web UI.
Storage format
Section titled “Storage format”Conversations are stored as append-only JSONL (JSON Lines) files in ~/.nimblebrain/conversations/. Each file is named by its conversation ID:
~/.nimblebrain/conversations/conv_a1b2c3d4e5f67890.jsonlThe file format:
- Line 1 — conversation metadata
- Lines 2+ — one
StoredMessageper line
Metadata (line 1)
Section titled “Metadata (line 1)”{ "id": "conv_a1b2c3d4e5f67890", "createdAt": "2026-03-25T10:30:00.000Z", "updatedAt": "2026-03-25T10:35:42.000Z", "title": "Meeting notes summary", "totalInputTokens": 24500, "totalOutputTokens": 1800, "totalCostUsd": 0.042, "lastModel": "claude-sonnet-4-5-20250929"}The metadata line is updated in place on each append — the file is rewritten atomically (write to temp file, then rename) to prevent corruption.
Messages (lines 2+)
Section titled “Messages (lines 2+)”Each message contains the role, content, timestamp, and optional metadata:
{ "role": "user", "content": "Summarize my meetings from this week", "timestamp": "2026-03-25T10:30:00.000Z"}Assistant messages include additional metadata:
{ "role": "assistant", "content": "Here are your meetings from this week...", "timestamp": "2026-03-25T10:30:15.000Z", "metadata": { "skill": "meeting-notes", "toolCalls": [ { "id": "tc_001", "name": "granola__search_meetings", "input": {"query": "this week"}, "output": "[{\"title\": \"Sprint Planning\", ...}]", "ok": true, "ms": 340 } ], "inputTokens": 12000, "outputTokens": 800, "cacheCreationTokens": 0, "cacheReadTokens": 8000, "costUsd": 0.021, "model": "claude-sonnet-4-5-20250929", "llmMs": 2400, "iterations": 2 }}Resuming a conversation
Section titled “Resuming a conversation”nb --resume conv_a1b2c3d4e5f67890This loads the conversation history and continues from where you left off.
Select a conversation from the sidebar list. The full message history loads, and new messages continue the conversation.
Listing conversations
Section titled “Listing conversations”curl http://localhost:27247/v1/conversations{ "conversations": [ { "id": "conv_a1b2c3d4e5f67890", "createdAt": "2026-03-25T10:30:00.000Z", "updatedAt": "2026-03-25T10:35:42.000Z", "title": "Meeting notes summary", "messageCount": 6, "preview": "Summarize my meetings from this week", "totalInputTokens": 24500, "totalOutputTokens": 1800, "totalCostUsd": 0.042 } ], "nextCursor": null, "totalCount": 1}Pagination is cursor-based. Pass cursor from nextCursor to get the next page:
curl "http://localhost:27247/v1/conversations?limit=20&cursor=abc123"Sort by creation or last update:
curl "http://localhost:27247/v1/conversations?sortBy=updatedAt"The sidebar shows recent conversations with titles and timestamps. Click any conversation to load it.
Viewing history
Section titled “Viewing history”Retrieve all messages for a conversation:
curl http://localhost:27247/v1/conversations/conv_a1b2c3d4e5f67890/history{ "conversationId": "conv_a1b2c3d4e5f67890", "messages": [ {"role": "user", "content": "Summarize my meetings", "timestamp": "2026-03-25T10:30:00.000Z"}, {"role": "assistant", "content": "Here are your meetings...", "timestamp": "2026-03-25T10:30:15.000Z"} ]}Forking a conversation
Section titled “Forking a conversation”Fork creates a new conversation from an existing one, optionally truncated at a specific message index:
curl -X POST http://localhost:27247/v1/conversations/conv_a1b2c3d4e5f67890/forkFork at a specific point (copies only the first 4 messages):
curl -X POST "http://localhost:27247/v1/conversations/conv_a1b2c3d4e5f67890/fork?atMessage=4"The forked conversation gets a new ID and re-accumulates token counts from the copied messages. The original conversation is unchanged.
Renaming a conversation
Section titled “Renaming a conversation”Update the title:
curl -X PATCH http://localhost:27247/v1/conversations/conv_a1b2c3d4e5f67890 \ -H "Content-Type: application/json" \ -d '{"title": "Q1 sprint meetings"}'Deleting a conversation
Section titled “Deleting a conversation”curl -X DELETE http://localhost:27247/v1/conversations/conv_a1b2c3d4e5f67890This deletes the JSONL file from disk. The operation is irreversible.
Searching conversations
Section titled “Searching conversations”Search across conversation titles and content:
curl "http://localhost:27247/v1/conversations?search=meeting+notes"Search is performed at the API level against the conversation index.
Auto-titling
Section titled “Auto-titling”NimbleBrain generates conversation titles automatically after the first assistant response. The title is stored in the metadata line of the JSONL file and displayed in the web UI sidebar and conversation list.
Storage configuration
Section titled “Storage configuration”By default, the CLI uses JSONL storage in ~/.nimblebrain/conversations/. You can change the storage backend in nimblebrain.json:
{ "store": { "type": "jsonl", "dir": "/custom/path/to/conversations" }}For in-memory storage (no persistence):
{ "store": { "type": "memory" }}What’s next
Section titled “What’s next”- Chat — how conversations are created during chat
- Multi-Agent Delegation — child agents run in their own conversations
- API: Conversations — full API reference