Python SDK

Call verifiable memory from Python.

Use CloudClient when Bilinc sits inside your agent runtime and needs hosted project-isolated memory.

Install pathPyPI package
RuntimeHosted Cloud
InterfacePython + CLI + MCP
Releasev2.3.9
Getting started

Import CloudClient, then write, recall, and inspect hosted state.

import os
from bilinc import CloudClient

client = CloudClient(api_key=os.environ["BILINC_API_KEY"])

client.commit("user.preference", {"theme": "dark"})
results = client.recall("user preference", limit=5)

# What can this key do? (authenticated, never billed)
status = client.status()

# Is the service reachable? (public service health)
health = client.health()
Full lifecycle

Write, correct, checkpoint, inspect, forget, recover.

import os
from bilinc import CloudClient

client = CloudClient(api_key=os.environ["BILINC_API_KEY"])

# 1. Write. The returned version is your optimistic-concurrency token.
written = client.commit("user.preference", {"theme": "dark"})
version = written["entryVersion"]

# 2. Read.
client.recall("user preference", profile="balanced", limit=5)

# 3. Correct something you already know. Fails if it does not exist.
client.revise(
    "user.preference",
    {"theme": "light"},
    reason="user changed it in settings",
    expected_version=version,
)

# 4. Checkpoint before risky agent work.
snapshot = client.create_snapshot(label="before-autonomous-run")["snapshot"]

# 5. See what the run changed. Values are redacted by default.
client.diff(snapshot["id"])

# 6. Review what is stored and how one memory changed. Both reads are free.
client.list_memories(prefix="user.", limit=50)
client.history("user.preference")

# 7. Drop obsolete state. A reason is required and is audited.
client.forget("user.preference", reason="superseded by profile service")

# 8. Recover. Preview is free; execute is destructive and needs the token.
preview = client.rollback_preview(snapshot["id"], reason="undo bad agent run")
client.rollback(
    snapshot["id"],
    confirmation_token=preview["confirmationToken"],
    reason="undo bad agent run",
)
Methods

The public surface, and what each call costs.

commit(key, value, ...)

Write a memory. Returns an entry version for optimistic concurrency.

recall(query, profile=, limit=)

Read memories. Profiles are entitlement gated; limit is 1–100.

revise(key, value, reason=, expected_version=)

Replace an existing memory. Never creates.

confirm(key, expected_version=, reason=)

Record that a memory is still accurate without resending it. One write operation.

forget(key, reason=)

Destructive. Remove a memory. A reason is required.

list_memories(prefix=, memory_type=, updated_after=, updated_before=, cursor=, limit=50, values="preview")

Free. One page of stored memories, ordered by key. Pass nextCursor back as cursor.

iter_memories(prefix=, memory_type=, updated_after=, updated_before=, page_size=100, values="preview")

Free. Yields every matching memory, following the cursor for you.

history(key, limit=20, values="full")

Free. One memory’s most recent changes, newest first: 20 by default, up to 100, with truncated set when older ones exist. Values from before a forget are never returned.

export(prefix=, memory_type=)

Free. Every matching memory with its full value, as one JSON-ready dict. History is not included.

create_snapshot(label=) / list_snapshots(limit=)

Checkpoint the project, or list checkpoints.

snapshot(action="create"|"list")

The same two operations behind one MCP-shaped call.

diff(from_snapshot_id, to_snapshot_id=, include_values=)

Free comparison; values redacted by default.

rollback_preview(snapshot_id, reason=)

Free. Returns a short-lived confirmation token.

rollback(snapshot_id, confirmation_token=, reason=)

Destructive. Requires that token.

status()

Authenticated workspace, plan, capabilities, limits, usage. Never billed.

health()

Public service health.

Review

See what Bilinc remembers, and how it changed.

list_memories, history, and export only read and are never billed. The time filters take a datetime (a naive one is read as UTC) or an ISO-8601 string. The same commands are in the CLI: bilinc list, bilinc history KEY, bilinc confirm KEY, and bilinc export -o FILE.

import json
import os
from bilinc import CloudClient

client = CloudClient(api_key=os.environ["BILINC_API_KEY"])

# Every memory under a prefix, page by page (free).
for entry in client.iter_memories(prefix="user."):
    print(entry["key"], entry["updatedAt"], entry.get("value"))

# How one memory changed, newest first (free).
for step in client.history("user.preference")["entries"]:
    print(step["at"], step["op"], step.get("before"), "->", step.get("after"))

# Still accurate? Confirm it without resending the value (one write).
client.confirm("user.preference", reason="user said it is still right")

# Everything, with full values, as one JSON file (free).
with open("bilinc-memory.json", "w") as handle:
    json.dump(client.export(), handle, indent=2)
Memory types

Use the right shape for the right state.

working

Active short-lived context.

episodic

Event and session memory.

procedural

Reusable workflows.

semantic

Durable facts and beliefs.

Retries

Reads retry themselves; writes do not.

The SDK retries read-only calls a bounded number of times on transport and 5xx failures. Writes are single-shot on purpose: a retried write could apply twice. Pass idempotency_key on a write you might retry, and the server replays the original result instead of executing again.