Search API
Endpoints for text search, compound similarity search, summary search, and hierarchical cross-collection search.
The search API provides four search modes, each targeting a different collection and use case. All search endpoints are POST requests that accept a JSON body and return results scoped to the user's workspace and permissions.
Text Search
POST /search/pages
Content-Type: application/jsonSearches the page_embeddings collection for text chunks matching the query. Uses dense vector retrieval (hybrid dense + sparse when SPARSE_ENCODING_ENABLED=true) followed by cross-encoder reranking (RERANKER_ENABLED, on by default).
{
"query_text": "NadD inhibitors with IC50 below 10uM",
"limit": 10,
"score_threshold": 0.5,
"artifact_id": null,
"tags": ["NadD"],
"tag_match_mode": "any",
"entity_types": ["target"]
}| Field | Type | Required | Description |
|---|---|---|---|
query_text | string | Yes | Search query |
limit | integer | No | Max results (default 10) |
score_threshold | float | No | Minimum similarity score |
artifact_id | UUID | No | Restrict to a specific document |
tags | string[] | No | Filter by NER tags |
tag_match_mode | string | No | any (default) or all |
entity_types | string[] | No | Filter by entity type (compound_name, target, gene_name, etc.) |
block_types | string[] | No | Filter by block type (table, figure, heading, paragraph) |
section | string | No | Restrict to chunks under a heading whose text matches (case-insensitive) |
is_table / is_figure | boolean | No | Restrict to (or exclude) table or figure chunks |
Response:
{
"query": "NadD inhibitors with IC50 below 10uM",
"results": [
{
"page_id": "...",
"artifact_id": "...",
"page_index": 7,
"similarity_score": 0.87,
"rerank_score": 0.92,
"original_rank": 3,
"text_preview": "The IC50 of SACC-111 was 2.3 uM...",
"artifact_name": "paper.pdf",
"artifact_details": {"title": "...", "tags": ["NadD", "SACC-111"], "...": "..."}
}
],
"total_results": 1,
"model_used": "...",
"rerank_info": {"reranker_model": "cross-encoder/ms-marco-MiniLM-L-12-v2", "candidates_before": 30, "results_after": 10, "top_promotion": 2}
}Compound Similarity Search
POST /search/compounds
Content-Type: application/jsonSearches the compound_embeddings collection for structurally similar compounds using ChemBERTa embeddings. The query SMILES is validated, canonicalized, and embedded before search.
{
"query_smiles": "CC(=O)Oc1ccccc1C(=O)O",
"limit": 10,
"score_threshold": 0.8
}| Field | Type | Required | Description |
|---|---|---|---|
query_smiles | string | Yes | SMILES string to search |
limit | integer | No | Max results (default 10) |
score_threshold | float | No | Minimum similarity score |
artifact_id | UUID | No | Restrict to a specific document |
Response includes query_smiles, query_canonical_smiles, total_results, model_used, and results, each with smiles, canonical_smiles, extracted_id, similarity_score, page_id, page_index, artifact_id, and artifact_name.
Summary Search
POST /search/summaries
Content-Type: application/jsonSearches the unified summary_embeddings collection containing both page-level and artifact-level summaries. Useful for broad thematic queries.
{
"query_text": "NadD enzyme inhibition mechanisms",
"limit": 10,
"entity_type": "artifact",
"artifact_id": null
}| Field | Type | Required | Description |
|---|---|---|---|
query_text | string | Yes | Search query |
limit | integer | No | Max results (default 10) |
entity_type | string | No | Filter by page or artifact summaries |
artifact_id | UUID | No | Restrict to a specific document |
score_threshold | float | No | Minimum similarity score |
tags | string[] | No | Filter by NER tags |
entity_types_filter | string[] | No | Filter by entity type (compound_name, target, etc.) |
tag_match_mode | string | No | any (default) or all |
Hierarchical Search
POST /search/hierarchical
Content-Type: application/jsonQueries both the text chunk collection and the summary collection in parallel, then returns grouped results. This is the most comprehensive search mode, combining fine-grained passage retrieval with broad document-level matching.
{
"query_text": "NadD with compound SACC-111 by TAMU",
"limit": 10,
"include_chunks": true,
"tags": [],
"tag_match_mode": "any"
}| Field | Type | Required | Description |
|---|---|---|---|
query_text | string | Yes | Search query |
limit | integer | No | Max results per collection |
include_chunks | boolean | No | Include chunk results (default true). Set false for faster summary-only search. |
tags | string[] | No | Filter by NER tags |
tag_match_mode | string | No | any or all |
Response:
{
"query": "NadD with compound SACC-111 by TAMU",
"summary_hits": [
{
"entity_id": "...",
"entity_type": "artifact",
"artifact_id": "...",
"summary_text": "This paper presents...",
"artifact_title": "...",
"score": 0.91
}
],
"chunk_hits": [
{
"page_id": "...",
"artifact_id": "...",
"page_index": 4,
"text_preview": "The IC50 was...",
"score": 0.85,
"rerank_score": 0.88
}
],
"total_summary_hits": 1,
"total_chunk_hits": 1,
"model_used": "..."
}Results from both collections are ranked independently. The frontend can present them as expandable cards with document-level matches at the top and passage-level matches nested beneath.
Generate Embedding (Manual)
POST /search/pages/{page_id}/generate-embedding?force_regenerate=falseManually triggers embedding generation for a specific page. Useful for testing the pipeline, regenerating after model changes, or recovering from failures.
Returns 202 Accepted.
Health Check
GET /search/healthChecks the health of all search infrastructure: text embedding model, compound embedding model, and all three Qdrant collections.
{
"status": "healthy",
"text_embedding_model": {"model_name": "ibm-granite/granite-embedding-english-r2", "dimensions": 768, "provider": "sentence-transformers", "device": "cpu"},
"text_vector_store": {"collection_name": "page_embeddings", "points_count": 1234, "vector_size": 768},
"smiles_embedding_model": {"model_name": "DeepChem/ChemBERTa-77M-MTR", "dimensions": 384, "provider": "transformers/chemberta", "device": "cpu"},
"compound_vector_store": {"collection_name": "compound_embeddings", "points_count": 56, "vector_size": 384},
"summary_vector_store": {"collection_name": "summary_embeddings", "points_count": 89, "vector_size": 768}
}