Skip to content

My Data — documents

Uploading, listing, organising, sharing and deleting the files in My Data, plus the AI features that run over them: summaries, generated questions, semantic search and document Q&A.

Three stores, one shape

Files are kept in module-specific stores that share the same URL shape:

StorePrefixHolds
Semantic search/semantic-search/PDFs, Office documents, text, images — chunked and embedded for retrieval
Database search/database-search/CSV/Excel treated as tabular data for the database chat
Spreadsheet search/spreadsheet-search/Spreadsheets for the spreadsheet chat

Each store exposes upload/, documents/, <uid>/delete/, folder/… and a chat/ endpoint. The semantic-search store is the richest and is the one the My Data page is built on; the other two are documented where they differ.

Processing status

An upload returns immediately; embedding happens in the background. Poll GET /semantic-search/documents/status/ (batched) or read the status field of GET /semantic-search/documents/ until the document is completed.

Endpoints

MethodPathPurpose
POST/semantic-search/upload/Upload a document
POST/semantic-search/upload/batch/Upload several documents at once
GET/semantic-search/upload/batch/{batch_id}/status/Status of a batch upload
GET/semantic-search/documents/List my documents
GET/semantic-search/documents/status/Documents still processing
POST/semantic-search/documents/status/Status of specific documents
GET/semantic-search/documents/{uid}/Get one document
PUT/semantic-search/{uid}/update/Move a document to a folder
DELETE/semantic-search/{uid}/delete/Move a document to the trash
GET/semantic-search/documents/trash/List trashed documents
POST/semantic-search/{uid}/restore/Restore a document from the trash
DELETE/semantic-search/{uid}/permanent-delete/Delete a document permanently
DELETE/semantic-search/folder/delete/Move a folder to the trash
POST/semantic-search/folder/move/Move or rename a folder
GET/semantic-search/documents/{uid}/users/Who a document is shared with
POST/semantic-search/documents/{uid}/users/add/Share a document with users
POST/semantic-search/documents/{uid}/users/remove/Stop sharing a document with users
GET/semantic-search/documents/requests/Access requests
POST/semantic-search/documents/request/Request access to a document
DELETE/semantic-search/documents/request/Cancel my pending request
POST/semantic-search/documents/approve/Approve an access request
POST/semantic-search/documents/deny/Deny an access request
POST/semantic-search/documents/revoke/Revoke previously granted access
GET/semantic-search/{uid}/summary/Document summary & suggested prompts
POST/semantic-search/{uid}/summary/generate/Generate the summary & prompts
GET/semantic-search/{uid}/questions/Suggested prompts for a document
POST/semantic-search/questions/Add suggested prompts to a document
POST/semantic-search/summaries/Template-generated summaries
POST/semantic-search/rewrite-summary/Generate a summary from a prompt template
POST/semantic-search/search/Semantic search across my documents
POST/semantic-search/re-embed/Re-index documents
POST/database-search/upload/Upload a CSV/Excel for the database chat
GET/database-search/documents/List my database-search files
PUT/database-search/{uid}/update/Move a database-search file to a folder
DELETE/database-search/{uid}/delete/Delete a database-search file
DELETE/database-search/folder/delete/Delete a database-search folder
POST/database-search/folder/move/Move or rename a database-search folder
POST/database-search/chat/Ask a question about a CSV/Excel file
POST/database-search/store/Store a database-chat message
GET/database-search/{uid}/thoughts/Analysis notes for a database-search file
GET/database-search/All my database-chat messages
POST/spreadsheet-search/upload/Upload a spreadsheet for the spreadsheet chat
GET/spreadsheet-search/documents/List my spreadsheet-search files
DELETE/spreadsheet-search/{uid}/delete/Delete a spreadsheet-search file
POST/spreadsheet-search/chat/Chat with a spreadsheet (streamed)
POST/spreadsheet-search/store/Store a spreadsheet-chat reply

POST /semantic-search/upload/

Upload a document

Stores the file and, unless train_after_upload is false, queues it for indexing (text extraction, chunking, embedding). The response is immediate; follow progress with documents/status/ or the document's processing_state.

Supported types include PDF, Word, PowerPoint, text/Markdown, images (with ocr) and CSV/Excel. Files are virus-scanned; a rejected file returns 400 with reasons. Storage quotas apply when the deployment enforces them.

Re-uploading a SharePoint file (sharepoint_drive_item_id set) that already exists simply shares the existing document with you and returns 200.

Auth: Session token · In the app: My Data → Upload

Request body (multipart/form-data)

FieldTypeRequiredDescription
pathstring (binary)yesThe file.
folderstringnoVirtual folder path, e.g. Finance/2026. Default root.
train_after_uploadbooleannofalse stores the file without indexing (state untrained). Default: true.
ocrbooleannoRun OCR on scanned PDFs and images. Default: false.
sharepoint_drive_item_idstringnoSet by the SharePoint importer.
text
path: @Q3-report.pdf
folder: Finance/2026
ocr: false

Response 200 — SharePoint file already imported — shared with you instead.

FieldTypeDescription
uidstring (uuid)
folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
page_numberintegerPages processed so far (also total pages once complete).
labelsinteger
doc_classstringDocument class inferred when the summary is generated (e.g. contract).
statusstringHuman-readable processing status text.
processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
enqueue_attempt_countinteger
last_errorstring
queued_atstring (date-time), nullable
processing_started_atstring (date-time), nullable
completed_atstring (date-time), nullable
from_dmsboolean
sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
created_atstring (date-time)
json
{
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "folder": "Finance/2026",
  "path": "/media/Acme/semantic-search/jane/Q3-report.pdf",
  "page_number": 24,
  "labels": 1,
  "doc_class": "report",
  "status": "100% - Complete",
  "processing_state": "completed",
  "enqueue_attempt_count": 1,
  "last_error": "",
  "queued_at": "2026-09-20T09:00:02Z",
  "processing_started_at": "2026-09-20T09:00:05Z",
  "completed_at": "2026-09-20T09:01:40Z",
  "from_dms": false,
  "sharepoint_drive_item_id": null,
  "created_at": "2026-09-20T09:00:01Z"
}

Response 201 — Stored and queued (or stored untrained).

FieldTypeDescription
uidstring (uuid)
folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
page_numberintegerPages processed so far (also total pages once complete).
labelsinteger
doc_classstringDocument class inferred when the summary is generated (e.g. contract).
statusstringHuman-readable processing status text.
processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
enqueue_attempt_countinteger
last_errorstring
queued_atstring (date-time), nullable
processing_started_atstring (date-time), nullable
completed_atstring (date-time), nullable
from_dmsboolean
sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
created_atstring (date-time)
upload_idstringCorrelation id for the processing pipeline.
queue_pendingbooleanPresent when the queue was unavailable; the file will be retried automatically.
queue_errorstring
json
{
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "folder": "Finance/2026",
  "path": "/media/Acme/semantic-search/jane/Q3-report.pdf",
  "page_number": 1,
  "labels": 1,
  "doc_class": "",
  "status": "Queued",
  "processing_state": "queued",
  "enqueue_attempt_count": 1,
  "last_error": "",
  "queued_at": "2026-09-22T07:10:02Z",
  "processing_started_at": null,
  "completed_at": null,
  "from_dms": false,
  "sharepoint_drive_item_id": null,
  "created_at": "2026-09-22T07:10:01Z",
  "upload_id": "8b1f2c3d"
}

Response 400 — Validation error or the file failed the security scan.

json
{
  "detail": "File failed security scan.",
  "reasons": [
    "Executable content detected"
  ]
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/upload/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -F "path=@Q3-report.pdf" \
  -F "folder=Finance/2026"

POST /semantic-search/upload/batch/

Upload several documents at once

Multiple files under the files field, one folder for all. Each file is scanned and queued independently; the response reports per-file outcomes and a batch_id to poll.

Auth: Session token

Request body (multipart/form-data)

FieldTypeRequiredDescription
filesstring (binary)[]yes
folderstringno
ocrbooleannoDefault: false.

Response 202 — Accepted.

FieldTypeDescription
batch_idstring (uuid)
totalinteger
resultsobject[]
results[].filenamestring
results[].uidstring
results[].upload_idstring
results[].statusstring ("queued", "pending_publish", "untrained", "blocked", "rejected")
results[].reasonsstring[]
results[].errorsobject
json
{
  "batch_id": "6f1e2d3c-4b5a-4c6d-8e9f-0a1b2c3d4e5f",
  "total": 2,
  "results": [
    {
      "filename": "a.pdf",
      "uid": "1b6c…",
      "upload_id": "8b1f2c3d",
      "status": "queued"
    },
    {
      "filename": "b.exe",
      "status": "blocked",
      "reasons": [
        "Executable content detected"
      ]
    }
  ]
}

Response 400 — No files.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/upload/batch/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/upload/batch/{batch_id}/status/

Status of a batch upload

Auth: Session token

Path parameters

FieldTypeRequiredDescription
batch_idstring (uuid)yes

Response 200 — Batch progress.

FieldTypeDescription
batch_idstring
statestring ("accepted", "processing", "completed", "partial", "failed")
source_typestring ("direct", "sharepoint", "sql")
totalinteger
completedinteger
failedinteger
pendinginteger
created_atstring (date-time)
completed_atstring (date-time), nullable
itemsobject[]
items[].idstring
items[].filenamestring
items[].statestring
items[].last_errorstring
items[].queued_atstring, nullable
items[].completed_atstring, nullable

Response 404 — Not your batch.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X GET "https://api.example.com/semantic-search/upload/batch/<batch_id>/status/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/documents/

List my documents

Documents you own plus documents shared with you, newest first, excluding the trash. folder is omitted on shared documents.

Auth: Session token · In the app: My Data file table

Response 200 — Documents.

Array of:

FieldTypeDescription
uidstring (uuid)
folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
page_numberintegerPages processed so far (also total pages once complete).
labelsinteger
doc_classstringDocument class inferred when the summary is generated (e.g. contract).
statusstringHuman-readable processing status text.
processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
enqueue_attempt_countinteger
last_errorstring
queued_atstring (date-time), nullable
processing_started_atstring (date-time), nullable
completed_atstring (date-time), nullable
from_dmsboolean
sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/documents/status/

Documents still processing

Every visible document in a non-terminal state (stored, pending_publish, queued, processing). Cheap; meant for polling.

Auth: Session token · Rate limit: 120/min (own scope) · In the app: My Data status badges (polled every few seconds while uploads run)

Response 200 — Minimal rows.

Array of:

FieldTypeDescription
uidstring
processing_statestring
statusstring
last_errorstring
created_atstring (date-time)
json
[
  {
    "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
    "processing_state": "processing",
    "status": "45% - Embedding",
    "last_error": "",
    "created_at": "2026-09-22T07:10:01Z"
  }
]

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/status/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/status/

Status of specific documents

Current state of up to 500 documents by uid, whatever state they are in.

Auth: Session token · Rate limit: 120/min (own scope)

Request body (application/json)

FieldTypeRequiredDescription
uidsstring (uuid)[]yes
json
{
  "uids": [
    "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b"
  ]
}

Response 200 — Minimal rows (unknown uids are omitted).

Array of:

FieldTypeDescription
uidstring
processing_statestring
statusstring
last_errorstring
created_atstring (date-time)

Response 400uids not a list, or more than 500.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/status/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"uids":["1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b"]}'

GET /semantic-search/documents/{uid}/

Get one document

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — The document (no folder if it is only shared with you).

FieldTypeDescription
uidstring (uuid)
folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
page_numberintegerPages processed so far (also total pages once complete).
labelsinteger
doc_classstringDocument class inferred when the summary is generated (e.g. contract).
statusstringHuman-readable processing status text.
processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
enqueue_attempt_countinteger
last_errorstring
queued_atstring (date-time), nullable
processing_started_atstring (date-time), nullable
completed_atstring (date-time), nullable
from_dmsboolean
sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
created_atstring (date-time)
json
{
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "folder": "Finance/2026",
  "path": "/media/Acme/semantic-search/jane/Q3-report.pdf",
  "page_number": 24,
  "labels": 1,
  "doc_class": "report",
  "status": "100% - Complete",
  "processing_state": "completed",
  "enqueue_attempt_count": 1,
  "last_error": "",
  "queued_at": "2026-09-20T09:00:02Z",
  "processing_started_at": "2026-09-20T09:00:05Z",
  "completed_at": "2026-09-20T09:01:40Z",
  "from_dms": false,
  "sharepoint_drive_item_id": null,
  "created_at": "2026-09-20T09:00:01Z"
}

Response 404 — Not found or no access.

json
{
  "error": "path is required"
}

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

PUT /semantic-search/{uid}/update/

Move a document to a folder

Only folder can be changed (renaming files is not supported). Owner only.

Auth: Session token · In the app: My Data → drag & drop / Move

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Request body (application/json)

FieldTypeRequiredDescription
folderstringyesNew folder path ("" for root).
json
{
  "folder": "Finance/2025"
}

Response 200 — Updated document.

FieldTypeDescription
uidstring (uuid)
folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
page_numberintegerPages processed so far (also total pages once complete).
labelsinteger
doc_classstringDocument class inferred when the summary is generated (e.g. contract).
statusstringHuman-readable processing status text.
processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
enqueue_attempt_countinteger
last_errorstring
queued_atstring (date-time), nullable
processing_started_atstring (date-time), nullable
completed_atstring (date-time), nullable
from_dmsboolean
sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
created_atstring (date-time)
json
{
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "folder": "Finance/2026",
  "path": "/media/Acme/semantic-search/jane/Q3-report.pdf",
  "page_number": 24,
  "labels": 1,
  "doc_class": "report",
  "status": "100% - Complete",
  "processing_state": "completed",
  "enqueue_attempt_count": 1,
  "last_error": "",
  "queued_at": "2026-09-20T09:00:02Z",
  "processing_started_at": "2026-09-20T09:00:05Z",
  "completed_at": "2026-09-20T09:01:40Z",
  "from_dms": false,
  "sharepoint_drive_item_id": null,
  "created_at": "2026-09-20T09:00:01Z"
}

Response 400 — A rename was attempted.

json
{
  "error": "Renaming is not supported from this endpoint."
}

Response 404 — Not your document.

json
{
  "error": "path is required"
}

Example

bash
curl -X PUT "https://api.example.com/semantic-search/<uid>/update/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"folder":"Finance/2025"}'

DELETE /semantic-search/{uid}/delete/

Move a document to the trash

Soft delete. The file stays recoverable for 30 days (SEMANTIC_TRASH_RETENTION_DAYS) and is then purged with its index. Owner only.

Auth: Session token · In the app: My Data → Delete

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Trashed.

FieldTypeDescription
statusstring ("trashed")
uidstring
deleted_atstring (date-time)
purge_atstring (date-time)
json
{
  "status": "trashed",
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "deleted_at": "2026-09-22T07:30:00Z",
  "purge_at": "2026-10-22T07:30:00Z"
}

Response 404 — Not your document (or already trashed).

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X DELETE "https://api.example.com/semantic-search/1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b/delete/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/documents/trash/

List trashed documents

Auth: Session token

Response 200 — Trashed documents with deleted_at and purge_at.

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/trash/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/{uid}/restore/

Restore a document from the trash

Restores the row and re-queues the file for indexing.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Restored.

FieldTypeDescription
statusstring ("restored")
uidstring
detailstring

Response 404 — No such trashed document.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/<uid>/restore/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /semantic-search/{uid}/permanent-delete/

Delete a document permanently

Removes the file, its index and its row immediately. Cannot be undone.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Purged.

FieldTypeDescription
statusstring ("permanently_deleted")
uidstring

Response 404 — Not your document.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X DELETE "https://api.example.com/semantic-search/<uid>/permanent-delete/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /semantic-search/folder/delete/

Move a folder to the trash

Trashes every owned document in the folder and its sub-folders. folder may be sent in the body or as a query parameter; "" targets files at the root.

Auth: Session token · In the app: My Data → folder → Delete

Query parameters

FieldTypeRequiredDescription
folderstringno

Response 200 — Trashed.

FieldTypeDescription
statusstring ("trashed")
countinteger
json
{
  "status": "trashed",
  "count": 7
}

Response 400folder missing.

json
{
  "error": "path is required"
}

Response 404 — Folder empty or unknown.

json
{
  "error": "path is required"
}

Example

bash
curl -X DELETE "https://api.example.com/semantic-search/folder/delete/?folder=Finance%2F2025" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/folder/move/

Move or rename a folder

Atomically rewrites the folder path of every owned document under from to sit under to. A rename is a move that keeps the same parent.

Auth: Session token · In the app: My Data → folder → Rename / Move

Request body (application/json)

FieldTypeRequiredDescription
fromstringyes
tostringyes
json
{
  "from": "Finance/2025",
  "to": "Archive/Finance-2025"
}

Response 200 — Moved.

FieldTypeDescription
statusstring ("moved")
countinteger
fromstring
tostring

Response 400 — Missing from, or moving a folder into itself.

json
{
  "error": "path is required"
}

Response 404 — Folder empty or unknown.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/folder/move/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"from":"Finance/2025","to":"Archive/Finance-2025"}'

GET /semantic-search/documents/{uid}/users/

Who a document is shared with

Auth: Session token · In the app: Share dialog

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Owner and users.

FieldTypeDescription
ownerobject
owner.idinteger
owner.usernamestring
owner.emailstring
usersobject[]
users[].idinteger
users[].usernamestring
users[].emailstring
json
{
  "owner": {
    "id": 42,
    "username": "jane",
    "email": "jane@acme.com"
  },
  "users": [
    {
      "id": 57,
      "username": "omar",
      "email": "omar@acme.com"
    }
  ]
}

Response 404 — Unknown document.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/<uid>/users/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/{uid}/users/add/

Share a document with users

Adds users by email. For SharePoint-sourced documents the sharing is mirrored to SharePoint in the background.

Auth: Session token · In the app: Share dialog → Add

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Request body (application/json)

FieldTypeRequiredDescription
emailsstring (email)[]yes
json
{
  "emails": [
    "omar@acme.com",
    "sara@acme.com"
  ]
}

Response 200 — Result.

FieldTypeDescription
addedstring[]
not_foundstring[]
detailstring
json
{
  "added": [
    "omar@acme.com"
  ],
  "not_found": [
    "sara@acme.com"
  ],
  "detail": "1 user(s) added. 1 email(s) not found."
}

Response 400 — No emails.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/<uid>/users/add/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"emails":["omar@acme.com","sara@acme.com"]}'

POST /semantic-search/documents/{uid}/users/remove/

Stop sharing a document with users

Auth: Session token · In the app: Share dialog → Remove

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Request body (application/json)

FieldTypeRequiredDescription
emailsstring (email)[]yes

Response 200 — Result.

FieldTypeDescription
removedstring[]
not_foundstring[]
detailstring

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/<uid>/users/remove/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/documents/requests/

Access requests

Without my, requests for your documents (to approve or deny). With my=1, requests you made.

Auth: Session token · In the app: Notifications → Access requests

Query parameters

FieldTypeRequiredDescription
mystringnoAny value switches to requests you made.

Response 200 — Requests.

Array of:

FieldTypeDescription
idinteger
documentobjectA file in the semantic-search store.
document.uidstring (uuid)
document.folderstringVirtual folder path ("" = root). Hidden on documents shared to you.
document.pathstringMedia URL of the file (/media/<org>/semantic-search/<user>/<name>). Sign it to download.
document.page_numberintegerPages processed so far (also total pages once complete).
document.labelsinteger
document.doc_classstringDocument class inferred when the summary is generated (e.g. contract).
document.statusstringHuman-readable processing status text.
document.processing_statestring ("stored", "pending_publish", "queued", "processing", "completed", "failed", "publish_failed", "untrained")Machine state. completed means the file is indexed and chat-ready; untrained means it was uploaded with training off.
document.enqueue_attempt_countinteger
document.last_errorstring
document.queued_atstring (date-time), nullable
document.processing_started_atstring (date-time), nullable
document.completed_atstring (date-time), nullable
document.from_dmsboolean
document.sharepoint_drive_item_idstring, nullableSet when the file was imported from SharePoint/OneDrive.
document.created_atstring (date-time)
userobjectThe requester.
user.idinteger
user.first_namestring
user.last_namestring
user.usernamestring
user.emailstring
user.phoneinteger, nullable
statusstring ("pending", "approved", "denied", "revoked")
created_atstring (date-time)
updated_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/semantic-search/documents/requests/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/request/

Request access to a document

Identify the document by its media path. Duplicate pending/approved requests are rejected.

Auth: Session token · In the app: Shared files → Request access

Request body (application/json)

FieldTypeRequiredDescription
pathstringyesThe document's media path (/media/... or media/...).
json
{
  "path": "/media/Acme/semantic-search/omar/policy.pdf"
}

Response 201 — Requested.

FieldTypeDescription
detailstringHuman-readable explanation.
codestringMachine-readable error code (present on some responses).
json
{
  "detail": "Document access requested"
}

Response 400 — A request already exists.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 404 — No document at that path.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/request/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"path":"/media/Acme/semantic-search/omar/policy.pdf"}'

DELETE /semantic-search/documents/request/

Cancel my pending request

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
request_idintegeryes

Response 200 — Deleted (or, when not pending, {"error": "Document status is not pending"}).

FieldTypeDescription
statusstring
json
{
  "status": "deleted"
}

Example

bash
curl -X DELETE "https://api.example.com/semantic-search/documents/request/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/approve/

Approve an access request

Owner only. Shares the document with the requester and notifies them.

Auth: Session token · In the app: Notifications → Access requests → Approve

Request body (application/json)

FieldTypeRequiredDescription
request_idintegeryes

Response 200 — Approved.

FieldTypeDescription
detailstringHuman-readable explanation.
codestringMachine-readable error code (present on some responses).
json
{
  "detail": "Document request approved"
}

Response 400 — Already processed.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 404 — Not found or you are not the owner.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/approve/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/deny/

Deny an access request

Auth: Session token · In the app: Notifications → Access requests → Deny

Request body (application/json)

FieldTypeRequiredDescription
request_idintegeryes

Response 200 — Denied.

FieldTypeDescription
detailstringHuman-readable explanation.
codestringMachine-readable error code (present on some responses).
json
{
  "detail": "Document request denied"
}

Response 400 — Already processed.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 404 — Not found or you are not the owner.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/deny/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/documents/revoke/

Revoke previously granted access

Auth: Session token · In the app: Notifications → Access requests → Revoke

Request body (application/json)

FieldTypeRequiredDescription
request_idintegeryes

Response 200 — Revoked.

FieldTypeDescription
detailstringHuman-readable explanation.
codestringMachine-readable error code (present on some responses).
json
{
  "detail": "User access revoked"
}

Response 404 — Not found or you are not the owner.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/documents/revoke/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/{uid}/summary/

Document summary & suggested prompts

Auth: Session token · In the app: Document viewer → Summary

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Query parameters

FieldTypeRequiredDescription
languagestring ("en", "ar")noDefault: "en".

Response 200 — Summary payload (available: false when none has been generated yet).

FieldTypeDescription
languagestring ("en", "ar")
availablebooleanWhether a summary exists for this language.
summarystring, nullable
doc_classstring
questionsstring[]Suggested prompts for the document.
generated_atstring (date-time), nullable
template_summariesstring[]Summaries produced from prompt templates (rewrite-summary/).
json
{
  "language": "en",
  "available": true,
  "summary": "The Q3 report covers revenue growth of 12.4%, margin expansion …",
  "doc_class": "report",
  "questions": [
    "What drove the margin expansion?",
    "Which region underperformed?"
  ],
  "generated_at": "2026-09-20T09:02:10Z",
  "template_summaries": []
}

Response 404 — Not found or no access.

json
{
  "detail": "Document does not exist"
}

Example

bash
curl -X GET "https://api.example.com/semantic-search/<uid>/summary/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/{uid}/summary/generate/

Generate the summary & prompts

Produces the summary, document class and suggested prompts for one language from the indexed text. Returns 200 exists if one is already there, 409 while another generation is running.

Auth: Session token · In the app: Document viewer → Generate summary

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Query parameters

FieldTypeRequiredDescription
languagestring ("en", "ar")noDefault: "en".

Response 200 — Already existed.

FieldTypeDescription
statusstring ("exists")
languagestring ("en", "ar")
availablebooleanWhether a summary exists for this language.
summarystring, nullable
doc_classstring
questionsstring[]Suggested prompts for the document.
generated_atstring (date-time), nullable
template_summariesstring[]Summaries produced from prompt templates (rewrite-summary/).

Response 201 — Generated.

FieldTypeDescription
statusstring ("generated")
languagestring ("en", "ar")
availablebooleanWhether a summary exists for this language.
summarystring, nullable
doc_classstring
questionsstring[]Suggested prompts for the document.
generated_atstring (date-time), nullable
template_summariesstring[]Summaries produced from prompt templates (rewrite-summary/).

Response 400 — The document has no indexed content yet.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 409 — Generation already in progress.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 502 — Summary service unavailable.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 503 — Chunk store temporarily unavailable — retry.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/<uid>/summary/generate/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /semantic-search/{uid}/questions/

Suggested prompts for a document

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Query parameters

FieldTypeRequiredDescription
languagestring ("en", "ar")noDefault: "en".

Response 200 — Prompts.

Array of:

FieldTypeDescription
contentstring
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/semantic-search/<uid>/questions/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/questions/

Add suggested prompts to a document

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
uidstring (uuid)yes
questionsstring[]yes
languagestring ("en", "ar")noDefault: "en".
json
{
  "uid": "1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b",
  "questions": [
    "What are the payment terms?"
  ]
}

Response 201 — Created.

FieldTypeDescription
statusstring
countinteger

Response 400 — Missing uid or questions.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/questions/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"uid":"1b6c1c1e-9d0a-4b6e-9f2a-3c4d5e6f7a8b","questions":["What are the payment terms?"]}'

POST /semantic-search/summaries/

Template-generated summaries

Summaries produced with a prompt template for one document, or for one chat session.

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
template_idintegeryes
document_idstring (uuid)no
session_idintegerno

Response 200 — Summaries.

FieldTypeDescription
summariesobject[]
summaries[].idinteger
summaries[].documentstring, nullable
summaries[].templateinteger
summaries[].sessioninteger, nullable
summaries[].contentstring
summaries[].created_atstring (date-time)

Response 400 — Neither document nor session given.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/summaries/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /semantic-search/rewrite-summary/

Generate a summary from a prompt template

Runs the template's prompt over a document (by file name), or over free text query bound to a document or a session, and stores the result.

Auth: Session token · In the app: My Data → Templates → Apply

Request body (application/json)

FieldTypeRequiredDescription
template_idintegeryes
document_namestringnoFile name of one of your semantic-search documents.
session_idintegerno
querystringnoText to summarise instead of the document (required with session_id).
json
{
  "template_id": 12,
  "document_name": "Q3-report.pdf"
}

Response 200 — The summary.

FieldTypeDescription
summarystring

Response 400 — Missing document/session.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/rewrite-summary/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"template_id":12,"document_name":"Q3-report.pdf"}'

POST /semantic-search/search/

Semantic search across my documents

Vector search over the user's index; returns the matching chunks with scores. 204 when nothing scores above the threshold.

Auth: Session token · In the app: My Data → search bar (relevance slider)

Request body (application/json)

FieldTypeRequiredDescription
querystringyes
score_thresholdnumberyesMinimum similarity (0–1).
json
{
  "query": "termination clause notice period",
  "score_threshold": 0.5
}

Response 200 — Results grouped by document (shape defined by the search service).

FieldTypeDescription
resultsobject

Response 204 — No results.

Example

bash
curl -X POST "https://api.example.com/semantic-search/search/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"termination clause notice period","score_threshold":0.5}'

POST /semantic-search/re-embed/

Re-index documents

Drops the existing index of the given documents (or all of yours) and queues them again — use after changing the embedding model or when a document looks stale.

Auth: Session token

Request body (application/json, optional)

FieldTypeRequiredDescription
uidsstring (uuid)[]noOmit to re-index everything you own.

Response 200 — All queued.

FieldTypeDescription
detailstring
queued_documentsstring[]
failed_documentsobject[]

Response 207 — Some queued, some failed.

Response 404 — No documents.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 503 — Nothing could be queued.

json
{
  "detail": "Authentication credentials were not provided."
}

Example

bash
curl -X POST "https://api.example.com/semantic-search/re-embed/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /database-search/upload/

Upload a CSV/Excel for the database chat

Stores the spreadsheet and queues it for tabular indexing. Answer questions over it with POST /database-search/chat/.

Auth: Session token · In the app: My Data → Upload (spreadsheets)

Request body (multipart/form-data)

FieldTypeRequiredDescription
pathstring (binary)yes
folderstringno

Response 201 — Stored and queued.

FieldTypeDescription
uidstring (uuid)
folderstring
pathstring/media/<org>/database-search/<user>/<name>
created_atstring (date-time)
upload_idstring

Response 400 — Validation error.

json
{
  "username": [
    "A user with that username already exists."
  ]
}

Response 503 — Stored but could not be queued; retry later.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/database-search/upload/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /database-search/documents/

List my database-search files

Auth: Session token

Response 200 — Files.

Array of:

FieldTypeDescription
uidstring (uuid)
folderstring
pathstring/media/<org>/database-search/<user>/<name>
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/database-search/documents/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

PUT /database-search/{uid}/update/

Move a database-search file to a folder

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Request body (application/json)

FieldTypeRequiredDescription
folderstringyes

Response 200 — Updated.

FieldTypeDescription
uidstring (uuid)
folderstring
pathstring/media/<org>/database-search/<user>/<name>
created_atstring (date-time)
json
{
  "uid": "2c7d2d2f-0e1b-4c7f-8a3b-4d5e6f7a8b9c",
  "folder": "",
  "path": "/media/Acme/database-search/jane/sales-2026.csv",
  "created_at": "2026-09-18T14:12:00Z"
}

Response 404 — Not your file.

json
{
  "error": "path is required"
}

Example

bash
curl -X PUT "https://api.example.com/database-search/<uid>/update/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /database-search/{uid}/delete/

Delete a database-search file

Immediate, permanent (no trash for this store).

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Deleted.

FieldTypeDescription
statusstring ("deleted")

Example

bash
curl -X DELETE "https://api.example.com/database-search/<uid>/delete/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /database-search/folder/delete/

Delete a database-search folder

Auth: Session token

Query parameters

FieldTypeRequiredDescription
folderstringno

Response 200 — Deleted.

FieldTypeDescription
statusstring
countinteger
queue_warningsstring[]

Response 404 — Folder empty or unknown.

json
{
  "error": "path is required"
}

Example

bash
curl -X DELETE "https://api.example.com/database-search/folder/delete/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /database-search/folder/move/

Move or rename a database-search folder

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
fromstringyes
tostringyes

Response 200 — Moved.

FieldTypeDescription
statusstring
countinteger
fromstring
tostring

Example

bash
curl -X POST "https://api.example.com/database-search/folder/move/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /database-search/chat/

Ask a question about a CSV/Excel file

Runs the question against one database-search file through the analysis service and returns the answer plus any generated charts/files. Unlike the document chats this call is not streamed; both the question and the answer are stored in the session automatically.

Auth: Session token · In the app: My Data → Chat with a spreadsheet

Request body (application/json)

FieldTypeRequiredDescription
questionstringyes
doc_uidstring (uuid)yes
filenamestringyesFile name (used to locate the file on disk).
sessionintegernoSession id of type database_search.
json
{
  "question": "Total sales per region in Q2?",
  "doc_uid": "2c7d2d2f-0e1b-4c7f-8a3b-4d5e6f7a8b9c",
  "filename": "sales-2026.csv",
  "session": 9203
}

Response 200 — Answer.

FieldTypeDescription
resultstringAnswer text (Markdown).
generated_files_urlsstring[]Media URLs of charts/exports produced.
json
{
  "result": "Q2 sales by region: East 1.2M, West 0.9M, Central 0.7M.",
  "generated_files_urls": [
    "/media/Acme/database-search/jane/charts/q2-by-region.png"
  ]
}

Response 500 — Service not configured or returned an error (body carries details).

json
{
  "error": "path is required"
}

Response 503 — Analysis service unreachable.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/database-search/chat/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"question":"Total sales per region in Q2?","doc_uid":"2c7d2d2f-0e1b-4c7f-8a3b-4d5e6f7a8b9c","filename":"sales-2026.csv","session":9203}'

POST /database-search/store/

Store a database-chat message

Manual storage for the database chat (the chat endpoint already stores both sides; use this for client-side edits or chart configs).

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
responsestringno
sessionintegerno
user_messagebooleanno
imagesstring[]no
csv_filesstring[]no
chart_configobjectnoPersisted onto the session's query.
doc_uidstringno

Response 200 — Stored.

Response 404 — Session not found.

json
{
  "error": "path is required"
}

Example

bash
curl -X POST "https://api.example.com/database-search/store/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /database-search/{uid}/thoughts/

Analysis notes for a database-search file

Reasoning notes recorded while the file was indexed.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Notes.

Array of:

FieldTypeDescription
idinteger
docstring
contentstring
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/database-search/<uid>/thoughts/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /database-search/

All my database-chat messages

Auth: Session token

Response 200 — Messages.

Array of:

FieldTypeDescription
idinteger
userinteger
sessioninteger, nullable
from_serverboolean
messagestring
imagesstring[]
csv_filesstring[]
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/database-search/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /spreadsheet-search/upload/

Upload a spreadsheet for the spreadsheet chat

Indexes the rows synchronously (row-wise embeddings). Legacy store used by the spreadsheet viewer.

Auth: Session token

Request body (multipart/form-data)

FieldTypeRequiredDescription
pathstring (binary)yes

Response 201 — Stored and indexed.

FieldTypeDescription
uidstring
pathstring
created_atstring (date-time)

Example

bash
curl -X POST "https://api.example.com/spreadsheet-search/upload/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /spreadsheet-search/documents/

List my spreadsheet-search files

Auth: Session token

Response 200 — Files.

Array of:

FieldTypeDescription
uidstring
pathstring
created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/spreadsheet-search/documents/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /spreadsheet-search/{uid}/delete/

Delete a spreadsheet-search file

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 200 — Deleted.

Response 404 — Not found.

json
{
  "error": "path is required"
}

Example

bash
curl -X DELETE "https://api.example.com/spreadsheet-search/<uid>/delete/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /spreadsheet-search/chat/

Chat with a spreadsheet (streamed)

Streams grouped sources followed by the answer, like the legacy semantic chat. Selects files by name.

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
questionstringyes
filenamestringyesComma-separated file names.
retrieverstringno

Response 200 — Streamed text.

Content type: text/event-stream

Example

bash
curl -X POST "https://api.example.com/spreadsheet-search/chat/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /spreadsheet-search/store/

Store a spreadsheet-chat reply

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
responsestringyes
sourcesstringyesJSON-encoded sources array.

Response 200 — Stored.

Example

bash
curl -X POST "https://api.example.com/spreadsheet-search/store/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

Finblade documentation