Skip to main content
Memic’s search endpoint is a unified retrieval layer. You pass it a query, and Memic classifies the intent and routes it to the right backend — semantic search over your indexed documents for natural-language questions, or structured queries against connector-backed data sources for filters and lookups. You don’t maintain two different retrieval pipelines; your agent just calls client.search(...) and gets back the right answer.

The basics

results = client.search("what is our refund policy")

for hit in results.semantic:
    print(f"[{hit.score:.2f}] {hit.text[:200]}...")
    print(f"   from {hit.source.file_name}")
Or via HTTP:
curl https://api.memic.ai/api/v1/search \
  -H "X-API-Key: $MEMIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "what is our refund policy", "top_k": 5}'

How routing works

Memic classifies every query along one axis: semantic or structured.
  • Semantic queries — natural-language questions best answered from document content (“what is our refund policy”, “summarize Q3 earnings”, “how do I reset my password”). These hit the semantic index over your uploaded files.
  • Structured queries — filters, aggregations, lookups, or anything that reads more like a database query (“orders from Q3 2025 over $500”, “customers in the Enterprise tier”, “open tickets assigned to me”). These hit connectors you’ve attached to the environment (Postgres, Notion, Google Sheets, Salesforce, custom connectors).
The routing field on every response shows exactly which path was taken and why:
{
  "query": "what is our refund policy",
  "results": {
    "semantic": [ ... ],
    "structured": null
  },
  "total_results": 3,
  "routing": {
    "route": "semantic",
    "reasoning": "Natural-language query over document content.",
    "connector_id": null
  }
}
For a structured query you’d see route: "structured", a non-null connector_id, and the results in results.structured instead of results.semantic.

Response shape

{
  "query": "...",
  "results": {
    "semantic": [
      {
        "text": "Customers may request a refund within 30 days...",
        "score": 0.87,
        "source": {
          "file_id": "...",
          "file_name": "policies.pdf",
          "page": 4
        }
      }
    ],
    "structured": null
  },
  "total_results": 3,
  "routing": {
    "route": "semantic",
    "reasoning": "...",
    "connector_id": null
  }
}
Both semantic and structured are present on every response — one will be populated, the other will be null. Your agent code can inspect routing.route to decide how to format the answer.

When to use which

You don’t normally pick. Memic picks for you based on the query. But if you want to influence routing, the easiest lever is phrasing:
  • Push toward semantic: use natural-language phrasing. “What does our refund policy say about digital products?”
  • Push toward structured: use explicit filters and comparisons. “Orders from 2025 where total > $500 in the eu-west region”
For the Application API’s perspective both feel identical — same endpoint, same response shape, same auth.

Tuning top_k

top_k controls how many results come back. Defaults:
  • Default: 5
  • For RAG prompts feeding an LLM: 510
  • For search UIs with a ranked list: 2050
Higher values cost more latency because more vectors are compared and more passage text is returned over the wire.

Filtering

Scope searches to specific folders or file types via the filters field:
results = client.search(
    query="refund policy",
    filters={"folder": "legal", "file_types": ["pdf"]}
)
Filters apply to the semantic side. Structured queries use their own filters embedded in the query text.

Debugging results

If search isn’t returning what you expect:
  1. Check the routing. Did Memic take the route you expected? If a natural-language query got routed to structured, rephrase it to be less filter-like. If a filter query got routed to semantic, be more explicit about the comparison.
  2. Verify the file is ready. GET /files/{id}/status. If it’s still processing, passages aren’t indexed yet.
  3. Inspect total_results. If it’s 0, no content matched. Try a broader query or verify the content is in the right environment.
  4. Confirm the environment. GET /me returns which environment your key is bound to. If it’s not the one your files live in, swap keys.
  5. Check connectors. If you expected a structured result and got nothing, verify the connector is attached and synced in the dashboard.

Chat guide

Use search results to power grounded LLM answers.

API reference

Full search endpoint reference.