Skip to main content
Engram uses SQLite FTS5 for fast full-text search across observations. Search queries are automatically sanitized and optimized.

Search Observations

GET /search Search observations using full-text search.

Query Parameters

q
string
required
Search query. Supports multiple words, automatically quoted for safety.
type
string
Filter by observation type (e.g., “bug”, “architecture”)
project
string
Filter by project name
scope
string
Filter by scope: project or personal
limit
integer
default:"10"
Maximum results to return (1-20)

Response

Returns an array of search results with relevance ranking:
id
integer
Observation ID
session_id
string
Session ID
type
string
Observation type
title
string
Observation title
content
string
Full observation content
rank
float
FTS5 relevance rank (lower is better)
All other observation fields are included (see Observations API for complete schema).

Example

# Basic search
curl "http://127.0.0.1:7437/search?q=authentication"

# Search with filters
curl "http://127.0.0.1:7437/search?q=token%20refresh&type=bug&project=engram&limit=5"
[
  {
    "id": 42,
    "session_id": "session-abc123",
    "type": "bug",
    "title": "Auth token expiration issue",
    "content": "Users were experiencing unexpected logouts due to token expiration not being handled properly. Fixed by implementing refresh token rotation.",
    "tool_name": null,
    "project": "engram",
    "scope": "project",
    "topic_key": null,
    "revision_count": 1,
    "duplicate_count": 1,
    "last_seen_at": null,
    "created_at": "2024-03-15 14:30:00",
    "updated_at": "2024-03-15 14:30:00",
    "deleted_at": null,
    "rank": -1.23456
  },
  {
    "id": 38,
    "session_id": "session-def456",
    "type": "architecture",
    "title": "Token refresh flow design",
    "content": "Implemented sliding window token refresh using JWT rotation. Old tokens remain valid for 5 minutes to handle race conditions.",
    "project": "engram",
    "scope": "project",
    "rank": -0.98765,
    "created_at": "2024-03-14 10:15:00",
    "updated_at": "2024-03-14 10:15:00"
  }
]

Search Behavior

Query Sanitization

All search queries are automatically sanitized to prevent FTS5 syntax errors:
Input:  "fix auth bug"
FTS5:   "fix" "auth" "bug"
Special characters are handled safely without manual escaping.

Ranking

Results are ranked by FTS5’s BM25 algorithm, which considers:
  • Term frequency - How often the search terms appear
  • Document length - Shorter documents with matches rank higher
  • Term rarity - Rare terms contribute more to relevance
Lower rank values indicate better matches (FTS5 uses negative scores).

Searched Fields

FTS5 searches across multiple fields:
  • title - Observation title
  • content - Full observation content
  • tool_name - Tool that created the observation
  • type - Observation type
  • project - Project name

Soft-Deleted Observations

Search excludes observations with deleted_at set (soft-deleted). Hard-deleted observations are permanently removed from the index.

Multi-Word Queries

Multi-word queries match observations containing all terms (AND logic):
curl "http://127.0.0.1:7437/search?q=token%20refresh%20flow"
# Matches: observations with "token" AND "refresh" AND "flow"

Empty Results

If no observations match, returns an empty array:
[]

Search Limits

The maximum limit is capped at 20 results to ensure performance. Default is 10.

Error Handling

Missing Query Parameter

curl http://127.0.0.1:7437/search
{
  "error": "q parameter is required"
}

Invalid Parameters

Invalid filter values are ignored. For example, a non-existent project returns empty results rather than an error.

Search Tips

  1. Be specific - More specific queries return better results
  2. Use filters - Combine text search with type, project, and scope filters
  3. Check rank - Lower rank values indicate more relevant matches
  4. Try variations - If no results, try different terms or broader queries

Performance

FTS5 provides sub-millisecond search performance for typical databases:
  • 1,000 observations: ~1ms
  • 10,000 observations: ~5ms
  • 100,000 observations: ~20ms
Search performance scales logarithmically with database size.

Build docs developers (and LLMs) love