Python SDK
API Reference
The complete surface of litica v0.1.0 — one method per API route, 22 routes in total.
Client
litica.ClientClient(
api_key: str | None = None, # or LITICA_API_KEY
*,
base_url: str | None = None, # or LITICA_BASE_URL; default https://mcp.litica.org
agent_id: str | None = None, # or LITICA_AGENT_ID; default "default"
namespace_id: str | None = None, # or LITICA_NAMESPACE_ID; default None
timeout: float = 30.0,
transport: httpx.BaseTransport | None = None,
)Synchronous client for the Litica HTTP API. Raises LiticaConfigError if no API key is resolvable. agent_id and namespace_id become defaults for every call that accepts them; any call may override, and an explicit namespace_id=None means agent-private scope. Usable as a context manager. LiticaClient is a deprecated alias kept for one release.
Memories
On all write methods, remember: accepted is not searchable. See Writing Memories.
add_memoryPOST /memories · 202add_memory(
content: str,
*,
agent_id=UNSET, namespace_id=UNSET,
session_id: str | None = None,
) -> QueuedWriteQueue one memory. Returns once the server has accepted the write — before it is searchable. session_id is recorded on the audit trail and never affects retrieval.
add_memories_batchPOST /memories/batch · 202add_memories_batch(
contents: list[str],
*,
agent_id=UNSET, namespace_id=UNSET,
session_id: str | None = None,
) -> QueuedBatchQueue several memories in one call. Enqueue order is persist order; the namespace write check runs once for the batch. An empty list raises LiticaValidationError client-side; an over-cap batch is a 422 from the server. .queued on the result is the accepted count.
add_documentPOST /documents · 202add_document(
file_path: str | Path,
*,
agent_id=UNSET, namespace_id=UNSET,
session_id: str | None = None,
timeout: float = 120.0,
) -> QueuedDocumentUpload a PDF, DOCX, PPTX, or text file to ingest as memories. Raises FileNotFoundError for a missing path, LiticaUnsupportedMediaError (415) for an unparseable type, LiticaValidationError (422) for a file with no extractable text. timeout covers the upload request only.
search_memoriesGET /memories/searchsearch_memories(
query: str,
*,
top_k: int = 5,
agent_id=UNSET, namespace_id=UNSET,
session_id: str | None = None,
) -> list[SearchResult]Ranked natural-language search. Strengthens the memories it returns and logs the query — see Search & Retrieval.
list_memoriesGET /memorieslist_memories(
*,
top_k: int = 10,
agent_id=UNSET, namespace_id=UNSET,
include_archived: bool = False,
) -> list[MemoryRow]Recent memories, newest first. Consolidated-away memories are hidden unless include_archived=True.
get_memory_traceGET /memories/{id}/traceget_memory_trace(memory_id: int) -> MemoryTraceFull retrieval lineage for one memory: salience, retrieval count, every query that surfaced it, linked memories. rank inside retrievals is 0-based (1-based in search_explain).
delete_memoryDELETE /memories/{id}delete_memory(memory_id: int) -> intDelete one memory. Returns its id.
clear_memoriesDELETE /memoriesclear_memories(*, agent_id=UNSET) -> intDelete every memory for one agent. Returns the count removed. There is no undo.
list_queriesGET /querieslist_queries(limit: int = 50) -> list[QueryRow]Recent logged queries for the tenant, newest first.
list_agentsGET /agentslist_agents() -> list[str]Agent ids that have memories under this tenant.
get_tenantGET /tenantget_tenant() -> strThe tenant id this API key resolves to.
healthGET /healthhealth() -> boolWhether the server is reachable and healthy. The one unauthenticated route — and the one method that returns False instead of raising on connection failure.
Namespaces
Concepts and examples in Namespaces.
list_namespacesGET /namespaceslist_namespaces() -> list[Namespace]Every namespace under this tenant.
create_namespacePOST /namespaces · 201create_namespace(
name: str,
*,
read_policy: str = "grant", # "grant" | "open"
write_policy: str = "grant", # "grant" | "open"
agents: list[str] | None = None,
) -> NamespaceCreate a shared namespace. Listed agents are granted read and write. A duplicate name is a 409 (LiticaConflictError); the server caps agents per namespace.
delete_namespaceDELETE /namespaces/{id}delete_namespace(namespace_id: str) -> strDelete a namespace. Returns its id.
list_namespace_agentsGET /namespaces/{id}/agentslist_namespace_agents(namespace_id: str) -> list[NamespaceAgent]Agents granted access to a namespace.
grant_namespace_agentPOST /namespaces/{id}/agentsgrant_namespace_agent(
namespace_id: str,
agent_id: str,
*,
can_read: bool = True,
can_write: bool = True,
) -> NamespaceAgentGrant an agent access. Upserts — calling again updates the existing grant.
remove_namespace_agentDELETE /namespaces/{id}/agents/{agent_id}remove_namespace_agent(namespace_id: str, agent_id: str) -> strRevoke an agent's access.
Inspection
Concepts and examples in Inspection.
viz_graphGET /viz/graphviz_graph(
*,
agent_id=UNSET, namespace_id=UNSET,
limit: int = 300,
) -> GraphMemory graph for one scope. .truncated flags that limit cut the result short.
viz_add_eventsGET /viz/add-eventsviz_add_events(
*,
since_id: int = 0,
limit: int = 100,
order: str = "asc",
agent_id: str | None = None, # does NOT inherit the client default
namespace_id: str | None = None, # does NOT inherit the client default
) -> AddEventPageCursor feed over the write-side audit trail. Feed .cursor back as since_id to continue; order="desc", limit=1 bootstraps the cursor. Scope filters deliberately default to all scopes.
viz_pendingGET /viz/pendingviz_pending(*, agent_id=UNSET) -> intWrite-queue depth for one agent.
search_explainPOST /viz/search-explainsearch_explain(
query: str,
*,
top_k: int = 5,
agent_id=UNSET, namespace_id=UNSET,
rehearse: bool = True,
max_candidates: int = 25,
session_id: str | None = None,
query_rf: dict | None = None,
) -> SearchExplanationSearch with the full score breakdown. With the default rehearse=True this is a real search — it strengthens results and logs the query. Pass rehearse=False for a side-effect-free what-if; query_rf (a pre-decomposed query) is honored only then.
Lifecycle
closeclose() -> None
# or:
with litica.Client(...) as client:
...Close the underlying connection pool. Entering the client as a context manager closes it on exit.
Response models
All responses are frozen dataclasses that mirror the JSON exactly as the server sends it — no renaming, no unit conversions. Timestamps stay ISO-8601 strings (the server sends null for rows without one). Unknown fields never break parsing, and every model keeps the untouched body on .raw. A response missing an identity field raises LiticaResponseError.
| Model | Fields |
|---|---|
| SearchResult | id, text, created_at, source_agent_id |
| MemoryRow | id, text, created_at |
| MemoryTrace | id, text, agent_id, namespace_id, field_, reference_frame, created_at, retrieval_count, salience, last_retrieved_at, retrievals, linked_memories |
| QueryRow | id, query_text, agent_id, namespace_id, top_k, result_count, created_at |
| Namespace | namespace_id, name, read_policy, write_policy, created_at, agents |
| NamespaceAgent | agent_id, can_read, can_write, namespace_id |
| QueuedWrite | queued: bool |
| QueuedBatch | queued: int (accepted count) |
| QueuedDocument | queued, filename, chars |
| Graph | nodes, links, scope, truncated |
| AddEventPage | events, cursor |
| ExplainResult | id, text, rank (1-based), final_score, source_agent_id |
| SearchExplanation | results, trace, rehearsed, candidates |
Deeply nested viz payloads — graph nodes, trace candidates, audit events — stay plain dicts by design: they are UI-shaped and evolve with the retrieval internals.
Exceptions
The full hierarchy, status-code mapping, and retry guidance live in Error Handling. Everything inherits from LiticaError, which carries .status_code, .detail, and .response.
Module exports
litica.__version__ is the package version. litica.Client is the client; litica.LiticaClient is a deprecated alias kept for one release. All models and exceptions are importable from the top-level litica package.