> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trygroundai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

> How Ground's hybrid search works

# Search

Ground uses **hybrid search** combining vector similarity with full-text search for optimal retrieval.

## How It Works

### 1. Query Embedding

Your search query is converted into a vector embedding using the same model used for indexing content.

### 2. Vector Search

pgvector finds the most similar chunks using cosine similarity:

```sql theme={null}
SELECT * FROM chunks
ORDER BY embedding <=> query_embedding
LIMIT 50
```

### 3. Full-Text Search

PostgreSQL's full-text search finds keyword matches:

```sql theme={null}
SELECT * FROM chunks
WHERE to_tsvector('english', content) @@ plainto_tsquery('english', query)
```

### 4. Score Fusion

Results are combined using weighted scores:

```
combined_score = 0.7 × vector_score + 0.3 × text_score
```

### 5. Policy application

The retrieval policy applies:

* Source priority weights (boost OpenAPI results for API questions)
* Staleness filtering (exclude or warn about stale results)
* Refusal thresholds (refuse to answer with insufficient evidence)

## Search Request

```bash theme={null}
curl "https://api.trygroundai.com/search?query=how+to+authenticate&top_k=10&max_tokens=4000" \
  -H "Authorization: Bearer gnd_your_api_key"
```

For **deeper context** (neighbor expansion and optional second hybrid pass), use **`POST /search/rmh`** — see the [RMH search API](/api-reference/rmh-search).

Parameters:

* `query`: Search query (required)
* `source_ids`: Filter to specific sources (optional)
* `top_k`: Maximum results (default: 10, max: 50)
* `max_tokens`: Token budget for results (default: 4000)
* `include_stale`: Include stale results with warning (default: true)

## Search Response

```json theme={null}
{
  "results": [
    {
      "content": "...",
      "score": 0.85,
      "token_count": 150,
      "citation": {
        "chunk_id": "...",
        "source_id": "...",
        "source_name": "My API",
        "path": "/api/auth/login",
        "symbol": "POST",
        "version_ref": "v2.3.0",
        "language": "openapi",
        "chunk_type": "openapi"
      },
      "freshness_days": 5.2,
      "is_stale": false
    }
  ],
  "total_results": 10,
  "total_tokens": 1500,
  "sources_searched": 3,
  "sources_with_results": 2,
  "evidence_quality": {
    "score": 0.72,
    "evidence_count": 10,
    "avg_freshness_days": 8.5,
    "has_conflicts": false,
    "confidence": "high"
  },
  "staleness_summary": {
    "total_sources": 3,
    "fresh_sources": 2,
    "stale_sources": 1,
    "staleness_budget_days": 30,
    "stale_source_names": ["Old Docs"]
  },
  "conflicts": [],
  "warnings": [],
  "query": "how to authenticate",
  "search_time_ms": 45
}
```

## Evidence Quality

Ground computes an evidence quality score based on:

* **Score distribution**: Higher average scores = better quality
* **Evidence count**: More results = more confidence (up to a point)
* **Freshness**: Fresher sources = higher quality
* **Conflicts**: Conflicts reduce quality score
* **Source type**: OpenAPI chunks get a small boost for API questions

Confidence levels:

* `high`: score ≥ 0.7
* `medium`: score ≥ 0.5
* `low`: score ≥ 0.3
* `insufficient`: score \< 0.3

## No Evidence Response

When no relevant content is found:

```json theme={null}
{
  "message": "No relevant evidence found",
  "query": "something obscure",
  "sources_searched": 5,
  "suggestions": [
    "Try a broader or different query",
    "Check if relevant sources are synced"
  ]
}
```
