Appearance
Chat AI
Conversational AI over the organisation's configured language models, with optional grounding in the user's documents. This is the API behind the Chat AI module.
Model of a conversation
- A session (
/sessions/) is a conversation thread. Every module that has a chat (Chat AI, document chat, database chat…) stores its threads in the same session table, distinguished bytype. - A message is stored with
POST /secure-gpt/store/(one call for the user's prompt, one for the assistant's reply) and read back withGET /sessions/{id}/fetch/. - The assistant's reply is produced by a streaming endpoint (
POST /secure-gpt/chat/and the document-chat variants). These returntext/event-stream-style chunked text rather than JSON — see Streaming & WebSockets.
End-to-end encryption
The web app encrypts every stored message on the client with the user's data encryption key (DEK) before calling store/, and marks the row is_encrypted: true. The DEK never leaves the browser in the clear, except transiently over TLS for the LLM call.
API clients that do not hold the user's DEK can store plaintext messages by sending is_encrypted: false (the default). Such rows are readable through the API, and the web app converts them to encrypted rows the next time that user signs in. The reverse is not possible: encrypted messages fetched through the API are opaque ciphertext (base64(nonce ‖ ciphertext ‖ tag), AES-256-GCM) without the DEK.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /microservices/agent/chat/ | Send a message to the assistant |
| GET | /sessions/ | List my conversations |
| POST | /sessions/ | Create a conversation |
| GET | /sessions/{id}/ | Get a conversation |
| PUT | /sessions/{id}/ | Rename or re-bind a conversation |
| DELETE | /sessions/{id}/ | Delete a conversation |
| GET | /sessions/{id}/delete-impact/ | What deleting a conversation removes |
| GET | /sessions/{id}/fetch/ | Messages of a conversation |
| POST | /secure-gpt/store/ | Store a message |
| GET | /secure-gpt/ | All my Chat AI messages |
| POST | /secure-gpt/generate-title/ | Generate a title for a conversation |
| POST | /secure-gpt/rewrite/ | Rewrite text in a tone |
| POST | /secure-gpt/category/ | Classify a question into a role category |
| POST | /secure-gpt/chat/ | Stream a model reply (direct, no agent) |
| POST | /semantic-search/single-file-chat/ | Chat with one document |
| POST | /semantic-search/multi-file-chat/ | Chat with several documents |
| POST | /semantic-search/all-files-chat/ | Chat across all my documents |
| POST | /semantic-search/advanced-search/ | Chat with one document using its summary (advanced) |
| POST | /semantic-search/doc-from-chunks/ | Full text of a document |
| POST | /semantic-search/chat/ | Chat with documents by file name (legacy) |
| POST | /semantic-search/store/ | Store a document-chat message |
| GET | /semantic-search/ | All my document-chat messages |
POST /microservices/agent/chat/
Send a message to the assistant
One turn of a Chat AI conversation. The request is synchronous: it returns when the agent has finished (typically 5–60 s; up to the timeout you pass when the agent uses tools such as web search, document generation or dashboard building).
Conversations are identified by a client-chosen conversation_id (the app uses a UUID per thread). The first authenticated caller to use an id owns it; other users get 403. All conversation state lives on the agent side, keyed by this id, so nothing else needs to be sent to continue a thread.
Progress while the turn runs is available on the WebSocket ws/chat/{conversation_id} (stage events, tool calls, streamed partial answer). See Streaming & WebSockets. The HTTP response remains the authoritative answer, except when the response is 504 or status: queued — the agent keeps working and the final answer is delivered over the socket and, when chat_session_id was given, persisted into the session history.
Attachments. Files from My Data can be attached to the turn with attached_files; send the current selection on every turn (an explicit [] clears it). Extracted-table databases (tables_database_ids) and connected SQL tables (database_tables) work the same way.
Skills. active_skill pins the agent to one skill (a saved procedure — see Workflow assistant → skills); send null to unlock. Unknown skill names return 404.
The server sets username, organization_name, user_id, base_url, media_root and callback_token itself — values you send for those are ignored.
Auth: Session token · In the app: Chat AI (every message)
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
timeout | integer | no | Seconds to wait for the agent before answering 504. The app uses 300. Default: 600. |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | Client-chosen thread id (UUID recommended). Stable for the life of the conversation. |
message | string | yes | The user's message. |
chat_session_id | integer | no | Id of a sessions/ row owned by the caller. Binds dashboards and the persisted answer to that thread. |
reasoning_effort | string ("minimal", "low", "medium", "high", "xhigh", "none") | no | Thinking level for this turn. Invalid values fall back to the user's saved default (medium). |
active_skill | string, nullable | no | Skill name to run in, or null to unlock. Only needed on the first turn or when it changes. |
use_skills | boolean | no | Set to true alongside active_skill. |
attached_files | object[] | no | Files from My Data to ground this turn. |
attached_files[].uid | string (uuid) | no | Document uid. |
attached_files[].name | string | no | File name. |
attached_files[].endpoint | string ("semantic-search", "database-search") | no | Which store the file lives in. |
tables_database_ids | string[] | no | Extracted-table database ids to expose to the agent. |
database_tables | object[] | no | Connected SQL tables (from My Data → Data sources). |
database_tables[].db_id | integer | no | Data source id. |
database_tables[].table_id | string | no | Table name. |
tool_params | object | no | Per-tool parameter overrides (advanced). File paths inside are validated against the caller's own media tree. |
json
{
"conversation_id": "0f3c9a1e-5d2b-4c7e-8a9f-6b1d2e3f4a5b",
"message": "What was Q3 revenue growth year over year?",
"chat_session_id": 9174,
"reasoning_effort": "medium",
"attached_files": [
{
"uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"name": "Q3-report.pdf",
"endpoint": "semantic-search"
}
]
}Response 200 — The agent's reply (proxied verbatim from the agent service; the status code is the agent's).
| Field | Type | Description |
|---|---|---|
status | string | completed — answer holds the reply. queued — the turn is queued behind another one; the reply will arrive on the ws/chat/{conversation_id} socket. missing_param, clarification, interrupted — the agent needs input; the question is in message. |
answer | string | The reply (Markdown). |
message | string | The agent's question when it needs input. |
turn_id | string | |
queue_position | integer | |
mgid | string | Present when the turn produced a dashboard chart (fetch it with GET /microservices/dashboard-data/?mgid=). |
dashboard_id | string | Present when the turn published a Studio artifact. |
generated_files_urls | string[] | Media URLs of files the turn produced (documents, images). Sign them to download. |
json
{
"status": "completed",
"turn_id": "7c1f0c1e-2b8f-4a6e-9c0a-1e4b6f2d3a55",
"answer": "Q3 revenue grew **12.4% year over year**, driven by the enterprise segment (+19%) …\n",
"generated_files_urls": []
}Response 400 — Missing conversation_id/message, a file reference outside your media tree, or an invalid chat_session_id.
json
{
"error": "conversation_id is required"
}Response 403 — The conversation (or chat_session_id) belongs to another user.
json
{
"error": "This conversation belongs to another user."
}Response 404 — The agent service is not registered, or active_skill names an unknown skill.
json
{
"error": "path is required"
}Response 409 — A newer turn on the same conversation superseded this one. Drop this response.
Response 502 — The agent service could not be reached.
json
{
"error": "path is required"
}Response 504 — The agent did not finish within timeout. The turn is still running; the answer arrives on the socket / in the session history. Do not resend.
json
{
"error": "super agent /chat timed out"
}Example
bash
curl -X POST "https://api.example.com/microservices/agent/chat/?timeout=300" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "0f3c9a1e-5d2b-4c7e-8a9f-6b1d2e3f4a5b",
"message": "Summarise the attached report in five bullets",
"attached_files": [{"uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b", "name": "Q3-report.pdf", "endpoint": "semantic-search"}]
}'GET /sessions/
List my conversations
Newest activity first is the app's sort; the API returns rows unsorted with last_activity for you to sort on.
Auth: Session token · In the app: Chat sidebar (all modules with a chat)
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
type | string | no | Only threads of this type. |
artifact_id | string | no | Only the Studio thread bound to this artifact. |
Response 200 — Sessions.
Array of:
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | Owner id. |
type | string | Which module the thread belongs to. Values in use: chatai_general, chatai_enterprise (Chat AI), dedicated-agent, studio, app, dashboard, semantic_search (document chat), database_search, workflow, template_session. |
title | string | Shown in the sidebar. The web app stores it encrypted for Chat AI threads. |
query | string, nullable | Free-form JSON/text the module attaches (e.g. saved chart config). |
workflow_id | string (uuid), nullable | For app threads, the workflow the app runs. |
version_id | integer, nullable | Workflow version used by an app thread. |
artifact_id | string, nullable | For studio threads, the artifact the conversation built. |
created_at | string (date-time) | |
last_activity | string (date-time) | Timestamp of the newest message (or created_at). |
Example
bash
curl -X GET "https://api.example.com/sessions/?type=chatai_general" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /sessions/
Create a conversation
Auth: Session token · In the app: "New chat" in every module
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
type | string | yes | See ChatSession.type. |
title | string | yes | |
query | string | no | |
workflow_id | string (uuid) | no | |
version_id | integer | no | |
artifact_id | string | no |
json
{
"type": "chatai_general",
"title": "New chat"
}Response 201 — Created.
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | Owner id. |
type | string | Which module the thread belongs to. Values in use: chatai_general, chatai_enterprise (Chat AI), dedicated-agent, studio, app, dashboard, semantic_search (document chat), database_search, workflow, template_session. |
title | string | Shown in the sidebar. The web app stores it encrypted for Chat AI threads. |
query | string, nullable | Free-form JSON/text the module attaches (e.g. saved chart config). |
workflow_id | string (uuid), nullable | For app threads, the workflow the app runs. |
version_id | integer, nullable | Workflow version used by an app thread. |
artifact_id | string, nullable | For studio threads, the artifact the conversation built. |
created_at | string (date-time) | |
last_activity | string (date-time) | Timestamp of the newest message (or created_at). |
json
{
"id": 9174,
"user": 42,
"type": "chatai_general",
"title": "Q3 revenue questions",
"query": null,
"workflow_id": null,
"version_id": null,
"artifact_id": null,
"created_at": "2026-09-21T11:03:15.402Z",
"last_activity": "2026-09-22T06:48:10.010Z"
}Response 400 — Validation errors.
json
{
"title": [
"This field is required."
]
}Example
bash
curl -X POST "https://api.example.com/sessions/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"chatai_general","title":"New chat"}'GET /sessions/{id}/
Get a conversation
Auth: Session token
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes |
Response 200 — The session.
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | Owner id. |
type | string | Which module the thread belongs to. Values in use: chatai_general, chatai_enterprise (Chat AI), dedicated-agent, studio, app, dashboard, semantic_search (document chat), database_search, workflow, template_session. |
title | string | Shown in the sidebar. The web app stores it encrypted for Chat AI threads. |
query | string, nullable | Free-form JSON/text the module attaches (e.g. saved chart config). |
workflow_id | string (uuid), nullable | For app threads, the workflow the app runs. |
version_id | integer, nullable | Workflow version used by an app thread. |
artifact_id | string, nullable | For studio threads, the artifact the conversation built. |
created_at | string (date-time) | |
last_activity | string (date-time) | Timestamp of the newest message (or created_at). |
json
{
"id": 9174,
"user": 42,
"type": "chatai_general",
"title": "Q3 revenue questions",
"query": null,
"workflow_id": null,
"version_id": null,
"artifact_id": null,
"created_at": "2026-09-21T11:03:15.402Z",
"last_activity": "2026-09-22T06:48:10.010Z"
}Response 404 — Not found or not yours.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X GET "https://api.example.com/sessions/9174/" \
-H "Authorization: Token $FINBLADE_TOKEN"PUT /sessions/{id}/
Rename or re-bind a conversation
Partial update of title, query, workflow_id, version_id, artifact_id.
Auth: Session token · In the app: Rename chat; auto-title after the first reply
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes |
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
title | string | no | |
query | string | no | |
workflow_id | string (uuid) | no | |
version_id | integer | no | |
artifact_id | string | no |
json
{
"title": "Q3 revenue questions"
}Response 200 — The updatable fields after the change.
| Field | Type | Description |
|---|---|---|
session | object | |
session.title | string | |
session.query | string, nullable | |
session.workflow_id | string, nullable | |
session.version_id | integer, nullable | |
session.artifact_id | string, nullable |
json
{
"session": {
"title": "Q3 revenue questions",
"query": null,
"workflow_id": null,
"version_id": null,
"artifact_id": null
}
}Response 404 — Not found or not yours.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X PUT "https://api.example.com/sessions/9174/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Q3 revenue questions"}'DELETE /sessions/{id}/
Delete a conversation
Deletes the thread, its messages, and the dashboards, generated files and chart rows the conversation created. Check the impact first with delete-impact/.
Auth: Session token · In the app: Chat sidebar → Delete
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes |
Response 204 — Deleted.
Response 404 — Not found or not yours.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X DELETE "https://api.example.com/sessions/9174/" \
-H "Authorization: Token $FINBLADE_TOKEN"GET /sessions/{id}/delete-impact/
What deleting a conversation removes
Auth: Session token · In the app: Delete-chat confirmation dialog
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes |
Response 200 — Impact report.
| Field | Type | Description |
|---|---|---|
session | object | |
session.id | integer | |
session.title | string | |
session.type | string | |
messages | integer | |
artifacts | object | |
artifacts.count | integer | |
artifacts.bytes | integer | |
artifacts.sample | string[] | |
charts | object | |
charts.count | integer | |
charts.sample | string[] |
json
{
"session": {
"id": 9174,
"title": "Q3 revenue questions",
"type": "chatai_general"
},
"messages": 14,
"artifacts": {
"count": 1,
"bytes": 48213,
"sample": [
"Q3 revenue dashboard"
]
},
"charts": {
"count": 0,
"sample": []
}
}Example
bash
curl -X GET "https://api.example.com/sessions/9174/delete-impact/" \
-H "Authorization: Token $FINBLADE_TOKEN"GET /sessions/{id}/fetch/
Messages of a conversation
Returns the thread's messages in insertion order. The row shape depends on the session type: Chat AI / Studio / app / dashboard / dedicated-agent threads return SecureChatMessage rows; semantic_search returns SemanticChatMessage rows; database_search returns rows with images and csv_files; template_session returns the session object itself.
Auth: Session token · In the app: Opening a chat
Path parameters
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes |
Response 200 — Messages.
Array of:
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | |
session | integer, nullable | |
message | string | Plaintext, or ciphertext when is_encrypted is true. |
is_encrypted | boolean | |
from_server | boolean | true for assistant replies, false for the user's prompts. |
tone | string | "True" when the message came from the rewrite-by-tone feature. |
rewrite | boolean | |
created_at | string (date-time) |
json
[
{
"id": 5510,
"user": 42,
"session": 9174,
"message": "What was Q3 revenue growth year over year?",
"is_encrypted": false,
"from_server": false,
"tone": "",
"rewrite": false,
"created_at": "2026-09-22T06:47:58.120Z"
},
{
"id": 5511,
"user": 42,
"session": 9174,
"message": "Q3 revenue grew **12.4%** year over year…",
"is_encrypted": false,
"from_server": true,
"tone": "",
"rewrite": false,
"created_at": "2026-09-22T06:48:10.010Z"
}
]Response 404 — Not found or not yours.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X GET "https://api.example.com/sessions/9174/fetch/" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /secure-gpt/store/
Store a message
Appends one message to a Chat AI thread. The app calls it twice per turn: once for the user's prompt (user_message: true) and once for the assistant's reply. Bodies may be sent as JSON or as form fields.
Auth: Session token · In the app: After every message and reply
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
response | string | yes | The message text (ciphertext when is_encrypted). |
session | integer | no | Session id. Omit to store an unthreaded message. |
user_message | boolean | no | true for the user's own prompt; omit/false for an assistant reply. |
is_encrypted | boolean | no | Default: false. |
tone | string | no | Any value marks the message as a tone rewrite. |
rewrite | string | no | Any value marks the message as a rewrite. |
json
{
"session": 9174,
"response": "What was Q3 revenue growth year over year?",
"user_message": true
}Response 200 — Stored. The body is the literal string "stored".
json
"stored"Example
bash
curl -X POST "https://api.example.com/secure-gpt/store/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"session":9174,"response":"What was Q3 revenue growth year over year?","user_message":true}'GET /secure-gpt/
All my Chat AI messages
Every stored Chat AI message of the user across sessions. Prefer sessions/{id}/fetch/ for one thread.
Auth: Session token
Response 200 — Messages.
Array of:
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | |
session | integer, nullable | |
message | string | Plaintext, or ciphertext when is_encrypted is true. |
is_encrypted | boolean | |
from_server | boolean | true for assistant replies, false for the user's prompts. |
tone | string | "True" when the message came from the rewrite-by-tone feature. |
rewrite | boolean | |
created_at | string (date-time) |
Example
bash
curl -X GET "https://api.example.com/secure-gpt/" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /secure-gpt/generate-title/
Generate a title for a conversation
Asks the user's model for a short title based on the first exchange. The app then saves it with PUT /sessions/{id}/.
Auth: Session token · In the app: Automatic after the first reply
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
context | string | yes | JSON-encoded array of the messages to summarise ([{"message": "...", "from_server": false}, …]). |
json
{
"context": "[{\"message\":\"What was Q3 revenue growth year over year?\",\"from_server\":false},{\"message\":\"Q3 revenue grew 12.4%…\",\"from_server\":true}]"
}Response 200 — Title.
| Field | Type | Description |
|---|---|---|
title | string |
json
{
"title": "Q3 revenue growth"
}Example
bash
curl -X POST "https://api.example.com/secure-gpt/generate-title/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"context":"[{\"message\":\"What was Q3 revenue growth year over year?\",\"from_server\":false},{\"message\":\"Q3 revenue grew 12.4%…\",\"from_server\":true}]"}'POST /secure-gpt/rewrite/
Rewrite text in a tone
Rewrites content using the user's model. tone is free text such as formal, friendly, shorter or modify.
Auth: Session token · In the app: Message actions → Rewrite
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
content | string | yes | |
tone | string | yes | |
session | integer | no | Optional; must be the caller's. |
json
{
"content": "pls send the report asap",
"tone": "formal"
}Response 200 — Rewritten text.
| Field | Type | Description |
|---|---|---|
response | string |
json
{
"response": "Could you please send the report at your earliest convenience?"
}Example
bash
curl -X POST "https://api.example.com/secure-gpt/rewrite/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"pls send the report asap","tone":"formal"}'POST /secure-gpt/category/
Classify a question into a role category
Used by the enterprise chat mode to decide which role-restricted documents may answer a question. Returns the category name as produced by the classifier.
Auth: Session token
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
question | string | yes |
json
{
"question": "What is our travel reimbursement limit?"
}Response 200 — Category.
| Field | Type | Description |
|---|---|---|
category | string |
json
{
"category": "HR"
}Example
bash
curl -X POST "https://api.example.com/secure-gpt/category/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"question":"What is our travel reimbursement limit?"}'POST /secure-gpt/chat/
Stream a model reply (direct, no agent)
A plain model completion without the agent's tools, streamed as it is generated. This is the engine behind the enterprise chat mode and older app flows; the Chat AI page itself uses POST /microservices/agent/chat/.
type selects the mode:
general— answer from the model only.app— same asgeneral(used by published apps).enterprise— classify the question into a role category, refuse if the user lacks that role, otherwise answer from the organisation's documents tagged with that role. The user's prompt is stored automatically in this mode.
The response body is the answer text streamed in chunks (content type text/event-stream, but not SSE-framed — concatenate the chunks). See Streaming & WebSockets.
Auth: Session token · In the app: Enterprise chat mode
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
question | string | yes | |
type | string ("general", "app", "enterprise") | no | Default: "general". |
session | integer | no | Session id (must be the caller's). |
chat_history | string | no | JSON-encoded array of prior messages [{"message": "...", "from_server": false}, …]. |
thinking | boolean | no | Accepted for compatibility; ignored. |
json
{
"question": "Explain net revenue retention in one paragraph.",
"type": "general",
"session": 9174,
"chat_history": "[]"
}Response 200 — Streamed answer text.
Content type: text/event-stream
text
Net revenue retention (NRR) measures how much recurring revenue from existing customers…Response 400 — question missing.
json
{
"error": "Question is required"
}Example
bash
curl -X POST "https://api.example.com/secure-gpt/chat/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"question":"Explain net revenue retention in one paragraph.","type":"general","session":9174,"chat_history":"[]"}'POST /semantic-search/single-file-chat/
Chat with one document
Retrieval-augmented answer over a single document in the semantic-search store. Streams the answer text. The stream starts with a JSON array of sources ([["Q3-report.pdf", 3, 7], …] — file name, page, chunk), immediately followed by the answer text. Bracket-match the array to split the two.
Bodies may be JSON or multipart form fields (the app sends form fields).
Auth: Session token · In the app: My Data → Chat with a selected document
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | |
document_name | string | yes | File name of the document. |
file_uid | string (uuid) | no | Document uid. |
chat_history | object[] | no | Prior turns (a JSON-encoded string is also accepted). |
chat_history[].HumanMessage | string | no | A user turn. |
chat_history[].AIMessage | string | no | An assistant turn. |
json
{
"query": "What are the key risks listed?",
"document_name": "Q3-report.pdf",
"file_uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"chat_history": []
}Response 200 — Sources array followed by streamed answer text.
Content type: text/event-stream
text
[["Q3-report.pdf", 12, 3], ["Q3-report.pdf", 13, 1]]The report lists three key risks: …Response 400 — Missing fields.
json
{
"detail": "document_name and query are required"
}Example
bash
curl -X POST "https://api.example.com/semantic-search/single-file-chat/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"What are the key risks listed?","document_name":"Q3-report.pdf","file_uid":"1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b","chat_history":[]}'POST /semantic-search/multi-file-chat/
Chat with several documents
Same contract as single-file chat, over a list of document uids. The stream begins with the sources array, then the answer.
Auth: Session token · In the app: My Data → Chat with several selected documents
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | |
files_list | string (uuid)[] | yes | Document uids (a JSON-encoded string is also accepted). Must be non-empty. |
chat_history | object[] | no | |
chat_history[].HumanMessage | string | no | A user turn. |
chat_history[].AIMessage | string | no | An assistant turn. |
json
{
"query": "Compare the two proposals' pricing.",
"files_list": [
"1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"2c7d2d2f-0e1b-4c7f-8a3b-4d5e6f7a8b9c"
]
}Response 200 — Sources array followed by streamed answer text.
Content type: text/event-stream
Response 400 — files_list missing, empty, or not a JSON array.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X POST "https://api.example.com/semantic-search/multi-file-chat/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"Compare the two proposals' pricing.","files_list":["1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b","2c7d2d2f-0e1b-4c7f-8a3b-4d5e6f7a8b9c"]}'POST /semantic-search/all-files-chat/
Chat across all my documents
Retrieval over the user's whole indexed corpus. The stream begins with a JSON array of the source file paths, a || delimiter, then the answer: ["/media/Acme/semantic-search/jane/Q3-report.pdf"]||The report….
Auth: Session token · In the app: My Data → Chat → "All files"
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | |
chat_history | object[] | no | |
chat_history[].HumanMessage | string | no | A user turn. |
chat_history[].AIMessage | string | no | An assistant turn. |
deep_search | boolean | no | Accepted for compatibility. Default: false. |
limit | integer | no | Accepted for compatibility (number of chunks). |
json
{
"query": "Which contracts renew in December?"
}Response 200 — Source paths, \|\|, then streamed answer text.
Content type: text/event-stream
text
["/media/Acme/semantic-search/jane/MSA-Globex.pdf"]||Two contracts renew in December: …Response 400 — query missing.
json
{
"error": "Query is required."
}Example
bash
curl -X POST "https://api.example.com/semantic-search/all-files-chat/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"Which contracts renew in December?"}'POST /semantic-search/advanced-search/
Chat with one document using its summary (advanced)
Variant of single-file chat that also feeds the document's stored summary to the model and filters retrieval by a similarity threshold. Streams the answer text.
Auth: Session token
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | |
file_uuid | string (uuid) | yes | |
threshold | number | yes | Minimum similarity score for a chunk to be used (0–1). |
language | string ("english", "arabic") | no | Which stored summary to use. |
chat_history | object[] | no | |
chat_history[].HumanMessage | string | no | A user turn. |
chat_history[].AIMessage | string | no | An assistant turn. |
json
{
"query": "Summarise the payment terms.",
"file_uuid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
"threshold": 0.6,
"language": "english"
}Response 200 — Streamed answer text.
Content type: text/event-stream
Response 400 — Missing fields.
json
{
"detail": "Authentication credentials were not provided."
}Example
bash
curl -X POST "https://api.example.com/semantic-search/advanced-search/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"Summarise the payment terms.","file_uuid":"1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b","threshold":0.6,"language":"english"}'POST /semantic-search/doc-from-chunks/
Full text of a document
Reassembles the document's text from its indexed chunks (Markdown). Handy for feeding a whole document to another tool.
Auth: Session token · In the app: Document viewer → text view
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
file_id | string (uuid) | yes |
json
{
"file_id": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b"
}Response 200 — The text.
| Field | Type | Description |
|---|---|---|
document_content | string |
json
{
"document_content": "# Q3 Report\n\nRevenue grew 12.4% …"
}Response 400 — file_id missing.
json
{
"error": "path is required"
}Response 404 — Not your document, or the file is missing on disk.
json
{
"error": "File does not exist."
}Response 503 — The chunk store is temporarily unavailable — retry.
json
{
"error": "path is required"
}Example
bash
curl -X POST "https://api.example.com/semantic-search/doc-from-chunks/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"file_id":"1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b"}'POST /semantic-search/chat/
Chat with documents by file name (legacy)
Older in-process document chat: selects documents by file name rather than uid, stores the user's prompt itself, and streams grouped sources followed by the answer. Kept for the legacy Semantic Search page; new integrations should use single-file-chat/ / multi-file-chat/.
Auth: Session token
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
question | string | yes | |
filename | string | yes | Comma-separated file names. |
session | integer | no | |
retriever | string | no | Retriever type selector (app-specific). |
Response 200 — Grouped sources, then streamed answer text.
Content type: text/event-stream
Example
bash
curl -X POST "https://api.example.com/semantic-search/chat/" \
-H "Authorization: Token $FINBLADE_TOKEN"POST /semantic-search/store/
Store a document-chat message
Counterpart of secure-gpt/store/ for document-chat threads (semantic_search sessions); additionally records the sources the answer cited.
Auth: Session token · In the app: My Data chat, after every message and reply
Request body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
response | string | yes | |
sources | string | yes | JSON-encoded array of sources (as streamed). Use "[]" for a user prompt. |
session | integer | no | |
user_message | boolean | no | |
is_encrypted | boolean | no | Default: false. |
json
{
"session": 9201,
"response": "What are the key risks listed?",
"sources": "[]",
"user_message": true
}Response 200 — Stored ("stored").
json
"stored"Example
bash
curl -X POST "https://api.example.com/semantic-search/store/" \
-H "Authorization: Token $FINBLADE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"session":9201,"response":"What are the key risks listed?","sources":"[]","user_message":true}'GET /semantic-search/
All my document-chat messages
Auth: Session token
Response 200 — Messages.
Array of:
| Field | Type | Description |
|---|---|---|
id | integer | |
user | integer | |
session | integer, nullable | |
from_server | boolean | |
message | string | |
is_encrypted | boolean | |
sources | any[] | Source citations as stored by the client (see the chat endpoints). |
created_at | string (date-time) |
Example
bash
curl -X GET "https://api.example.com/semantic-search/" \
-H "Authorization: Token $FINBLADE_TOKEN"