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

# Metadata

> How HydraDB uses metadata fields to filter recall results deterministically.

## 1. What it is

Metadata is structured data attached to knowledge and memories. It lets you narrow recall to a known scope before semantic retrieval runs.

Use metadata when you already know a concrete attribute of the content you want back - for example:

* `environment: "production"`
* `document_type: "runbook"`
* `compliance_framework: "SOC2"`
* `status: "published"`

Metadata filtering is different from semantic search. Semantic search finds content by meaning; metadata filtering narrows the candidate set using structured fields.

***

## 2. What it does

When you pass `metadata_filters` to recall, HydraDB uses those filters to narrow the candidate set before ranking retrieved chunks.

This gives you more predictable recall when the query needs to stay inside a known slice of data.

For example, this query:

```json theme={"dark"}
{
  "query": "How does authentication work?",
  "metadata_filters": {
    "compliance_framework": "SOC2"
  }
}
```

does not ask HydraDB to semantically interpret "SOC2". It narrows recall to content tagged with that metadata value, then runs retrieval inside that filtered set.

Use metadata filters for hard constraints. Use semantic recall for fuzzy or conceptual matching.

***

## 3. When to use it

Use metadata filtering when:

* The result must come from a known category, environment, customer tier, language, status, or document type.
* You need deterministic narrowing alongside semantic recall.
* You want to avoid mixing content from different operational scopes.
* You want to keep draft, archived, internal, or region-specific content out of a user-facing answer.

Do not use metadata filtering for:

* Synonyms
* Partial matches
* Fuzzy intent
* Conceptual similarity
* Ranking preferences
* Range or contains-style operators

Those belong in the query, recall mode, or downstream reranking logic.

***

## 4. How it works

### 1. Define filterable fields

Filterable top-level metadata fields are defined in the tenant metadata schema.

Plan filterable fields before ingestion. If your application needs to filter on a field, define it in the tenant metadata schema before writing data that depends on that filter, and enable matching for it.

### 2. Attach metadata when writing data

Attach metadata when adding knowledge or memories.

Use metadata for stable attributes that you expect to filter on later, such as:

```json theme={"dark"}
{
  "environment": "production",
  "document_type": "runbook",
  "status": "published"
}
```

### 3. Filter during recall

Pass `metadata_filters` during recall to narrow the candidate set.

```json theme={"dark"}
{
  "tenant_id": "acme_corp",
  "query": "How do I rotate API keys?",
  "metadata_filters": {
    "environment": "production",
    "document_type": "runbook"
  }
}
```

Recall then runs over candidates matching the filter.

***

## 5. Key concepts

### Tenant metadata schema

The tenant metadata schema defines which top-level metadata fields can be matched during recall.

Use it for fields that your application will filter on repeatedly, such as:

* `environment`
* `language`
* `region`
* `document_type`
* `status`
* `customer_tier`

For complete `tenant_metadata_schema` examples, supported field types, and advanced configuration options, see [Create Tenant API Reference](/api-reference/endpoint/create-tenant).

### `enable_match`

A metadata field must be match-enabled to be usable in `metadata_filters`.

If a field is stored but not match-enabled, do not rely on it for deterministic filtering.

### `metadata_filters`

`metadata_filters` is the recall parameter used to apply deterministic filters.

Example:

```json theme={"dark"}
{
  "metadata_filters": {
    "status": "published",
    "language": "en"
  }
}
```

Multiple keys are treated as structured filter constraints; use semantic recall or downstream reranking for fuzzy, range, or preference-based matching.
Use it when the filter value is known exactly. Operators such as range, contains, or fuzzy matching are not supported.

### `metadata` vs `additional_metadata`

HydraDB exposes two metadata fields on every source object. **Both are filterable at recall**, but via different keys in `metadata_filters` and with different performance characteristics:

* **`metadata`** -- schema-aligned tenant-level fields. Each key must be declared in `tenant_metadata_schema` with `enable_match: true` at tenant creation. Filter via **top-level keys** in `metadata_filters`. Pre-filtered in the vector store, so this is the fast path.
* **`additional_metadata`** -- free-form document-level fields. Filter by nesting under the **`additional_metadata`** key inside `metadata_filters` (canonical) or `document_metadata` (legacy alias). Applied post-retrieval, with the engine over-fetching (\~3x) to compensate -- slower than tenant-level filters.

````json theme={"dark"}
{
  "metadata_filters": {
    "environment": "production",
    "additional_metadata": { "author": "alice" }
  }
}

If a field will be filtered on every query (hot path), put it in `metadata` and declare it in the tenant schema with `enable_match: true`. For ad-hoc or per-document fields, use `additional_metadata`.

### Metadata filtering vs `sub_tenant_id`

Use `sub_tenant_id` to partition data by user, workspace, team, or another logical scope.

Use `metadata_filters` to narrow results inside that scope.

They are complementary:

```text
tenant_id      -> primary scope
sub_tenant_id  -> logical partition inside the tenant
metadata       -> deterministic filters inside that partition
````

Do not use metadata filters as a substitute for choosing the right tenant or sub-tenant.

***

## 6. Minimal working example

This example shows the full pattern:

1. Create a tenant with a filterable metadata field.
2. Write content tagged with that metadata.
3. Recall content matching that metadata.

### 1. Define filterable metadata

```json theme={"dark"}
{
  "tenant_id": "acme_corp",
  "tenant_metadata_schema": [
    {
      "name": "compliance_framework",
      "data_type": "VARCHAR",
      "enable_match": true
    }
  ]
}
```

The exact tenant creation request may include additional fields depending on your setup. See the [Create Tenant API Reference](/api-reference/endpoint/create-tenant) for the complete schema.

### 2. Attach metadata when writing content

```json theme={"dark"}
{
  "tenant_id": "acme_corp",
  "app_knowledge": [
    {
      "tenant_id": "acme_corp",
      "sub_tenant_id": "acme_corp",
      "id": "auth-controls-001",
      "kind": "knowledge_base",
      "provider": "internal",
      "external_id": "auth-controls-001",
      "fields": {
        "kind": "knowledge_base",
        "title": "Authentication controls",
        "body": "Authentication controls are reviewed quarterly for SOC2."
      },
      "metadata": {
        "compliance_framework": "SOC2"
      }
    }
  ]
}
```

Use the metadata field names you planned in the tenant metadata schema.

### 3. Recall with `metadata_filters`

```python theme={"dark"}
result = client.recall.full_recall(
    tenant_id="acme_corp",
    query="How does authentication control review work?",
    metadata_filters={
        "compliance_framework": "SOC2",
    },
)
```

```typescript theme={"dark"}
const result = await client.recall.fullRecall({
  tenant_id: "acme_corp",
  query: "How does authentication control review work?",
  metadata_filters: {
    compliance_framework: "SOC2",
  },
});
```

Recall then runs over candidates matching the filter.

***

## 7. Recommended patterns

### Published vs draft content

Use a `status` field when your application has both draft and published content.

```json theme={"dark"}
{
  "metadata_filters": {
    "status": "published"
  }
}
```

This helps prevent draft content from appearing in user-facing answers.

### Language-specific recall

Use a `language` field when your tenant contains multilingual content.

```json theme={"dark"}
{
  "metadata_filters": {
    "language": "en"
  }
}
```

### Environment-specific recall

If environment-specific content intentionally exists in the same tenant scope, use an `environment` field to narrow recall.

```json theme={"dark"}
{
  "metadata_filters": {
    "environment": "production"
  }
}
```

For stronger separation between production and staging, prefer separate tenants. Use metadata only when the content is intentionally stored under the same tenant.

### Document-type filtering

Use a `document_type` field when different source types should be retrieved differently.

```json theme={"dark"}
{
  "metadata_filters": {
    "document_type": "runbook"
  }
}
```

***

## 8. Common mistakes

**Filtering on fields that were not configured for matching.**\
If a field is not declared and match-enabled, HydraDB ignores that filter. Plan filterable fields before ingestion so your filters actually narrow recall.

**Using metadata filters for fuzzy search.**\
Metadata filters are for structured constraints. Use semantic recall for fuzzy meaning, synonyms, or conceptual matches.

**Trying to use metadata as a tenant boundary.**\
Metadata narrows results inside a scope. It should not replace `tenant_id` or `sub_tenant_id` for scoping customers, users, or workspaces.

**Adding filterable fields too late.**\
If your application needs deterministic filtering on a field, plan it early and declare it in the tenant metadata schema before ingestion.

**Confusing metadata fields across endpoints.**\
Metadata is always passed as plain JSON objects using the field names `metadata` and `additional_metadata`. Check the relevant endpoint reference for which fields are supported.

**Over-filtering.**\
Too many filters can remove the chunk that would have answered the question. Start with the minimum hard constraints needed, then tune.

***

## Related

* [Recall](/essentials/recall) - using `metadata_filters` during retrieval
* [Memories](/essentials/memories) - metadata fields on memory items
* [Multi-Tenant Support](/essentials/multi-tenant) - tenant and sub-tenant scoping
* [Create Tenant API Reference](/api-reference/endpoint/create-tenant) - defining tenant metadata schema
* [Full Recall API Reference](/api-reference/endpoint/full-recall) - using metadata filters in recall
