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

# Provider capabilities and feature negotiation

> Capabilities let your app discover what features a provider supports at runtime, so you can degrade gracefully across different backends.

Not every memory provider supports the same features. One backend may offer full vector search and temporal queries; another may support only basic keyword lookup. OMP solves this with a capabilities system: every provider declares exactly what it supports, and your application can inspect that declaration at runtime to decide how to behave.

## What are capabilities?

Capabilities are a structured declaration of the features, verbs, and limits a provider exposes. They are returned by the `GET /capabilities` endpoint on any OMP server, and surfaced through `mem.capabilities()` in the SDK. Rather than hardcoding assumptions about what a provider can do, you query capabilities once and let that answer drive your code path.

## Querying capabilities

```python theme={null}
from openmem import Memory

mem = Memory(provider="mem0", api_key="...")

caps = mem.capabilities()

print(caps.provider)              # "mem0"
print(caps.omp_version)           # "0.1"
print(caps.verbs)                 # ["add", "search", "get", "update", "delete", "list", "context"]
print(caps.features.vector_search)    # True
print(caps.features.temporal)         # True
print(caps.features.scopes)           # "native"
print(caps.limits.rate_limit_per_minute)  # 600
```

<Note>
  The SDK caches the capabilities response per session. Subsequent calls to `mem.capabilities()` return the cached result without any additional network round-trip.
</Note>

## Capabilities response structure

The raw JSON response from `GET /capabilities` looks like this:

```json theme={null}
{
  "omp_version": "0.1",
  "provider": "mem0",
  "verbs": ["add", "search", "get", "update", "delete", "list", "context"],
  "features": {
    "vector_search": true,
    "keyword_search": true,
    "graph_queries": true,
    "temporal": true,
    "scopes": "native",
    "max_content_length": 10000,
    "supports_e2e": false,
    "supports_audit": true,
    "supports_supersession": true
  },
  "limits": {
    "rate_limit_per_minute": 600,
    "max_search_results": 100
  }
}
```

### Field reference

**Top-level fields**

| Field         | Type      | Description                                                                                                                                                              |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `omp_version` | string    | The OMP spec version the provider implements. Its presence signals that the provider speaks OMP natively; the SDK uses a passthrough adapter when this field is present. |
| `provider`    | string    | A human-readable identifier for the provider, e.g. `"mem0"` or `"postgres"`.                                                                                             |
| `verbs`       | string\[] | The list of OMP verbs this provider supports. Common values: `"add"`, `"search"`, `"get"`, `"update"`, `"delete"`, `"list"`, `"context"`, `"audit"`.                     |

**`features` object**

| Field                   | Type    | Description                                                                                                                |
| ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------- |
| `vector_search`         | boolean | Whether the provider supports semantic/vector similarity search.                                                           |
| `keyword_search`        | boolean | Whether the provider supports exact keyword or full-text search.                                                           |
| `graph_queries`         | boolean | Whether the provider supports graph-based relationship queries.                                                            |
| `temporal`              | boolean | Whether search supports time-range filters like `since` and `until`.                                                       |
| `scopes`                | string  | How scopes are implemented: `"native"` (first-class), `"tags"` (simulated via tag filtering), or `"none"` (not supported). |
| `max_content_length`    | integer | Maximum number of characters allowed in the `content` field of a single memory.                                            |
| `supports_e2e`          | boolean | Whether end-to-end encryption is supported (deferred to OMP v0.2).                                                         |
| `supports_audit`        | boolean | Whether the `audit` verb is available on this provider.                                                                    |
| `supports_supersession` | boolean | Whether the provider tracks memory lineage via `supersedes` chains.                                                        |

**`limits` object**

| Field                   | Type    | Description                                                                     |
| ----------------------- | ------- | ------------------------------------------------------------------------------- |
| `rate_limit_per_minute` | integer | Maximum number of API requests the provider accepts per minute.                 |
| `max_search_results`    | integer | Maximum value you can pass for the `limit` parameter in `search()` or `list()`. |

## Capability-aware code

The recommended pattern is to query capabilities once at startup and then branch on the features you need:

```python theme={null}
from datetime import datetime, timezone
from openmem import Memory

mem = Memory(provider="mem0", api_key="...")
caps = mem.capabilities()

uid = "u1"

# Use temporal list when the provider supports it
if caps.features.temporal:
    page = mem.list(
        uid,
        since=datetime(2026, 4, 20, tzinfo=timezone.utc),
    )
else:
    # Fall back to semantic search
    results = mem.search("what did I work on last week?", user_id=uid)
```

You can apply the same pattern to guard any feature-dependent code path:

```python theme={null}
# Guard graph queries
if caps.features.graph_queries:
    # Use graph-aware prompting strategy
    ...

# Guard audit log access
if caps.features.supports_audit:
    log = mem.audit(uid, limit=20)

# Respect content length limits before adding
if caps.features.max_content_length:
    content = content[:caps.features.max_content_length]
```

<Tip>
  Because capabilities are cached per session, it is safe to call `mem.capabilities()` inside a helper function without worrying about repeated network overhead.
</Tip>
