Skip to content

Chat

The chat system manages conversations within notebooks. Each conversation contains messages exchanged between the user and the AI assistant. The core endpoint (POST .../messages) runs the full RAG pipeline: retrieval, context assembly, LLM generation, and background quality evaluation.

Base path: /api/notebooks/{notebook_id}


GET /api/notebooks/{notebook_id}/conversations

List all conversations for a notebook.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Query Parameters:

Parameter Type Required Default Description
include_archived boolean No false Include archived conversations

Status: 200 OK

{
  "success": true,
  "data": [
    {
      "conversation_id": "conv-1234-...",
      "notebook_id": "a1b2c3d4-...",
      "user_id": "user_abc",
      "title": "Support questions",
      "chat_mode": "rag",
      "is_pinned": false,
      "is_archived": false,
      "message_count": 12,
      "last_message_at": "2026-02-25T14:30:00Z",
      "created_at": "2026-02-25T10:00:00Z",
      "updated_at": "2026-02-25T14:30:00Z",
      "session_metadata": {}
    }
  ]
}
Code Cause
401 Invalid or missing token
curl "http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations?include_archived=true" \
  -H "Authorization: Bearer $TOKEN"
import httpx

notebook_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
response = httpx.get(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations",
    headers={"Authorization": f"Bearer {token}"},
    params={"include_archived": False},
)
conversations = response.json()["data"]
for conv in conversations:
    print(f"{conv['title']} ({conv['message_count']} messages)")

POST /api/notebooks/{notebook_id}/conversations

Create a new conversation.

Auth: User

Headers:

Header Value
Authorization Bearer <token>
Content-Type application/json

Body:

{
  "title": "New Chat",
  "chat_mode": "rag"
}
Field Type Required Default Description
title string No "New Chat" Conversation title
chat_mode string No "rag" Always "rag"

Status: 201 Created

{
  "success": true,
  "data": {
    "conversation_id": "conv-1234-...",
    "notebook_id": "a1b2c3d4-...",
    "user_id": "user_abc",
    "title": "New Chat",
    "chat_mode": "rag",
    "is_pinned": false,
    "is_archived": false,
    "message_count": 0,
    "created_at": "2026-02-25T15:00:00Z"
  }
}
Code Cause
401 Invalid or missing token
curl -X POST http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "New Chat", "chat_mode": "rag"}'
import httpx

notebook_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
response = httpx.post(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations",
    headers={"Authorization": f"Bearer {token}"},
    json={"title": "New Chat", "chat_mode": "rag"},
)
conv = response.json()["data"]
print(f"Created conversation: {conv['conversation_id']}")

DELETE /api/notebooks/{notebook_id}/conversations/{conversation_id}

Delete a conversation and all its messages.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "success": true
  }
}
Code Cause
401 Invalid or missing token
404 Conversation not found
curl -X DELETE http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID \
  -H "Authorization: Bearer $TOKEN"
import httpx

notebook_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
conversation_id = "conv-1234-..."
response = httpx.delete(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}",
    headers={"Authorization": f"Bearer {token}"},
)
print(response.json()["data"])

PUT /api/notebooks/{notebook_id}/conversations/{conversation_id}

Update conversation title or archive status.

Auth: User

Headers:

Header Value
Authorization Bearer <token>
Content-Type application/json

Body:

{
  "title": "Updated title",
  "is_archived": false
}
Field Type Required Default Description
title string No -- New conversation title
is_archived boolean No -- Archive or unarchive

Status: 200 OK

{
  "success": true,
  "data": {
    "conversation_id": "conv-1234-...",
    "title": "Updated title",
    "is_archived": false
  }
}
Code Cause
401 Invalid or missing token
curl -X PUT http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Updated title"}'
import httpx

response = httpx.put(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}",
    headers={"Authorization": f"Bearer {token}"},
    json={"title": "Updated title"},
)
print(response.json()["data"])

POST /api/notebooks/{notebook_id}/conversations/{conversation_id}/pin

Toggle the pin status for a conversation.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "is_pinned": true
  }
}
Code Cause
401 Invalid or missing token
curl -X POST http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID/pin \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.post(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}/pin",
    headers={"Authorization": f"Bearer {token}"},
)
print(f"Pinned: {response.json()['data']['is_pinned']}")

GET /api/notebooks/{notebook_id}/conversations/{conversation_id}/messages

Get all messages for a conversation, including feedback data.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": [
    {
      "id": "msg-1234-...",
      "conversation_id": "conv-1234-...",
      "notebook_id": "a1b2c3d4-...",
      "user_id": "user_abc",
      "role": "user",
      "content": "What is the refund policy?",
      "citations": [],
      "run_metadata": null,
      "created_at": "2026-02-25T15:01:00Z",
      "feedback_is_positive": null,
      "feedback_text": null
    },
    {
      "id": "msg-5678-...",
      "role": "assistant",
      "content": "Based on the documents, the refund policy states...",
      "citations": [
        {
          "citation_id": 1,
          "rank": 1,
          "content": "Refund policy section...",
          "metadata": {"file_name": "handbook.pdf", "chunk_index": 12},
          "similarity": 0.89
        }
      ],
      "run_metadata": {
        "strategy_id": "fusion",
        "latency_ms": 2340,
        "model": "openai/gpt-4o-mini",
        "chunks_count": 5,
        "suggested_questions": ["What are the exceptions?"],
        "is_cached": false
      }
    }
  ]
}
Code Cause
401 Invalid or missing token
curl http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID/messages \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.get(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}/messages",
    headers={"Authorization": f"Bearer {token}"},
)
messages = response.json()["data"]
for msg in messages:
    print(f"[{msg['role']}] {msg['content'][:80]}...")

POST /api/notebooks/{notebook_id}/conversations/{conversation_id}/messages

Send a user message and get an AI response. This is the core RAG endpoint. It saves the user message, retrieves context via the selected strategy, generates an AI response via Pydantic AI, saves the assistant message, and triggers LLM Judge evaluation in the background.

Auth: User

Headers:

Header Value
Authorization Bearer <token>
Content-Type application/json

Body:

{
  "content": "What is the refund policy?",
  "chat_mode": "rag",
  "strategy_id": "fusion",
  "persona": "professional",
  "language": "en",
  "custom_persona_text": null,
  "selected_file_ids": []
}
Field Type Required Default Description
content string Yes -- User message (1-50000 chars)
chat_mode string No "rag" Always "rag"
strategy_id string No "fusion" Retrieval strategy ID
persona string No "professional" One of: funny, professional, mentor, storyteller, clear, custom
language string No "en" One of: en, de, es, fr, it, pt, nl, ru, zh, ja
custom_persona_text string No null Custom persona instructions (when persona is "custom")
selected_file_ids array No [] Restrict retrieval to specific files

Status: 200 OK

{
  "success": true,
  "data": {
    "user_message": {
      "id": "msg-1234-...",
      "role": "user",
      "content": "What is the refund policy?"
    },
    "assistant_message": {
      "id": "msg-5678-...",
      "role": "assistant",
      "content": "Based on the documents [1], the refund policy allows...",
      "citations": [
        {
          "citation_id": 1,
          "rank": 1,
          "content": "Our refund policy states that...",
          "metadata": {"file_name": "handbook.pdf"},
          "similarity": 0.92
        }
      ],
      "run_metadata": {
        "strategy_id": "fusion",
        "latency_ms": 2340,
        "model": "openai/gpt-4o-mini",
        "chunks_count": 5,
        "suggested_questions": [
          "What are the exceptions to the refund policy?",
          "How long does a refund take to process?"
        ],
        "is_cached": false,
        "expanded_query": "refund policy return money"
      }
    }
  }
}

Cache Hits

When a cache hit occurs, is_cached is true, cache_match_type is "exact" or "semantic", and cache_similarity shows the cosine similarity score.

Code Cause
400 Missing API key for the configured provider
400 Empty or too-long message content
401 Invalid or missing token
curl -X POST http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID/messages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "What is the refund policy?",
    "chat_mode": "rag",
    "strategy_id": "fusion",
    "persona": "professional",
    "language": "en"
  }'
import httpx

response = httpx.post(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}/messages",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "content": "What is the refund policy?",
        "chat_mode": "rag",
        "strategy_id": "fusion",
        "persona": "professional",
        "language": "en",
    },
    timeout=60.0,  # RAG pipeline can take time
)
result = response.json()["data"]
print(f"AI: {result['assistant_message']['content']}")
for cite in result["assistant_message"]["citations"]:
    print(f"  [{cite['citation_id']}] {cite['metadata'].get('file_name')}")

DELETE /api/notebooks/{notebook_id}/conversations/{conversation_id}/messages

Delete all messages in a conversation (clear chat history).

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "deleted": 12
  }
}
Code Cause
401 Invalid or missing token
curl -X DELETE http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations/$CONV_ID/messages \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.delete(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations/{conversation_id}/messages",
    headers={"Authorization": f"Bearer {token}"},
)
print(response.json()["data"])

POST /api/notebooks/{notebook_id}/messages/{message_id}/feedback

Submit thumbs-up or thumbs-down feedback for a message. Uses upsert -- calling again updates the existing feedback.

Auth: User

Headers:

Header Value
Authorization Bearer <token>
Content-Type application/json

Body:

{
  "is_positive": true,
  "feedback_text": "Very helpful answer",
  "feedback_category": "accuracy"
}
Field Type Required Default Description
is_positive boolean Yes -- Thumbs up (true) or down (false)
feedback_text string No null Optional text feedback
feedback_category string No null Optional category tag

Status: 200 OK

{
  "success": true,
  "data": {
    "message_id": "msg-5678-...",
    "is_positive": true
  }
}
Code Cause
401 Invalid or missing token
curl -X POST http://localhost:8000/api/notebooks/$NOTEBOOK_ID/messages/$MSG_ID/feedback \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"is_positive": true, "feedback_text": "Very helpful"}'
import httpx

response = httpx.post(
    f"http://localhost:8000/api/notebooks/{notebook_id}/messages/{message_id}/feedback",
    headers={"Authorization": f"Bearer {token}"},
    json={"is_positive": True, "feedback_text": "Very helpful"},
)
print(response.json()["data"])

DELETE /api/notebooks/{notebook_id}/messages/{message_id}/feedback

Remove feedback for a message.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "deleted": true
  }
}
Code Cause
401 Invalid or missing token
curl -X DELETE http://localhost:8000/api/notebooks/$NOTEBOOK_ID/messages/$MSG_ID/feedback \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.delete(
    f"http://localhost:8000/api/notebooks/{notebook_id}/messages/{message_id}/feedback",
    headers={"Authorization": f"Bearer {token}"},
)
print(response.json()["data"])

DELETE /api/notebooks/{notebook_id}/conversations

Delete all conversations for a notebook.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "deleted": 5
  }
}
Code Cause
401 Invalid or missing token
curl -X DELETE http://localhost:8000/api/notebooks/$NOTEBOOK_ID/conversations \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.delete(
    f"http://localhost:8000/api/notebooks/{notebook_id}/conversations",
    headers={"Authorization": f"Bearer {token}"},
)
print(response.json()["data"])