API Documentation
This document describes the HTTP API exposed by the Node.js backend server that connects to a locally running Ollama instance with the llama3.2 model. All endpoints accept and return JSON unless otherwise stated.
#Overview
The backend acts as a proxy and context manager between your frontend and Ollama. It handles:
- Forwarding chat messages to Ollama with an optional system prompt
- Parsing uploaded Word (.docx / .doc) and Excel (.xlsx / .xls) documents
- Injecting extracted document text as temporary knowledge into every chat request
- Health-checking the Ollama connection and model availability
Knowledge is stored in memory only — it is cleared when the server restarts or when you call DELETE /api/knowledge.
#Base URL & Headers
https://backend.aiassistant.rohitkrishna.onlineAll endpoints are prefixed with /api.
Required headers (JSON endpoints)
| Header | Value |
|---|---|
| Content-Type | application/json |
| Accept | application/json (optional) |
Required headers (upload endpoint)
Do not set Content-Type manually for multipart uploads — let the HTTP client set it automatically so the boundary is included.
#POST /api/chat
Sends a conversation to Ollama and returns the assistant reply. If a document has been uploaded, its text is automatically injected as a system prompt.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| messages | array | Yes | Array of message objects in chronological order |
| messages[].role | "user" | "assistant" | Yes | Who sent the message |
| messages[].content | string | Yes | Message text |
| searchWeb | boolean | No (default: false) | Run a DuckDuckGo web search for the last user message and inject results as context before answering |
POST /api/chat
Content-Type: application/json
{
"messages": [
{ "role": "user", "content": "What is the capital of France?" }
],
"searchWeb": false
}Success response — 200 OK
{
"message": {
"role": "assistant",
"content": "The capital of France is Paris."
},
"webSearched": false
}webSearched is true when searchWeb was requested and search results were successfully retrieved and injected into the prompt.
Multi-turn conversation
Pass the full conversation history each time. The backend does not persist history — the client is responsible for maintaining it.
{
"messages": [
{ "role": "user", "content": "My name is Alex." },
{ "role": "assistant", "content": "Hello Alex! How can I help?" },
{ "role": "user", "content": "What is my name?" }
]
}Status codes
| Code | Meaning |
|---|---|
| 200 | Success — message returned |
| 400 | Missing or invalid messages array |
| 502 | Ollama returned an error |
| 503 | Cannot connect to Ollama |
#Web Search Mode
When searchWeb: true is included in a POST /api/chat request, the backend performs the following steps before calling Ollama:
- Extracts the last user message as the search query
- Uses Crawlee (
CheerioCrawler) to scrape Bing search results — no API key required, uses browser-like TLS fingerprints viagot-scrapingto avoid bot detection - Formats up to 5 results (title, snippet, source URL) as a context block
- Replaces the default system prompt with a web-aware one that instructs the model to answer using those results
Note: Web search is automatically disabled when a document is loaded (POST /api/upload). Document knowledge takes priority.
Request example
POST /api/chat
Content-Type: application/json
{
"messages": [
{ "role": "user", "content": "What happened in tech news today?" }
],
"searchWeb": true
}Response example
{
"message": {
"role": "assistant",
"content": "Based on current web search results: [1] ..."
},
"webSearched": true
}System prompt injected (simplified)
You are a helpful assistant with access to live web search results.
Use the search results below to answer the user's question accurately.
Cite sources when relevant. If the results don't contain enough
information, say so.
--- WEB SEARCH RESULTS ---
[1] Result title
Snippet text...
Source: https://example.com
[2] ...
--- END OF SEARCH RESULTS ---Behaviour when search fails
If DuckDuckGo is unreachable or returns no results, the backend logs the error and falls back to answering without web context (same as searchWeb: false). The response will still have webSearched: false in that case.
cURL example
curl -X POST https://backend.aiassistant.rohitkrishna.online/api/chat \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role":"user","content":"Latest Node.js release?"}],
"searchWeb": true
}'#POST /api/upload
Uploads a Word or Excel file. The server extracts all plain text from the document and stores it in memory. Subsequent /api/chat calls will include this text as knowledge until cleared.
Uploading a new file replaces the previous knowledge.
Request
Send a multipart/form-data request with a single file field named document.
| Parameter | Type | Description |
|---|---|---|
| document | file (form field) | The file to upload (.docx, .doc, .xlsx, .xls) |
POST /api/upload
Content-Type: multipart/form-data; boundary=----boundary
------boundary
Content-Disposition: form-data; name="document"; filename="report.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
<binary file data>
------boundary--JavaScript fetch example
const form = new FormData();
form.append("document", fileInput.files[0]);
const res = await fetch("https://backend.aiassistant.rohitkrishna.online/api/upload", {
method: "POST",
body: form, // do NOT set Content-Type manually
});
const data = await res.json();
console.log(data.filename, data.characters);cURL example
curl -X POST https://backend.aiassistant.rohitkrishna.online/api/upload \
-F "document=@/path/to/report.docx"Success response — 200 OK
{
"success": true,
"filename": "report.docx",
"characters": 4821,
"preview": "This report covers Q3 financials..."
}Supported file types
| Extension | MIME type | Parser |
|---|---|---|
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | mammoth |
| .doc | application/msword | mammoth |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | xlsx (SheetJS) |
| .xls | application/vnd.ms-excel | xlsx (SheetJS) |
Status codes
| Code | Meaning |
|---|---|
| 200 | File parsed and knowledge stored |
| 400 | No file provided |
| 413 | File exceeds 10 MB limit |
| 422 | File could not be parsed (empty or corrupt) |
| 500 | Server error during parsing |
#GET /api/knowledge/status
Returns whether document knowledge is currently loaded and how large it is.
GET /api/knowledge/statusResponse — 200 OK
// With knowledge loaded
{
"loaded": true,
"characters": 4821
}
// Without knowledge
{
"loaded": false,
"characters": 0
}#DELETE /api/knowledge
Clears the in-memory document knowledge. After this call, the chatbot reverts to general-purpose mode.
DELETE /api/knowledgeResponse — 200 OK
{
"success": true,
"message": "Temporary knowledge cleared"
}cURL example
curl -X DELETE https://backend.aiassistant.rohitkrishna.online/api/knowledge#GET /api/health
Checks whether the backend can reach Ollama and whether the llama3.2 model is available.
GET /api/healthResponse — 200 OK (Ollama reachable)
{
"status": "ok",
"ollama": "connected",
"model": "llama3.2",
"modelAvailable": true,
"availableModels": ["llama3.2:latest", "mistral:7b"]
}Response — 503 (Ollama unreachable)
{
"status": "error",
"ollama": "unreachable",
"model": "llama3.2"
}#Document Knowledge Mode
When a document is uploaded, the backend automatically prepends the following system prompt to every /api/chat request:
You are a helpful assistant. Answer ONLY based on the following
document knowledge provided to you. If the user asks something
not covered in this knowledge, say you can only answer based on
the uploaded document.
--- DOCUMENT KNOWLEDGE START ---
<extracted document text>
--- DOCUMENT KNOWLEDGE END ---This means the model will only answer questions that can be answered from the document. This is enforced through the system prompt — no fine-tuning or vector search is involved.
Workflow
- Call
POST /api/uploadwith the document - Use
POST /api/chatnormally — knowledge is injected automatically - Call
DELETE /api/knowledgewhen done to return to general mode
Limitations
- Knowledge is session-scoped — restarting the server clears it
- Only one document can be loaded at a time; uploading replaces the previous one
- Very large documents may exceed the model context window (~8 K tokens for llama3.2)
- Images, charts, and embedded objects in documents are ignored
#Error Responses
All error responses follow the same shape:
{
"error": "Human-readable error message"
}| HTTP Code | When it occurs |
|---|---|
| 400 | Required fields are missing or the request body is malformed |
| 413 | Uploaded file exceeds the 10 MB limit |
| 422 | File was received but text extraction produced no content |
| 500 | Unexpected server-side error |
| 502 | Ollama returned a non-OK response (model error, etc.) |
| 503 | Backend cannot reach the Ollama process on localhost:11434 |
#Integration Examples
Python (requests)
import requests
BASE = "https://backend.aiassistant.rohitkrishna.online"
# Basic chat
resp = requests.post(f"{BASE}/api/chat", json={
"messages": [{"role": "user", "content": "Hello!"}]
})
print(resp.json()["message"]["content"])
# Upload a document
with open("report.docx", "rb") as f:
resp = requests.post(f"{BASE}/api/upload", files={"document": f})
print(resp.json())
# Chat with document context (same as basic chat — knowledge injected automatically)
resp = requests.post(f"{BASE}/api/chat", json={
"messages": [{"role": "user", "content": "Summarise the key findings."}]
})
print(resp.json()["message"]["content"])
# Clear knowledge
requests.delete(f"{BASE}/api/knowledge")JavaScript / Node.js (native fetch)
const BASE = "https://backend.aiassistant.rohitkrishna.online";
// Send a chat message
const chat = await fetch(`${BASE}/api/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
messages: [{ role: "user", content: "Hello!" }]
}),
});
const { message } = await chat.json();
console.log(message.content);
// Upload a file (Node.js 18+ with FormData)
import { readFileSync } from "fs";
const form = new FormData();
form.append("document", new Blob([readFileSync("data.xlsx")]), "data.xlsx");
const upload = await fetch(`${BASE}/api/upload`, { method: "POST", body: form });
console.log(await upload.json());cURL — full workflow
# 1. Check health
curl https://backend.aiassistant.rohitkrishna.online/api/health
# 2. Chat
curl -X POST https://backend.aiassistant.rohitkrishna.online/api/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"What is 2+2?"}]}'
# 3. Upload document
curl -X POST https://backend.aiassistant.rohitkrishna.online/api/upload \
-F "document=@company_policy.docx"
# 4. Ask about the document
curl -X POST https://backend.aiassistant.rohitkrishna.online/api/chat \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"What is the leave policy?"}]}'
# 5. Clear knowledge
curl -X DELETE https://backend.aiassistant.rohitkrishna.online/api/knowledgeBackend: Node.js + Express · Model: Ollama llama3.2 · Web search: Crawlee + Bing · Document parsing: mammoth (Word), SheetJS (Excel)