Neuroloom

Reference

Search API

Run semantic and keyword search across your workspace memories. The search endpoint combines pgvector cosine similarity with keyword frequency scoring and ranks results using a weighted formula. Use it to surface relevant past decisions, patterns, and context before starting new work.

See Memory Concepts for how memories are structured, or Knowledge Base Ingestion cookbook for bulk ingestion patterns.

Base URL and Authentication

https://api.neuroloom.dev

All requests require an API key:

Authorization: Token $MEMORIES_API_TOKEN

Search Memories

POST /api/v1/memories/search

Combined keyword and semantic search. Results are ranked by a weighted formula and returned ordered by score descending.

Ranking Formula

score = (keyword_score × 0.3) + (semantic_score × 0.6) + (importance_score × 0.1)

Semantic search uses pgvector cosine similarity on precomputed embeddings. It requires an OpenAI API key configured for the workspace — if not available, the endpoint falls back to keyword-only ranking.

memory_search(
  query="database connection pooling strategy",
  memory_types=["pattern", "decision"],
  min_importance=0.6,
  limit=10
)

The MCP memory_search tool accepts one additional parameter not available in the REST API:

ParameterTypeDefaultDescription
tag_prefixesarray of stringsFilter to memories whose tags start with any of these prefixes. Useful for namespaced tagging schemes.

The memory_by_file MCP tool is a convenience wrapper that calls search with a files filter:

memory_by_file(
  file_path="api/neuroloom_api/routers/memories.py",
  limit=10
)
import httpx, os

response = httpx.post(
    "https://api.neuroloom.dev/api/v1/memories/search",
    headers={"Authorization": f"Token {os.environ['MEMORIES_API_TOKEN']}"},
    json={
        "query": "database connection pooling strategy",
        "memory_types": ["pattern", "decision"],
        "min_importance": 0.6,
        "limit": 10,
        "use_semantic": True,
    },
)
results = response.json()
for r in results["results"]:
    print(r["memory"]["title"], r["score"])
curl -X POST "https://api.neuroloom.dev/api/v1/memories/search" \
  -H "Authorization: Token $MEMORIES_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "database connection pooling strategy",
    "memory_types": ["pattern", "decision"],
    "min_importance": 0.6,
    "limit": 10
  }'

Request Body

FieldTypeRequiredDefaultDescription
querystringNo""Free-text query used for both keyword matching and semantic similarity. Can be a question, phrase, or concept label.
memory_typesarray of stringsNonullFilter to one or more memory type values (e.g. ["decision", "pattern"]). Note: plural field name, unlike the list endpoint's singular memory_type.
tagsarray of stringsNonullFilter to memories that include ANY of these tags (OR semantics).
filesarray of stringsNonullFilter to memories that reference ANY of these file paths. Note: this field is files, not source_files.
min_importancefloatNonullOnly return memories with importance_score >= this value.
min_confidencefloatNonullOnly return memories with confidence_score >= this value.
use_semanticbooleanNotrueEnable semantic (embedding) search. Set false for pure keyword search.
limitintegerNo20Max results to return (min 1, max 200).
offsetintegerNo0Results to skip for pagination.
Warning

The search endpoint uses memory_types (plural array) while the list endpoint uses memory_type (singular string). Using the wrong one silently drops your filter.

Warning

File filtering uses files (not source_files). Using source_files in a search request body is silently ignored.


Response

200 OK

{
  "count": 2,
  "query": "database connection pooling strategy",
  "filters": {
    "workspace_id": "ws-xyz789",
    "memory_types": ["pattern", "decision"],
    "tags": null,
    "min_importance": 0.6
  },
  "results": [
    {
      "memory": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "memory_id": "mem-a1b2c3d4e5f6g7h8",
        "workspace_id": "ws-xyz789",
        "title": "Use connection pooling for all DB connections",
        "narrative": "Configure SQLAlchemy with pool_size=10, max_overflow=20. Never create engines per-request — share a single engine per process.",
        "memory_type": "pattern",
        "tags": ["sqlalchemy", "database", "performance"],
        "concepts": ["connection-pooling", "database"],
        "source_files": ["api/neuroloom_api/database.py"],
        "importance_score": 0.88,
        "confidence_score": 0.9,
        "pagerank_score": 0.45,
        "community_label": "database-patterns",
        "access_count": 8,
        "retrieval_count": 22,
        "created_at": "2026-03-15T10:00:00Z"
      },
      "score": 0.92,
      "keyword_score": 0.0,
      "semantic_score": 0.0,
      "match_type": "combined"
    }
  ]
}

SearchResult fields

FieldTypeDescription
memoryobjectFull memory object.
scorefloatCombined ranking score, 0.01.0.
keyword_scorefloatReserved for future use; currently always 0.0.
semantic_scorefloatReserved for future use; currently always 0.0.
match_typestringWhich component(s) contributed: "keyword", "semantic", or "combined".
Note

count is the number of results returned on this page, not a total record count. Search is bounded by limit. There is no total_count or cursor field.


Common Search Patterns

Find memories by file

Surface decisions and patterns captured while working on a specific file:

curl -X POST "https://api.neuroloom.dev/api/v1/memories/search" \
  -H "Authorization: Token $MEMORIES_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "files": ["api/neuroloom_api/routers/memories.py"],
    "limit": 20
  }'

Disable semantic ranking for exact phrase matching:

curl -X POST "https://api.neuroloom.dev/api/v1/memories/search" \
  -H "Authorization: Token $MEMORIES_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "HNSW ef_construction",
    "use_semantic": false,
    "limit": 10
  }'

High-importance decisions only

Retrieve only well-established decisions above an importance threshold:

curl -X POST "https://api.neuroloom.dev/api/v1/memories/search" \
  -H "Authorization: Token $MEMORIES_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "database schema migration strategy",
    "memory_types": ["decision", "architecture"],
    "min_importance": 0.8,
    "limit": 5
  }'

Filter by tags

Find all memories tagged with specific labels:

curl -X POST "https://api.neuroloom.dev/api/v1/memories/search" \
  -H "Authorization: Token $MEMORIES_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tags": ["pgvector", "performance"],
    "limit": 20
  }'

Semantic Search Fallback

When semantic search is enabled (use_semantic: true) but embeddings are unavailable — either because the workspace has no OpenAI API key configured or because a memory's embedding has not yet been generated — the endpoint falls back to keyword-only ranking. Results are still returned; only the scoring changes.

To check whether a memory has an embedding, inspect whether pagerank_score is non-null (both are populated by the same background job). Embeddings are generated asynchronously after memory creation, typically within seconds.


Error Responses

StatusWhen
401 UnauthorizedMissing or invalid Authorization header.
422 Unprocessable EntityInvalid parameter value (e.g. limit > 200, min_importance > 1.0).
{
  "detail": [
    {
      "loc": ["body", "limit"],
      "msg": "Input should be less than or equal to 200",
      "type": "less_than_equal"
    }
  ]
}

Ready to get started?

Start building with Neuroloom for free.

Start Building Free