DocuStore.io
API Reference

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.

POST /search/pages
Content-Type: application/json

Searches 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"]
}
FieldTypeRequiredDescription
query_textstringYesSearch query
limitintegerNoMax results (default 10)
score_thresholdfloatNoMinimum similarity score
artifact_idUUIDNoRestrict to a specific document
tagsstring[]NoFilter by NER tags
tag_match_modestringNoany (default) or all
entity_typesstring[]NoFilter by entity type (compound_name, target, gene_name, etc.)
block_typesstring[]NoFilter by block type (table, figure, heading, paragraph)
sectionstringNoRestrict to chunks under a heading whose text matches (case-insensitive)
is_table / is_figurebooleanNoRestrict 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}
}
POST /search/compounds
Content-Type: application/json

Searches 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
}
FieldTypeRequiredDescription
query_smilesstringYesSMILES string to search
limitintegerNoMax results (default 10)
score_thresholdfloatNoMinimum similarity score
artifact_idUUIDNoRestrict 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.

POST /search/summaries
Content-Type: application/json

Searches 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
}
FieldTypeRequiredDescription
query_textstringYesSearch query
limitintegerNoMax results (default 10)
entity_typestringNoFilter by page or artifact summaries
artifact_idUUIDNoRestrict to a specific document
score_thresholdfloatNoMinimum similarity score
tagsstring[]NoFilter by NER tags
entity_types_filterstring[]NoFilter by entity type (compound_name, target, etc.)
tag_match_modestringNoany (default) or all
POST /search/hierarchical
Content-Type: application/json

Queries 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"
}
FieldTypeRequiredDescription
query_textstringYesSearch query
limitintegerNoMax results per collection
include_chunksbooleanNoInclude chunk results (default true). Set false for faster summary-only search.
tagsstring[]NoFilter by NER tags
tag_match_modestringNoany 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=false

Manually 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/health

Checks 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}
}