Python API Reference

The CLI (keep put, keep find, etc.) is the primary interface. The Python API is for embedding keep into applications.

Installation

pip install keep-skill

For LangChain/LangGraph integration:

pip install keep-skill[langchain]

See QUICKSTART.md for provider configuration (API keys or local models).

Quick Start

from keep import Keeper

kp = Keeper()  # Uses ~/.keep/ by default

# Index documents
kp.put(uri="file:///path/to/doc.md", tags={"project": "myapp"})
kp.put(uri="https://example.com/page", tags={"topic": "reference"})
kp.put("Important insight about auth patterns")

# Search
results = kp.find("authentication", limit=5)
for r in results:
    print(f"[{r.score:.2f}] {r.id}: {r.summary}")

# Retrieve
item = kp.get("file:///path/to/doc.md")
print(item.summary)
print(item.tags)

API Reference

Imports

from keep import Keeper, Item
from keep.document_store import VersionInfo, PartInfo  # for version/part history

Initialization

# Default store (~/.keep/)
kp = Keeper()

# Custom store location
kp = Keeper(store_path="/path/to/store")

Core Operations

Indexing

# Index from URI (file:// or https://)
kp.put(uri=uri, tags={}, summary=None) → Item

# Index inline content
kp.put(content, tags={}, summary=None) → Item

# Full signature:
# kp.put(content=None, *, uri=None, id=None, summary=None,
#        tags=None, created_at=None) → Item

# Notes:
# - Exactly one of content or uri must be provided
# - If summary provided, skips auto-summarization
# - Inline content used verbatim if short (≤max_summary_length)
# - User tags (domain, topic, etc.) provide context for summarization
# - id: override auto-generated ID (for managed imports)
# - created_at: ISO timestamp override (for historical imports)
# Semantic search (default)
kp.find("auth", limit=10) → list[Item]

# With tag pre-filtering
kp.find("auth", tags={"user": "alice"}, limit=10) → list[Item]

# Full-text search
kp.find("auth", fulltext=True) → list[Item]

# Find similar to an existing note
kp.find(similar_to="note-id", limit=10) → list[Item]

# Time filtering (all search methods support since)
kp.find("auth", since="P7D")      # Last 7 days
kp.find("auth", since="P1W")      # Last week
kp.find("auth", since="PT1H")     # Last hour
kp.find("auth", since="2026-01-15")  # Since date

Listing and Filtering

# Unified listing with composable filters (all optional, AND'd together)
kp.list_items(limit=10) → list[Item]
kp.list_items(tags={"project": "myapp"}, since="P7D")
kp.list_items(tag_keys=["act"], since="P3D")      # Key-only: any value
kp.list_items(prefix=".tag/act")                   # ID prefix
kp.list_items(order_by="accessed", limit=20)       # Sort by access time

Item Access

# Get by ID
kp.get(id) → Item | None

# Check existence
kp.exists(id) → bool

Tags

# Update tags only (no re-processing)
kp.tag(id, tags={}) → Item | None

# Delete tag by setting empty value
kp.tag("doc:1", {"obsolete": ""})  # Removes 'obsolete' tag

# Edit tags on a part (parts are otherwise immutable)
kp.tag_part("doc:1", 1, tags={"topic": "oauth2"}) → PartInfo | None
kp.tag_part("doc:1", 1, tags={"topic": ""})  # Remove tag

# List tag keys or values
kp.list_tags(key=None) → list[str]
kp.list_tags()          # All tag keys
kp.list_tags("project") # All values for 'project' key

Version History

# Get previous version
kp.get_version(id, offset=1) → Item | None
# selector: 0=current, 1=previous, 2=two versions ago, -1=oldest archived

# List all versions
kp.list_versions(id, limit=10) → list[VersionInfo]

# Get navigation metadata
kp.get_version_nav(id, current_version=None, limit=3) → dict
# Returns: {"prev": [VersionInfo, ...], "next": [VersionInfo, ...]}

Current Intentions (Now)

# Get current intentions (auto-creates if missing)
kp.get_now() → Item

# Per-user scoped intentions
kp.get_now(scope="alice") → Item

# Set current intentions
kp.set_now(content, tags={}) → Item

# Per-user scoped update (auto-tags user=alice)
kp.set_now(content, scope="alice") → Item

Deletion

# Delete item and its versions
kp.delete(id) → bool
kp.delete(id, delete_versions=False) → bool  # Keep version history

# Revert to previous version (if history exists)
kp.revert(id) → Item | None

Data Types

Item

Fields:

Properties (from tags):

VersionInfo

Fields for version history listings:

PartInfo

Fields for structural parts (from analyze()):

Tags

Tag Merge Order

When indexing, tags merge in priority order (later wins):

  1. Existing tags (from previous version)
  2. Config tags (from [tags] in keep.toml)
  3. Environment tags (from KEEP_TAG_* variables)
  4. User tags (passed to put() or tag())

Tag Rules

Environment Tags

import os
os.environ["KEEP_TAG_PROJECT"] = "myapp"
os.environ["KEEP_TAG_OWNER"] = "alice"

kp.put("note")  # Auto-tagged with project=myapp, owner=alice

Config Tags

Add to keep.toml:

[tags]
project = "my-project"
owner = "alice"
required = ["user"]                    # Enforce required tags on put()
namespace_keys = ["category", "user"]  # LangGraph namespace mapping

See TAGGING.md for details on:

System Tags (Read-Only)

Protected tags (prefix _) managed automatically:

Query system tags:

kp.list_items(tags={"_updated_date": "2026-01-30"})
kp.list_items(tags={"_source": "inline"})

See SYSTEM-TAGS.md for complete reference.

Version Identifiers

Append @V{N} to specify version by offset:

item = kp.get("doc:1@V{1}")  # Get previous version
versions = kp.list_versions("doc:1")

Error Handling

from keep import Keeper

try:
    kp = Keeper()
    item = kp.get("nonexistent")
    if item is None:
        print("Item not found")
except Exception as e:
    print(f"Error: {e}")

Common errors:

LangChain / LangGraph

For LangChain and LangGraph integration (BaseStore, retriever, tools, middleware), see LANGCHAIN-INTEGRATION.md.

See Also