{"openapi":"3.1.0","info":{"title":"FutureSmart Document Intelligence API","version":"0.1.0","description":"Add documents, search them, ask questions with cited sources and read the fields extracted from each one. This is the public subset of the deployed contract: the operations a Document Intelligence API key can call."},"servers":[{"url":"https://futuresmart.ai/document-intelligence/api"}],"tags":[{"name":"Collections","description":"Collections your key can see. Collections are created in the app."},{"name":"Documents","description":"Add documents, follow their processing, and remove them."},{"name":"Batch upload","description":"Add up to 50 documents in one call."},{"name":"Search","description":"Find the passages that match a query."},{"name":"Chat","description":"Ask questions answered from the collection, with cited sources."},{"name":"Extracted fields","description":"The fields read out of every document, per document or as a table."},{"name":"Sections","description":"The indexed sections (chunks) a document was split into."},{"name":"Service","description":"Service status."}],"paths":{"/v1":{"get":{"tags":["Collections"],"summary":"List your collections","description":"List knowledge services. If owner_id is provided, returns every collection\nthat account can reach — owned and shared alike — as bare ids. If not\nprovided, returns all non-deleted knowledge services (master API key only).\n\ninclude=summary exists because a Home-style \"one card per collection\" UI\notherwise has to call GET /config and GET /enrichment per collection just\nto render a card — 1 + 2N requests for N collections, with no document\ncount available at all no matter how many extra calls are made (no\nendpoint returns one). This aggregates that in one extra pass over\nDocument/FieldConfiguration/KnowledgeConfig, grouped by knowledge_id, so\nit's a fixed number of queries regardless of N. See\ndocs/screen-api-flow-document-intelligence.md §3 (G2+G3).\n\nIncludes `collection_name` (G1) — null for a collection created before\nthat column existed, or created without one.\n\nOwned vs. shared is deliberately NOT distinguished in this response (no\n`owner_id` per item either — see docs/api/knowledge-invitations.md). The\nUI's own Share flow calls `GET /v1/validate\n?owner_id=…&knowledge_id=…` once per id from this list to split them into\nits \"My collections\" / \"Shared with me\" tabs — that is the intended\ndiscovery contract this endpoint feeds, not a separate \"shared\" listing.","operationId":"list_knowledge_v1_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"owner_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Id"}},{"name":"include","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Set to 'summary' to get per-collection document count, processing rollup, and field counts inline instead of a bare id list. Omit to keep the original bare-id response.","title":"Include"},"description":"Set to 'summary' to get per-collection document count, processing rollup, and field counts inline instead of a bare id list. Omit to keep the original bare-id response."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/upload-url":{"post":{"tags":["Documents"],"summary":"Get an upload URL","operationId":"get_upload_url_v1__knowledge_id__upload_url_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_get_upload_url_v1__knowledge_id__upload_url_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents":{"get":{"tags":["Documents"],"summary":"List documents","operationId":"list_documents_v1__knowledge_id__documents_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"content_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"}},{"name":"metadata_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional JSON-encoded metadata filter dict","title":"Metadata Filter"},"description":"Optional JSON-encoded metadata filter dict"},{"name":"include_source_id","in":"query","required":false,"schema":{"type":"boolean","description":"When true (with metadata_filter), return [{object_id, source_id}] instead of bare object_ids","default":false,"title":"Include Source Id"},"description":"When true (with metadata_filter), return [{object_id, source_id}] instead of bare object_ids"},{"name":"include_metadata","in":"query","required":false,"schema":{"type":"boolean","description":"When true (with metadata_filter), return [{object_id, metadata}] with full payload inline in a single call (avoids per-doc metadata fetches)","default":false,"title":"Include Metadata"},"description":"When true (with metadata_filter), return [{object_id, metadata}] with full payload inline in a single call (avoids per-doc metadata fetches)"},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Max docs for the filtered path (default 15; raise for full-folder reconcile sweeps)","title":"Limit"},"description":"Max docs for the filtered path (default 15; raise for full-folder reconcile sweeps)"},{"name":"match_all","in":"query","required":false,"schema":{"type":"boolean","description":"Optional. false (default) = loose OR (match at least one), preserving legacy behavior; true = strict AND (every metadata_filter field must match, e.g. to scope by space_id)","default":false,"title":"Match All"},"description":"Optional. false (default) = loose OR (match at least one), preserving legacy behavior; true = strict AND (every metadata_filter field must match, e.g. to scope by space_id)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"},"post":{"tags":["Documents"],"summary":"Add a document","operationId":"add_document_v1__knowledge_id__documents_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_add_document_v1__knowledge_id__documents_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v2/{knowledge_id}/documents":{"get":{"tags":["Documents"],"summary":"List documents (paginated)","description":"List documents with long-lived presigned URLs (7-day expiry with DB caching).\n\nSupports the Knowledge Upload Status window: search uploaded items by\nfile_name or object_id, and get direct links to both the original\nuploaded document and its parsed/extracted document. Also backs the\nKnowledge screen's document table — this endpoint previously returned\nevery matching document in one response with no pagination or sort,\nwhich was fine at small counts and wrong at any real one.\n\nSorted and paginated here in Python, not in SQL: retrieve_chatbot_knowledge_v2\ngroups crawled sub-pages under their parent document (sub_urls) AFTER\nfetching every matching row, so a SQL-level OFFSET/LIMIT could split a\nparent from its own children across pages. Sorting/slicing the\nalready-grouped result keeps every parent with its children on one\npage — the cost is holding the knowledge base's full filtered document\nset in memory for the sort, the same tradeoff the v2 tabular data view\n(get_data_view_tabular_v2) already makes for its multi-field sort.\nPresigned URLs are generated only for the returned page, not the whole\nset, so pagination is also what keeps this endpoint's S3 URL-signing\ncost bounded.\n\nReturns:\n    - source_presigned_url: Presigned URL for original uploaded file (7-day expiry, cached in DB)\n    - extracted_s3_url: Presigned URL for extracted markdown text (7-day expiry)\n    - source: where the document came from — \"clickup\" for a connector-synced page,\n      otherwise the row's content_type value unchanged (\"file\" / \"url\" / \"plain_text\").\n      Only \"clickup\" is new: a synced page is posted through the ordinary file_url\n      path, so content_type calls it a \"file\" and cannot tell the two apart; the\n      connector's identity survives only in extra_metadata.\n    - document_processing_mode: the mode the document was requested to be read in\n      (\"text_based\", \"scanned\", \"layout_aware\", \"visual\", \"mixed\"). Requested, not\n      effective — the worker may auto-shift a mode it finds wrong (an image-only PDF\n      shifts to OCR) and does not report that back to this service.\n    - total_count / current_page / total_pages: pagination metadata","operationId":"list_documents_v2_v2__knowledge_id__documents_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"content_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"}},{"name":"file_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search uploaded items by file name (case-insensitive partial match)","title":"File Name"},"description":"Search uploaded items by file name (case-insensitive partial match)"},{"name":"object_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search uploaded items by object ID (case-insensitive partial match)","title":"Object Id"},"description":"Search uploaded items by object ID (case-insensitive partial match)"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"1-indexed page number.","default":1,"title":"Page"},"description":"1-indexed page number."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Documents per page.","default":20,"title":"Page Size"},"description":"Documents per page."},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"One of: created_time, file_name, status, updated_time.","default":"created_time","title":"Sort By"},"description":"One of: created_time, file_name, status, updated_time."},{"name":"order","in":"query","required":false,"schema":{"type":"string","description":"'asc' or 'desc'.","default":"desc","title":"Order"},"description":"'asc' or 'desc'."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/{object_id}":{"delete":{"tags":["Documents"],"summary":"Delete a document","operationId":"delete_document_v1__knowledge_id__documents__object_id__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"object_id","in":"path","required":true,"schema":{"type":"string","title":"Object Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/{object_id}/status":{"get":{"tags":["Documents"],"summary":"Get a document's processing status","operationId":"get_document_status_v1__knowledge_id__documents__object_id__status_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"object_id","in":"path","required":true,"schema":{"type":"string","title":"Object Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/{object_id}/deletion-status":{"get":{"tags":["Documents"],"summary":"Get a document's deletion status","operationId":"get_document_deletion_status_v1__knowledge_id__documents__object_id__deletion_status_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"object_id","in":"path","required":true,"schema":{"type":"string","title":"Object Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/summaries":{"post":{"tags":["Documents"],"summary":"Get document summaries","operationId":"get_document_summaries_v2_v1__knowledge_id__documents_summaries_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search query over document summaries","title":"Query"},"description":"Search query over document summaries"},{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search mode: 'hybrid' (default, RRF fusion) or 'semantic' (dense-only)","default":"hybrid","title":"Mode"},"description":"Search mode: 'hybrid' (default, RRF fusion) or 'semantic' (dense-only)"},{"name":"metadata_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional JSON-encoded metadata filter dict","title":"Metadata Filter"},"description":"Optional JSON-encoded metadata filter dict"},{"name":"match_all","in":"query","required":false,"schema":{"type":"boolean","description":"Optional. Metadata-only path (no query): false (default) = loose OR; true = strict AND (e.g. to scope by space_id). The search path (query set) already applies filters as AND.","default":false,"title":"Match All"},"description":"Optional. Metadata-only path (no query): false (default) = loose OR; true = strict AND (e.g. to scope by space_id). The search path (query set) already applies filters as AND."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional limit for number of documents","title":"Limit"},"description":"Optional limit for number of documents"},{"name":"include_metadata","in":"query","required":false,"schema":{"type":"boolean","description":"Include document metadata with summaries","default":false,"title":"Include Metadata"},"description":"Include document metadata with summaries"},{"name":"include_summary","in":"query","required":false,"schema":{"type":"boolean","description":"Include document summary in response (default: true)","default":true,"title":"Include Summary"},"description":"Include document summary in response (default: true)"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDocumentSummariesRequest","default":{"object_ids":[]}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentSummariesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/upload-urls/batch":{"post":{"tags":["Batch upload"],"summary":"Get upload URLs for many files","description":"Generate presigned S3 URLs for multiple files in a single request.\nReturns a batch_id for tracking.","operationId":"batch_upload_urls_v1__knowledge_id__upload_urls_batch_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUploadUrlsRequest","description":"Batch upload request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUploadUrlsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/batch":{"post":{"tags":["Batch upload"],"summary":"Add many documents","description":"Process multiple files with shared configuration.\nAll files inherit identical processing settings.\n\nCan process files via direct upload (files parameter) or via URLs (file_urls parameter).\nFiles can be uploaded via batch_upload_urls endpoint first, then their URLs\nare provided here for processing.\n\nAll configuration parameters are provided as form fields.\nIf not provided, default values will be used.","operationId":"batch_process_documents_v1__knowledge_id__documents_batch_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_batch_process_documents_v1__knowledge_id__documents_batch_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDocumentsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/batch/{batch_id}/status":{"get":{"tags":["Batch upload"],"summary":"Get a batch's status","description":"Check processing status for all documents in a batch.\nReturns aggregated counts and individual document statuses.","operationId":"get_batch_status_v1__knowledge_id__batch__batch_id__status_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","description":"Batch identifier","title":"Batch Id"},"description":"Batch identifier"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/{object_id}/chunks":{"get":{"tags":["Sections"],"summary":"List a document's sections","description":"Retrieve chunks for a specific document with pagination and optional metadata.\nIncludes chunk-level metadata: chunk_keywords, chunk_topic, chunk_entities.","operationId":"get_document_chunks_with_metadata_v1__knowledge_id__documents__object_id__chunks_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"object_id","in":"path","required":true,"schema":{"type":"string","description":"Document Object ID","title":"Object Id"},"description":"Document Object ID"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Number of chunks to return","default":20,"title":"Limit"},"description":"Number of chunks to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"},{"name":"metadata","in":"query","required":false,"schema":{"type":"boolean","description":"Include chunk metadata in response","default":false,"title":"Metadata"},"description":"Include chunk metadata in response"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/chunks/{chunk_id}":{"get":{"tags":["Sections"],"summary":"Get a section","description":"Retrieve a single chunk by its ID.\nResponse includes chunk metadata.","operationId":"get_chunk_by_id_v1__knowledge_id__chunks__chunk_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"chunk_id","in":"path","required":true,"schema":{"type":"string","description":"Chunk ID","title":"Chunk Id"},"description":"Chunk ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/chunks/batch":{"post":{"tags":["Sections"],"summary":"Get many sections","description":"Retrieve multiple chunks by their IDs in batch.\nResponse includes chunk metadata.","operationId":"get_chunks_by_ids_batch_v1__knowledge_id__chunks_batch_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"description":"List of chunk IDs","title":"Chunk Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/search":{"post":{"tags":["Search"],"summary":"Search a collection","description":"Search for chunks using semantic or hybrid search.\n\nThis endpoint is an improvement on /chunks/search from knowledge_retrieval.py.","operationId":"search_knowledge_v1__knowledge_id__search_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest","description":"Search request parameters"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/{object_id}/metadata":{"get":{"tags":["Extracted fields"],"summary":"Get a document's extracted fields","description":"Return document-level metadata only (no chunks/text).\nIncludes: document_outline, document_type, entities, keywords, organizations,\nprepended_doc_summary, summary, temporal_context, title, topics, file_name","operationId":"get_document_metadata_only_v1__knowledge_id__documents__object_id__metadata_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"object_id","in":"path","required":true,"schema":{"type":"string","description":"Document Object ID","title":"Object Id"},"description":"Document Object ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/chunks/{chunk_id}/metadata":{"get":{"tags":["Sections"],"summary":"Get a section's fields","description":"Return chunk-level metadata only (no text).\nDynamically returns all chunk-level metadata fields based on field configurations.\nExcludes system fields like object_id, knowledge_id, user_id, sub_object_id, and chunk_text.","operationId":"get_chunk_metadata_only_v1__knowledge_id__chunks__chunk_id__metadata_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"chunk_id","in":"path","required":true,"schema":{"type":"string","description":"Chunk ID","title":"Chunk Id"},"description":"Chunk ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/documents/metadata/all":{"post":{"tags":["Extracted fields"],"summary":"Get every document's fields as a table (cursor pages)","description":"Key Features\n\n        Fixed schema (null for missing values)\n        Includes column metadata + total count + user selection flags\n        List[dict] fields expanded → exp_0_year, exp_1_year, …\n        Sorting capped at 10k docs (memory safety)\n        Efficient cursor-based pagination using Qdrant's next_page_offset\n\n        Column Selection with Availability Flag\n\n        All available columns are ALWAYS returned in the response\n        Each column has an is_user_selected flag indicating if it was explicitly requested\n        When columns parameter is omitted/null: all fields have is_user_selected=true\n        When columns=['field1', 'field2']: only those fields have is_user_selected=true\n        UI can use is_user_selected to determine default column visibility\n        Users can discover and add additional columns without re-fetching data\n\n        Transformation Rules\n\n        dict → flatten with _ (location.city)\n        List[str] → kept as array\n        List[dict] → expanded to indexed columns (controlled by max_nested_items, default=3)\n                     + overflow items collected in field_remaining_* columns as lists\n        Nested dicts → recursive flatten\n\n        Pagination (Cursor-Based)\n\n        Uses efficient cursor-based pagination via page_offset\n        First request: omit page_offset or set to null\n        Subsequent requests: use next_page_offset from previous response\n        Example first page: {\"limit\": 20}\n        Example next page: {\"limit\": 20, \"page_offset\": \"qdrant_offset_token\"}\n        Response includes next_page_offset (null when no more pages) and has_more flag\n\n        Filtering (examples)\n\n        {\"document_type\": \"resume\"}\n        {\"location.city\": \"Bangalore\"}\n        {\"topics\": [\"rag\", \"llm\"]} (any match)\n        {\"experience[].year\": {\"gte\": 2022}}\n        {\"year\": {\"gte\": 2020, \"lte\": 2025}}\n        {\"degree\": {\"in\": [\"M.Tech\", \"MS\"]}}\n\n        Sorting (uses Qdrant native order_by for efficiency)\n        [{\"field\": \"created_at\", \"order\": \"desc\"}]\n        [{\"field\": \"title\", \"order\": \"asc\"}, {\"field\": \"created_at\", \"order\": \"desc\"}]\n        Column Selection (optional)\n        [\"object_id\", \"title\", \"location.city\"]\n        Notes\n\n        object_id always first\n        Max page size: 100\n        Only active document-level fields\n        System fields excluded\n        All rows = same columns","operationId":"get_all_documents_metadata_flattened_endpoint_v1__knowledge_id__documents_metadata_all_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataViewRequest","description":"Request body with pagination, columns, filters, sort options, and array expansion control","examples":[{"limit":20,"max_nested_items":3},{"limit":50,"columns":["object_id","title","topics","experience"],"filters":{"document_type":"resume","location.city":"Bangalore","topics":["rag","llm"],"experience[].year":{"gte":"2022"}},"sort":[{"field":"title","order":"asc"},{"field":"created_at","order":"desc"}],"max_nested_items":5},{"limit":20,"page_offset":"qdrant_page_token_from_previous_response","max_nested_items":3}],"default":{"limit":20,"sort":[{"field":"created_at","order":"desc"}],"max_nested_items":2}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataViewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v2/{knowledge_id}/documents/metadata/all":{"post":{"tags":["Extracted fields"],"summary":"Get every document's fields as a table","description":"Simplified API with page-based pagination (1, 2, 3...) for UI table views.\n\n        **Key Features**\n        - Fixed schema tabular format (null for missing values)\n        - Simple page numbers instead of cursor tokens\n        - Column schema includes field_path, subcolumn, parent_type for UI filter builder\n        - List[dict] fields expanded → experience_0_role, experience_1_role, …\n        - Overflow items collected in experience_remaining_role columns\n\n        **Column Schema (ColumnSchemaV2)**\n        - name: flattened column key used in row data (e.g. address_city)\n        - original_field: top-level field — use in columns/sort/filters (e.g. address)\n        - field_path: filter key in dot/bracket notation (e.g. address.city, experience[].role)\n        - subcolumn: leaf key for nested fields (e.g. city, role); null for scalar/List[str]\n        - parent_type: scalar | list_str | dict | list_dict\n        - is_user_selected: true if field was in columns request or columns was omitted\n\n        **Pagination**\n        - 1-indexed (page=1 is first page)\n        - has_more = current_page < total_pages\n\n        **Filter Syntax** — {\"field\": {\"op\": \"<op>\", \"value\": <val>}}\n        - eq: exact match — {\"document_type\": {\"op\": \"eq\", \"value\": \"Resume\"}}\n        - ne: not equal — {\"document_type\": {\"op\": \"ne\", \"value\": \"Resume\"}}\n        - contains: substring match — {\"summary\": {\"op\": \"contains\", \"value\": \"Python\"}}\n        - not_contains: does not contain — {\"summary\": {\"op\": \"not_contains\", \"value\": \"Java\"}}\n        - is_empty: null or empty field — {\"phone\": {\"op\": \"is_empty\"}}\n        - is_not_empty: non-null, non-empty — {\"phone\": {\"op\": \"is_not_empty\"}}\n        - gte / lte / gt / lt: range — {\"education[].year\": {\"op\": \"gte\", \"value\": \"2018\"}}\n        - in: match any in list — {\"current_role\": {\"op\": \"in\", \"value\": [\"Dev\", \"Analyst\"]}}\n        - Nested dict field: use dot notation key — {\"address.city\": {\"op\": \"eq\", \"value\": \"Kochi\"}}\n        - Array of dicts: use bracket notation key — {\"experience[].company\": {\"op\": \"eq\", \"value\": \"KeralaSoft\"}}\n\n        **Sorting**\n        - Default: created_at desc\n        - Single field: Qdrant native order_by (efficient)\n        - Multi-field: in-memory sort, capped at 10,000 docs","operationId":"get_all_documents_metadata_v2_endpoint_v2__knowledge_id__documents_metadata_all_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataViewRequestV2","description":"Request body with page number, page size, columns, filters, sort options, and array expansion control","default":{"page":1,"page_size":20,"sort":[{"field":"created_at","order":"desc"}],"max_nested_items":2}},"examples":{"basic_pagination":{"summary":"Basic pagination","value":{"page":1,"page_size":5}},"filter_eq_ne":{"summary":"op: eq / ne","value":{"page":1,"page_size":5,"filters":{"document_type":{"op":"eq","value":"Resume"}}}},"filter_contains":{"summary":"op: contains / not_contains","value":{"page":1,"page_size":5,"filters":{"summary":{"op":"contains","value":"Python"}}}},"filter_is_empty":{"summary":"op: is_empty / is_not_empty","value":{"page":1,"page_size":5,"filters":{"phone":{"op":"is_not_empty"}}}},"filter_in":{"summary":"op: in","value":{"page":1,"page_size":5,"filters":{"current_role":{"op":"in","value":["Senior Python Developer","Data Scientist"]}}}},"filter_range":{"summary":"op: gte / lte (range)","value":{"page":1,"page_size":5,"filters":{"education[].year":{"op":"gte","value":"2018"}}}},"combined_filters_sort":{"summary":"Combined op filters + sort","value":{"page":1,"page_size":10,"columns":["object_id","current_role","address","skills","experience"],"filters":{"document_type":{"op":"eq","value":"Resume"},"address.city":{"op":"eq","value":"Kochi"},"phone":{"op":"is_not_empty"},"experience[].company":{"op":"contains","value":"Kerala"}},"sort":[{"field":"current_role","order":"asc"}],"max_nested_items":2}}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataViewResponseV2"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/enrichment":{"get":{"tags":["Extracted fields"],"summary":"Get the field definitions","description":"Get enrichment configuration v2 with metadata (unique values) per field.\n\nWhen field_name is provided, returns possible values for that specific metadata field with optional filtering.\nWhen field_name is not provided, returns all field configurations (backward compatible behavior).","operationId":"get_enrichment_v1__knowledge_id__enrichment_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"include_metadata","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to include metadata in the response","default":false,"title":"Include Metadata"},"description":"Whether to include metadata in the response"},{"name":"field_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Return values only for this specific field.","title":"Field Name"},"description":"Return values only for this specific field."},{"name":"filters","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-encoded dict for filtering documents (e.g., '{\"document_type\": \"case_study\"}').","title":"Filters"},"description":"JSON-encoded dict for filtering documents (e.g., '{\"document_type\": \"case_study\"}')."},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Limit number of results.","title":"Limit"},"description":"Limit number of results."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/config":{"get":{"tags":["Collections"],"summary":"Get a collection's configuration","operationId":"get_knowledge_configuration_v2_v1__knowledge_id__config_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetKnowledgeConfigResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/chat":{"post":{"tags":["Chat"],"summary":"Ask a question","description":"Chat over a knowledge base's indexed documents.\n\nRuns chat/graph.py's query_refiner -> rag graph. Persists the turn to\nknowledge_chat_sessions/knowledge_chat_logs (session ownership: this\nservice, per the plan's \"Who calls this endpoint\" §3, Option (a)).\nStreams via SSE when request.stream is true (default); returns a single\nJSON ChatResponse otherwise. 404s if knowledge_chat_config.chat_enabled\nis explicitly false for this knowledge_id.","operationId":"chat_v1__knowledge_id__chat_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest","description":"Chat request parameters"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/sessions":{"get":{"tags":["Chat"],"summary":"List conversations","description":"List a knowledge base's chat sessions, most recently active first.\n\nPowers two screens. The Conversations rail (the owner's own threads): search,\ndate-range filter, per-session exchange counts. And Share -> Activity, which asks\nthe opposite question — what other people did with a shared collection — via\n``source``/``exclude_user_id``.\n\nEvery filter and the sort are applied in SQL, so one tab is one query:\n``total_count`` is that tab's real total and a page is a page of the filtered\nresult. (Before this, a caller had to split and re-count a page in the browser,\nwhich meant a page of 20 could render 3 rows and the counts described the page\nrather than the collection.)","operationId":"list_chat_sessions_v1__knowledge_id__sessions_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO 8601. Filter to sessions created on/after this time.","title":"From"},"description":"ISO 8601. Filter to sessions created on/after this time."},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO 8601. Filter to sessions created on/before this time.","title":"To"},"description":"ISO 8601. Filter to sessions created on/before this time."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Case-insensitive substring match against session_title and every turn's query/response text.","title":"Q"},"description":"Case-insensitive substring match against session_title and every turn's query/response text."},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to sessions started by this user.","title":"User Id"},"description":"Filter to sessions started by this user."},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by origin: \"widget\", \"dashboard\", \"api\", or \"shared\" (a dashboard conversation held by somebody other than this collection's current owner). A session recorded before migration 044 has no origin and matches none of these; it still appears when the filter is omitted.","title":"Source"},"description":"Filter by origin: \"widget\", \"dashboard\", \"api\", or \"shared\" (a dashboard conversation held by somebody other than this collection's current owner). A session recorded before migration 044 has no origin and matches none of these; it still appears when the filter is omitted."},{"name":"exclude_user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Drop this person's own conversations. Matched case-insensitively against both user_id and user_email, so either an account id or an email works.","title":"Exclude User Id"},"description":"Drop this person's own conversations. Matched case-insensitively against both user_id and user_email, so either an account id or an email works."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Sort key: \"last_activity\" (default), \"questions\", \"title\", \"user\". An unrecognised value falls back to the default.","title":"Sort"},"description":"Sort key: \"last_activity\" (default), \"questions\", \"title\", \"user\". An unrecognised value falls back to the default."},{"name":"order","in":"query","required":false,"schema":{"type":"string","description":"\"asc\" or \"desc\" (default).","default":"desc","title":"Order"},"description":"\"asc\" or \"desc\" (default)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/v1/{knowledge_id}/sessions/{session_id}":{"get":{"tags":["Chat"],"summary":"Get a conversation","description":"Reopen one session's full transcript, oldest turn first, numbered.\n\n404s for an unknown session_id, a session_id belonging to a different\nknowledge_id, or a soft-deleted session — all three are \"not found\" from\nthe caller's side, and get_session_transcript already can't tell them\napart from a genuine miss without leaking which knowledge_id a foreign\nsession_id belongs to.\n\nshow_sources=False strips relevant_sources/summaries/detailed_chunks from\nevery assistant message here, same as the live /chat response — the DB\nrow (get_session_transcript) always returns the full stored evidence;\nthis endpoint is where that policy is applied for reads, mirroring\n_build_response_payload's client-facing strip.","operationId":"get_chat_session_v1__knowledge_id__sessions__session_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"knowledge_id","in":"path","required":true,"schema":{"type":"string","title":"Knowledge Id"}},{"name":"session_id","in":"path","required":true,"schema":{"type":"string","description":"Session ID","title":"Session Id"},"description":"Session ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"x-credential":"Document Intelligence API key (x-api-key)"}},"/health":{"get":{"summary":"Health check","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"tags":["Service"],"x-credential":"None"}}},"components":{"schemas":{"BatchDocumentStatus":{"properties":{"object_id":{"type":"string","title":"Object Id","description":"Object identifier for the document"},"file_name":{"type":"string","title":"File Name","description":"File name of the document"},"status":{"type":"string","title":"Status","description":"Processing status of the document"},"processing_duration_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Processing Duration Ms","description":"Processing duration in milliseconds (completed_at - created_at)"},"error_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Detail","description":"Error detail if status is 'failed'"}},"type":"object","required":["object_id","file_name","status"],"title":"BatchDocumentStatus","description":"Status model for a single document in batch processing."},"BatchDocumentsResponse":{"properties":{"batch_id":{"type":"string","title":"Batch Id","description":"Unique batch identifier"},"status":{"type":"string","title":"Status","description":"Batch status: 'processing' if any document is being processed, 'failed' if all failed"},"message":{"type":"string","title":"Message","description":"Status message"},"documents":{"items":{"$ref":"#/components/schemas/BatchDocumentStatus"},"type":"array","title":"Documents","description":"List of documents with their status"}},"type":"object","required":["batch_id","status","message","documents"],"title":"BatchDocumentsResponse","description":"Response model for batch document processing."},"BatchStatusResponse":{"properties":{"batch_id":{"type":"string","title":"Batch Id","description":"Unique batch identifier"},"total":{"type":"integer","title":"Total","description":"Total number of documents in the batch"},"completed":{"type":"integer","title":"Completed","description":"Number of completed documents"},"processing":{"type":"integer","title":"Processing","description":"Number of documents currently processing"},"failed":{"type":"integer","title":"Failed","description":"Number of failed documents"},"documents":{"items":{"$ref":"#/components/schemas/BatchDocumentStatus"},"type":"array","title":"Documents","description":"List of documents with their status"},"elapsed_since_created_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Elapsed Since Created Ms","description":"Milliseconds elapsed from batch creation to now"}},"type":"object","required":["batch_id","total","completed","processing","failed","documents"],"title":"BatchStatusResponse","description":"Response model for batch status tracking."},"BatchUploadFileRequest":{"properties":{"file_name":{"type":"string","title":"File Name","description":"Name of the file"},"content_type":{"type":"string","title":"Content Type","description":"MIME type of the file"}},"type":"object","required":["file_name","content_type"],"title":"BatchUploadFileRequest","description":"Request model for a single file in batch upload."},"BatchUploadFileResponse":{"properties":{"object_id":{"type":"string","title":"Object Id","description":"Unique object identifier for the file"},"file_name":{"type":"string","title":"File Name","description":"Name of the file"},"presigned_url":{"type":"string","title":"Presigned Url","description":"Presigned URL for uploading the file"},"download_presigned_url":{"type":"string","title":"Download Presigned Url","description":"Presigned URL for downloading the file"}},"type":"object","required":["object_id","file_name","presigned_url","download_presigned_url"],"title":"BatchUploadFileResponse","description":"Response model for a single file upload URL."},"BatchUploadUrlsRequest":{"properties":{"files":{"items":{"$ref":"#/components/schemas/BatchUploadFileRequest"},"type":"array","title":"Files","description":"List of files to generate upload URLs for (1-50 items)"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id","description":"User identifier (optional)"}},"type":"object","required":["files"],"title":"BatchUploadUrlsRequest","description":"Request model for batch upload URLs generation."},"BatchUploadUrlsResponse":{"properties":{"uploads":{"items":{"$ref":"#/components/schemas/BatchUploadFileResponse"},"type":"array","title":"Uploads","description":"List of upload URLs for each file"}},"type":"object","required":["uploads"],"title":"BatchUploadUrlsResponse","description":"Response model for batch upload URLs generation."},"Body_add_document_v1__knowledge_id__documents_post":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"file":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"File"},"file_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Url"},"weblink":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Weblink"},"use_llama_parse":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Use Llama Parse"},"document_processing_mode":{"anyOf":[{"$ref":"#/components/schemas/DocumentProcessingMode"},{"type":"null"}],"description":"What the document's content is like: auto (default — reads locally and detects), text_based, scanned, layout_aware, visual, or mixed. Ignored for plain text content, which has no scanned/layout/visual dimension. For a weblink it applies two ways: a URL that resolves to a file (PDF/DOCX/plain text) picks LlamaParse settings, exactly like an uploaded file; a URL that resolves to an HTML page picks the scraper (auto/text_based/scanned -> Newspaper, layout_aware/visual/mixed -> FireCrawl with boilerplate-stripping off) — see fs-agent-workers/docs/plan/document-processing/archive/design-weblink-modes.md for the full table. Omit to inherit the legacy use_llama_parse behaviour."},"transcript_provider":{"$ref":"#/components/schemas/TranscribeUsing","default":"openai"},"scrape_using":{"$ref":"#/components/schemas/ScrapeUsing","description":"Deprecated, no effect. The scraper is now chosen from document_processing_mode.","default":"FireCrawl"},"scraping_method":{"$ref":"#/components/schemas/ScrapingMethod","default":"scrape"},"max_depth":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Depth","default":1},"chunk_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Chunk Size","default":2000},"enable_chunking":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enable Chunking","default":true},"extra_metadata":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Extra Metadata","description":"Optional JSON string of arbitrary key-value metadata"}},"type":"object","title":"Body_add_document_v1__knowledge_id__documents_post"},"Body_batch_process_documents_v1__knowledge_id__documents_batch_post":{"properties":{"files":{"anyOf":[{"items":{"type":"string","format":"binary"},"type":"array"},{"type":"null"}],"title":"Files","description":"Optional collection of files to upload and process"},"file_urls":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Urls","description":"Comma-separated file URLs to process"},"enable_chunking":{"type":"boolean","title":"Enable Chunking","description":"Enable chunking (default: true)","default":true},"use_llama_parse":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Use Llama Parse","description":"Deprecated — use document_processing_mode. Defaults to None so 'not sent' stays distinguishable from an explicit false."},"document_processing_mode":{"anyOf":[{"$ref":"#/components/schemas/DocumentProcessingMode"},{"type":"null"}],"description":"What the documents' content is like: auto (default — reads locally and detects), text_based, scanned, layout_aware, visual, or mixed. Applies to every file in the batch."},"chunk_size":{"type":"integer","title":"Chunk Size","description":"Chunk size for processing (default: 2000)","default":2000},"transcript_provider":{"$ref":"#/components/schemas/TranscribeUsing","description":"Transcript provider: 'openai' or 'groq' (default: 'openai')","default":"openai"}},"type":"object","title":"Body_batch_process_documents_v1__knowledge_id__documents_batch_post"},"Body_get_upload_url_v1__knowledge_id__upload_url_post":{"properties":{"file_name":{"type":"string","title":"File Name"},"content_type":{"type":"string","title":"Content Type"}},"type":"object","required":["file_name","content_type"],"title":"Body_get_upload_url_v1__knowledge_id__upload_url_post"},"ChatMessage":{"properties":{"n":{"type":"integer","title":"N","description":"1-indexed position of the exchange this message belongs to."},"chat_id":{"type":"string","title":"Chat Id"},"role":{"type":"string","title":"Role","description":"\"user\" or \"assistant\""},"message":{"type":"string","title":"Message"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"is_answered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Answered"},"refined_query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refined Query"},"llm_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Provider"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"user_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Feedback","description":"\"positive\", \"negative\", or null. Set via PATCH .../messages/{chat_id}/feedback."},"data":{"additionalProperties":true,"type":"object","title":"Data","description":"assistant-only. data.knowledge.{relevant_sources,summaries,detailed_chunks} are genuinely the same fields the live /chat response returns (persisted verbatim by _persist_turn, G14) — not a relabeled stand-in. data.knowledge.knowledge_evidence is a SEPARATE, lossier shape kept for cross-turn memory only; don't treat it as a sources-panel substitute. rag_context is the one live field not persisted. See KnowledgeChatLogs' docstring."},"has_attachment":{"type":"boolean","title":"Has Attachment","default":false},"attachment_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attachment Url"}},"type":"object","required":["n","chat_id","role","message"],"title":"ChatMessage","description":"One turn split into its user/assistant halves, matching the message-list\nshape a chat transcript UI actually renders (and the shape fs-agent-chat's\nown session endpoint already uses) instead of a query+response pair.\n\nBoth halves of one exchange share `chat_id` and `n`. Fields that only\napply to one role are null on the other rather than duplicated."},"ChatRequest":{"properties":{"query":{"type":"string","title":"Query","description":"User's chat query. Already description-enriched if an image was sent to the caller — vision handling stays upstream, see the plan's Vision section."},"owner_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Id","description":"Owner of the knowledge base, for owner LLM credentials and usage attribution. Resolved from knowledge_config when omitted."},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Chat session id. Omit to start a new session (a fresh id is minted and returned)."},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id","description":"Acting user, for audit. Distinct from owner_id. Resolved from the caller's session when omitted."},"stream":{"type":"boolean","title":"Stream","description":"Stream the answer via SSE. When false, the full response is returned as one JSON object.","default":true},"has_attachment":{"type":"boolean","title":"Has Attachment","description":"Whether an image was attached to this turn upstream. The query above is already description-enriched — this is a transcript-completeness flag only.","default":false},"attachment_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attachment Url","description":"URL of the attached image, if any, for transcript/audit purposes only."},"from_widget":{"type":"boolean","title":"From Widget","description":"Set by the website chat bubble. Records the session's origin as \"widget\" even when the visitor is signed in — a credential-less caller is already detectable server-side, a signed-in one is not, so only the embed can tell us. See SessionSummary.source.","default":false},"from_full_screen":{"type":"boolean","title":"From Full Screen","description":"Set by the full-screen chat embed. For a credential-less caller, gates the request against fullscreen_is_public + fullscreen_allowed_domains instead of the widget's is_public + allowed_domains.","default":false},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"LLM provider override applied to every node. Falls through to knowledge_chat_config / env / hardcoded default when omitted. Prefer node_configs when nodes differ."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"LLM model override applied to every node, e.g. 'gpt-5.4-mini'."},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Temperature override applied to every node. Accepted but not yet applied downstream (see NodeConfig.temperature)."},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Max output tokens override. Only meaningful for the generate_answer node; see NodeConfig.max_tokens."},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt","description":"System prompt suffix applied to the RAG answer. Equivalent to node_configs.rag_agent.prompt; node_configs wins if both are sent."},"node_configs":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/NodeConfig"},"type":"object"},{"type":"null"}],"title":"Node Configs","description":"Per-node LLM config, keyed by node name. Accepted keys: 'rag_agent' (the retrieval ReAct loop), 'generate_answer' (the answer writer), 'refined_query_node' (the query rewriter). Any other key is a 422 — see SUPPORTED_NODES for why the Orchestrator's 'supervisor'/'response_node' have no counterpart here. Takes precedence over the flat provider/model/temperature/system_prompt fields for the nodes it names; unnamed nodes fall back to those flat fields, then to the DB row / env / default."}},"type":"object","required":["query"],"title":"ChatRequest","description":"Request body. knowledge_id itself is a path param (matches\nrouters/search.py's SearchRequest convention), not a body field.\nowner_id is optional — if omitted, the router resolves it from the KB's\nown knowledge_config row (utils/auth/dependencies.py::resolve_kb_owner_id),\nthe same lookup routers/document_management.py already relies on.","example":{"node_configs":{"generate_answer":{"model":"gemini-2.5-flash","prompt":"Answer only from the retrieved context. Include any ClickUp URLs found.","provider":"google"},"rag_agent":{"model":"gpt-5.4-mini","prompt":"Prioritise accuracy and completeness in retrieval.","provider":"openai"},"refined_query_node":{"model":"gpt-4o-mini","provider":"openai"}},"owner_id":"owner-123","query":"What invoices do we have from March?","stream":true,"user_id":"user-456"}},"ChunkingStrategyConfig":{"properties":{"document_level_metadata":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Document Level Metadata","description":"Enable document-level metadata extraction","default":true},"chunk_level_metadata":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Chunk Level Metadata","description":"Enable chunk-level metadata extraction","default":false}},"type":"object","title":"ChunkingStrategyConfig","description":"Chunking strategy configuration for knowledge settings."},"ColumnSchema":{"properties":{"name":{"type":"string","title":"Name","description":"Column name as it appears in the row data"},"original_field":{"type":"string","title":"Original Field","description":"Original field name from metadata before flattening"},"data_type":{"type":"string","title":"Data Type","description":"Data type using Python type notation (str, int, float, bool, dict, List[str], List[dict])"},"is_user_selected":{"type":"boolean","title":"Is User Selected","description":"True if user selected this column or if no columns filter was specified. False if user specified columns but this column was not included.","default":true}},"type":"object","required":["name","original_field","data_type"],"title":"ColumnSchema","description":"Schema definition for a single column in the data view."},"ColumnSchemaV2":{"properties":{"name":{"type":"string","title":"Name","description":"Flattened column key used in row data (e.g. location_country)"},"original_field":{"type":"string","title":"Original Field","description":"Top-level field name — use in filters/sort/columns requests (e.g. location)"},"field_path":{"type":"string","title":"Field Path","description":"Dot-notation path to use as the filter key (e.g. location.country, experience[].year)"},"subcolumn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subcolumn","description":"Leaf key within nested field (e.g. country, year); null for scalar and List[str]"},"parent_type":{"type":"string","title":"Parent Type","description":"Parent field type: scalar, list_str, dict, or list_dict"},"data_type":{"type":"string","title":"Data Type","description":"Data type using Python type notation (str, int, float, bool, dict, List[str], List[dict])"},"sort_field":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sort Field","description":"Payload key to use as sort field. scalar → field name, dict → dot path (e.g. address.city), list_dict with numeric index → bracket path (e.g. experience[1].company). Null for list_str and list_dict _remaining_ columns (not sortable)."},"is_user_selected":{"type":"boolean","title":"Is User Selected","description":"True if user selected this column or if no columns filter was specified. False if user specified columns but this column was not included.","default":true}},"type":"object","required":["name","original_field","field_path","parent_type","data_type"],"title":"ColumnSchemaV2","description":"Schema definition for a single column in the V2 data view (includes filter path metadata)."},"DataViewRequest":{"properties":{"limit":{"type":"integer","maximum":100,"minimum":1,"title":"Limit","description":"Maximum number of documents to return (1-100)","default":20},"page_offset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Offset","description":"Qdrant page offset token for efficient pagination. Use next_page_offset from previous response. Omit for the first page."},"columns":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Columns","description":"Optional list of top-level field names to include. If not provided, all active fields are included.","examples":[["object_id","title","location","topics"]]},"filters":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"items":{},"type":"array"},{"additionalProperties":true,"type":"object"}]},"type":"object"},{"type":"null"}],"title":"Filters","description":"Optional filter conditions. Supports scalar, nested, list, array-of-dicts, range, and in operators.","examples":[{"document_type":"resume","experience[].year":{"gte":"2022"},"location.city":"Bangalore","topics":["rag","llm"]}]},"sort":{"anyOf":[{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array"},{"type":"null"}],"title":"Sort","description":"Optional sort configuration. List of field/order pairs. Defaults to created_at descending.","default":[{"field":"created_at","order":"desc"}],"examples":[[{"field":"title","order":"asc"},{"field":"created_at","order":"desc"}]]},"max_nested_items":{"type":"integer","maximum":5,"minimum":0,"title":"Max Nested Items","description":"Maximum number of items to expand for List[dict] fields into field_0_*, field_1_* columns. Overflow collected into field_remaining_* columns. Set to 0 to disable.","default":2}},"type":"object","title":"DataViewRequest","description":"Request model for data view tabular endpoint with cursor-based pagination."},"DataViewRequestV2":{"properties":{"page":{"type":"integer","minimum":1,"title":"Page","description":"1-indexed page number (first page is 1)","default":1},"page_size":{"type":"integer","maximum":100,"minimum":1,"title":"Page Size","description":"Items per page (1-100)","default":20},"columns":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Columns","description":"Optional list of top-level field names to include. If not provided, all active fields are included.","examples":[["object_id","title","location","topics"]]},"filters":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"items":{},"type":"array"},{"additionalProperties":true,"type":"object"}]},"type":"object"},{"type":"null"}],"title":"Filters","description":"Optional filter conditions for document metadata.","examples":[{"document_type":"resume","experience[].year":{"gte":"2022"},"location.city":"Bangalore","topics":["rag","llm"]}]},"sort":{"anyOf":[{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array"},{"type":"null"}],"title":"Sort","description":"Optional sort configuration. Defaults to created_at descending.","default":[{"field":"created_at","order":"desc"}],"examples":[[{"field":"title","order":"asc"},{"field":"created_at","order":"desc"}]]},"max_nested_items":{"type":"integer","maximum":5,"minimum":0,"title":"Max Nested Items","description":"Maximum number of items to expand into individual columns for List[dict] fields. Set to 0 to disable.","default":2}},"type":"object","title":"DataViewRequestV2","description":"Request model for data view tabular endpoint with page-based pagination (v2 API)."},"DataViewResponse":{"properties":{"columns":{"items":{"$ref":"#/components/schemas/ColumnSchema"},"type":"array","title":"Columns","description":"Fixed schema definition for all columns in the data view."},"rows":{"items":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"items":{},"type":"array"},{"type":"null"}]},"type":"object"},"type":"array","title":"Rows","description":"Data rows conforming to the column schema. Every row contains all columns, null for missing values."},"total_count":{"type":"integer","title":"Total Count","description":"Total number of documents matching the filter criteria (before pagination)"},"current_count":{"type":"integer","title":"Current Count","description":"Number of documents returned in the current response"},"next_page_offset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Page Offset","description":"Qdrant page offset token for fetching the next page. None if no more pages available."},"has_more":{"type":"boolean","title":"Has More","description":"True if more documents are available beyond this page"},"extraction_context":{"additionalProperties":{"$ref":"#/components/schemas/DocumentExtractionContext"},"type":"object","title":"Extraction Context","description":"Per returned object ID, latest successful field-name context. Unknown is not an attempted-empty result; definitions/types are not recorded."}},"type":"object","required":["columns","rows","total_count","current_count","has_more"],"title":"DataViewResponse","description":"Response model for data view tabular endpoint with fixed schema."},"DataViewResponseV2":{"properties":{"columns":{"items":{"$ref":"#/components/schemas/ColumnSchemaV2"},"type":"array","title":"Columns","description":"Schema definitions for each column in the data view"},"rows":{"items":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"integer"},{"type":"number"},{"type":"boolean"},{"items":{},"type":"array"},{"type":"null"}]},"type":"object"},"type":"array","title":"Rows","description":"Data rows conforming to the column schema. Every row contains all columns, null for missing values."},"total_count":{"type":"integer","title":"Total Count","description":"Total number of documents matching the filter criteria (before pagination)"},"current_count":{"type":"integer","title":"Current Count","description":"Number of documents returned in the current page"},"current_page":{"type":"integer","title":"Current Page","description":"Current page number (1-indexed)"},"total_pages":{"type":"integer","title":"Total Pages","description":"Total number of pages available based on page_size and total_count"},"extraction_context":{"additionalProperties":{"$ref":"#/components/schemas/DocumentExtractionContext"},"type":"object","title":"Extraction Context","description":"Per returned object ID, latest successful field-name context. Unknown is not an attempted-empty result; definitions/types are not recorded."}},"type":"object","required":["columns","rows","total_count","current_count","current_page","total_pages"],"title":"DataViewResponseV2","description":"Response model for data view tabular endpoint with page-based pagination (v2 API)."},"DocumentExtractionContext":{"properties":{"status":{"type":"string","enum":["recorded","unknown"],"title":"Status","default":"unknown"},"event_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Key"},"processed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Processed At"},"processed_fields":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Processed Fields"},"definition_history":{"type":"string","const":"unknown","title":"Definition History","default":"unknown"}},"type":"object","title":"DocumentExtractionContext","description":"Field-name evidence from the latest successful attempt, never a schema version."},"DocumentProcessingMode":{"type":"string","enum":["auto","text_based","scanned","layout_aware","visual","mixed"],"title":"DocumentProcessingMode","description":"What a document's content is like — the caller's answer, not a parser name.\n\nThe point of this enum is that it asks a question the person uploading the file can\nactually answer. \"Is this a scan?\" is answerable by anyone; \"should this use OCR with\nhigh-resolution preprocessing?\" is not. Choosing the machinery is our job, and it\nhappens in the worker (fs-agent-workers `celery_utils/processing/processing_modes.py`),\nwhich is the only place that knows which parser serves which kind of content.\n\nSent to the worker as a plain string over SQS, so these *values* are the cross-service\ncontract — renaming one is a breaking change even though it looks local."},"DocumentSummariesResponse":{"properties":{"summaries":{"additionalProperties":{"$ref":"#/components/schemas/SummaryItem"},"type":"object","title":"Summaries"}},"type":"object","required":["summaries"],"title":"DocumentSummariesResponse"},"EmbeddingModel":{"type":"string","enum":["paraphrase-multilingual-mpnet-base-v2","openai-text-embedding-3-large","openai-text-embedding-3-small"],"title":"EmbeddingModel"},"GetDocumentSummariesRequest":{"properties":{"object_ids":{"items":{"type":"string"},"type":"array","title":"Object Ids"}},"type":"object","required":["object_ids"],"title":"GetDocumentSummariesRequest"},"GetKnowledgeConfigResponse":{"properties":{"knowledge_id":{"type":"string","title":"Knowledge Id"},"embedding_model":{"anyOf":[{"$ref":"#/components/schemas/EmbeddingModel"},{"type":"null"}]},"hybrid_search_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Hybrid Search Enabled"},"chunking_strategy":{"anyOf":[{"$ref":"#/components/schemas/ChunkingStrategyConfig"},{"type":"null"}]},"collection_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Collection Name","description":"Short display name (G1) — distinct from service_description, the longer free-text description. Null if never set."},"service_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Description"},"enrichment_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Provider"},"enrichment_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Model"},"enrichment_temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Enrichment Temperature"},"enrichment_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Prompt"},"enrichment_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Source"},"enrichment_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enrichment Enabled","default":true},"use_deterministic_chunking":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Use Deterministic Chunking","default":true},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["knowledge_id"],"title":"GetKnowledgeConfigResponse","description":"Response model for GET /get-knowledge-config endpoint.","example":{"chunking_strategy":{"chunk_level_metadata":false,"document_level_metadata":true},"created_at":"2025-09-30T17:55:00Z","embedding_model":"paraphrase-multilingual-mpnet-base-v2","enrichment_model":"gpt-4.1-mini","enrichment_prompt":"Extract metadata deterministically. Use only information explicitly present in the document. Do not infer missing facts. Return stable, normalized values that follow the field definitions exactly.","enrichment_provider":"openai","enrichment_temperature":0,"hybrid_search_enabled":true,"knowledge_id":"123e4567-e89b-12d3-a456-426614174000","service_description":"Knowledge base for customer support documents","updated_at":"2025-09-30T17:55:00Z"}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"NodeConfig":{"properties":{"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"LLM provider, e.g. 'openai', 'anthropic', 'google', 'groq'."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"LLM model id, e.g. 'gpt-5.4-mini'."},"temperature":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Temperature","description":"Sampling temperature. Accepted but NOT yet applied — every get_llm call site in the RAG chain still passes temperature=0. Kept in the schema so callers can send their stored value without it being rejected, and so wiring it later is not a breaking change."},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Max output tokens. Only meaningful for 'generate_answer' — the node that actually writes the final response; threaded into its get_llm call."},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt","description":"Suffix prompt for this node, appended to the node's own base prompt. NOT a full system-prompt replacement."}},"type":"object","title":"NodeConfig","description":"Per-node LLM config for ONE of this service's LLM roles.\n\nMirrors one ``node_configs`` row in the Orchestrator's agent registry\n(fs-agent-chat/agent_registry/pydantic_model_db.py::NodeConfig), minus\nthe fields this service has no use for — see ChatRequest.node_configs\nfor which node names are accepted and why the rest are dropped.\n\nEvery field is optional: a caller may pin the model but leave the prompt\nto fall through to the DB row / env / hardcoded default, and vice versa.\nAn empty object is legal and simply changes nothing for that node."},"ScrapeUsing":{"type":"string","enum":["Newspaper","FireCrawl"],"title":"ScrapeUsing"},"ScrapingMethod":{"type":"string","enum":["scrape","crawl"],"title":"ScrapingMethod"},"SearchRequest":{"properties":{"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query","description":"Search query text"},"num_chunks":{"type":"integer","maximum":100,"minimum":1,"title":"Num Chunks","description":"Number of chunks to return","default":3},"object_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Object Ids","description":"Hard document scope. Omit or use null for the whole knowledge base; [] returns no chunks. Metadata filters are not supported by this endpoint."},"mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mode","description":"Search mode: 'hybrid' or 'non_hybrid'","default":"hybrid"}},"additionalProperties":false,"type":"object","title":"SearchRequest","description":"Request model for search endpoint"},"SessionDetailResponse":{"properties":{"session_id":{"type":"string","title":"Session Id"},"knowledge_id":{"type":"string","title":"Knowledge Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email"},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"exchange_count":{"type":"integer","title":"Exchange Count"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages"}},"type":"object","required":["session_id","knowledge_id","exchange_count","messages"],"title":"SessionDetailResponse"},"SessionListResponse":{"properties":{"sessions":{"items":{"$ref":"#/components/schemas/SessionSummary"},"type":"array","title":"Sessions"},"total_count":{"type":"integer","title":"Total Count"},"current_page":{"type":"integer","title":"Current Page"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["sessions","total_count","current_page","total_pages"],"title":"SessionListResponse"},"SessionSummary":{"properties":{"session_id":{"type":"string","title":"Session Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"session_title if ever set, else the session's first query, truncated to 120 chars."},"exchange_count":{"type":"integer","title":"Exchange Count"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"user_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Email","description":"The caller's address, captured from their session when the conversation started (migration 044). Null for a public/widget visitor, and for any session recorded before that migration — this service cannot resolve an account id to an address after the fact."},"user_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Name","description":"Display name from the same session, when the identity provider supplied one. Null otherwise — fall back to user_email, not to the id."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Where the conversation came from: \"widget\" (website bubble or full-screen embed), \"dashboard\" (signed in at a screen), or \"api\" (master-key integration). Null for sessions recorded before migration 044. Owner-vs-invited is NOT encoded here — use ?source=shared, which derives it from the collection's current owner."},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At","description":"The most recent turn's timestamp. Null only for a session with no turns yet."}},"type":"object","required":["session_id","exchange_count"],"title":"SessionSummary"},"SummaryItem":{"properties":{"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"filename":{"type":"string","title":"Filename"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["filename"],"title":"SummaryItem"},"TranscribeUsing":{"type":"string","enum":["openai","groq"],"title":"TranscribeUsing"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"x-api-key"}}},"security":[{"APIKeyHeader":[]}]}