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 hybrid retrieval (dense + sparse) with cross-encoder reranking.

{
  "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, target, etc.)

Response:

{
  "results": [
    {
      "page_id": "...",
      "artifact_id": "...",
      "chunk_text": "The IC50 of SACC-111 was 2.3 uM...",
      "score": 0.87,
      "rerank_score": 0.92,
      "page_index": 7,
      "tags": ["NadD", "SACC-111"]
    }
  ]
}
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

Response includes matched compounds with their SMILES, similarity scores, source page, and artifact references.

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
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:

{
  "summary_hits": [
    {
      "entity_id": "...",
      "entity_type": "artifact",
      "summary_text": "This paper presents...",
      "score": 0.91
    }
  ],
  "chunk_hits": [
    {
      "page_id": "...",
      "artifact_id": "...",
      "chunk_text": "The IC50 was...",
      "score": 0.85
    }
  ]
}

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": "nomic-ai/nomic-embed-text-v1.5", "dimensions": 768},
  "text_vector_store": {"collection": "page_embeddings", "points_count": 1234},
  "smiles_embedding_model": {"model": "DeepChem/ChemBERTa-77M-MTR"},
  "compound_vector_store": {"collection": "compound_embeddings", "points_count": 56},
  "summary_vector_store": {"collection": "summary_embeddings", "points_count": 89}
}