SDKs

How do I connect to Areev from code?

Create an Areev client instance — it reads connection details from environment variables and connects to a running Areev server.

from areev import Areev

areev = Areev()
areev.remember("John likes coffee")
results = areev.recall("what does John like?")
import { Areev } from "@areev/client";

const areev = new Areev();
await areev.remember("John likes coffee");
const { results } = await areev.recall("what does John like?");
use areev_client::Areev;

let areev = Areev::from_env();
areev.remember("John likes coffee").await?;
let results = areev.recall("what does John like?").await?;

All three SDKs share the same API surface. The client reads server connection details from environment variables, so you never hardcode credentials in your code. Install with pip install areev (Python), npm install @areev/client (TypeScript), or add areev-client to your Cargo.toml (Rust).

Python also provides an async variant for use in async applications:

from areev import AsyncAreev

async with AsyncAreev() as areev:
    await areev.remember("John likes coffee")
    results = await areev.recall("what does John like?")

How do I configure the connection?

Set three environment variables: AREEV_API_KEY, AREEV_URL, and AREEV_MEMORY_ID. All three have sensible defaults except the API key.

export AREEV_API_KEY="ar_your_api_key_here"
export AREEV_URL="https://app.areev.ai"      # default
export AREEV_MEMORY_ID="default"               # default
VariableDefaultDescription
AREEV_API_KEYAPI key (sent as X-API-Key header)
AREEV_URLhttps://app.areev.aiServer endpoint
AREEV_MEMORY_IDdefaultMemory database ID

The client sends the API key as an X-API-Key header on every request. Create API keys through the Areev console or the POST /auth/keys endpoint. For local development without authentication, the API key can be omitted if the server runs with auth disabled.

How do I store and recall memories?

Call remember(text) to store natural-language memories and recall(query) to search them. These are the primary operations for AI agent memory.

from areev import Areev

areev = Areev()

# Store memories (LLM extracts structured Belief grains automatically)
areev.remember("John likes coffee every morning")
areev.remember("Bob's favorite language is Rust")
areev.remember("The deployment deadline is Friday")

# Recall memories by natural-language query
results = areev.recall("what are John's preferences?")
for hit in results:
    print(hit["score"], hit["fields"])
import { Areev } from "@areev/client";

const areev = new Areev();

await areev.remember("John likes coffee every morning");
await areev.remember("Bob's favorite language is Rust");

const { results } = await areev.recall("what are John's preferences?");
results.forEach(hit => console.log(hit.score, hit.fields));

The remember() method accepts plain text and uses an LLM to extract structured Belief grains (subject/relation/object triples). In Python, remember() defaults to sync=True, meaning extraction happens inline before the call returns. All SDKs default the recall() limit to 10 results.

What methods does the client provide?

The Areev client exposes 9 methods covering memory storage, retrieval, deletion, health checks, and database management.

MethodDescription
remember(text)Store natural-language memory (LLM extracts structured grains)
recall(query)Search memories by natural-language query
forget(hash)Delete a memory by its content-address hash
add(grain_type, fields)Add a typed grain directly (belief, event, action, etc.)
get(hash)Retrieve a grain by its content-address hash
supersede(old_hash, grain_type, fields)Replace a grain with updated content (immutable versioning)
health()Server health check
stats()Database statistics (grain count, disk space)
flush()Flush the write buffer to disk

For operations beyond these 9 methods (compliance, consent, PII detection, sessions, scopes, hooks), use the HTTP REST API or CLI directly.

How do I add typed grains?

Use add(grain_type, fields) to store grains with explicit types and structured fields. This is useful when you need control over the grain type rather than relying on LLM extraction.

from areev import Areev

areev = Areev()

# Add a belief grain (triple-indexed in the hexastore)
h = areev.add("belief", {
    "subject": "john",
    "relation": "likes",
    "object": "coffee",
    "confidence": 0.95,
    "namespace": "prefs",
    "tags": ["ui", "settings"]
})
# h = "a3f8c1..." (64-char hex content-address hash)

# Other grain types
areev.add("event", {"content": "User completed onboarding", "user_id": "john"})
areev.add("action", {"input": "translate('hello')", "content": "hola"})
areev.add("goal", {"content": "Improve response latency below 200ms"})
import { Areev } from "@areev/client";

const areev = new Areev();

const h = await areev.add("belief", {
    subject: "john",
    relation: "likes",
    object: "coffee",
    confidence: 0.95,
});

await areev.add("event", { content: "User completed onboarding" });
use areev_client::Areev;
use serde_json::json;

let areev = Areev::from_env();

let h = areev.add("belief", json!({
    "subject": "john",
    "relation": "likes",
    "object": "coffee",
    "confidence": 0.95
})).await?;

areev.add("event", json!({
    "content": "User completed onboarding"
})).await?;

The add() method maps to the POST /api/memories/{id}/batch-add endpoint. Each grain type has required fields: beliefs need subject/relation/object; events need content; actions need tool_name or input/content; goals need description or content. See Grain Types for the full field reference.

How do I get, update, and delete grains?

Use get(hash) for lookup, supersede(old_hash, type, fields) for immutable updates, and forget(hash) for deletion.

from areev import Areev

areev = Areev()

# Get a grain by its content-address hash
grain = areev.get("a3f8c1...")

# Supersede: creates a new version linked to the original
new_hash = areev.supersede("a3f8c1...", "belief", {
    "object": "tea",
    "confidence": 0.99
})

# Delete a grain
areev.forget("a3f8c1...")
import { Areev } from "@areev/client";

const areev = new Areev();

const grain = await areev.get("a3f8c1...");
const newHash = await areev.supersede("a3f8c1...", "belief", {
    object: "tea",
    confidence: 0.99,
});
await areev.forget("a3f8c1...");
use areev_client::Areev;
use serde_json::json;

let areev = Areev::from_env();

let grain = areev.get("a3f8c1...").await?;
let new_hash = areev.supersede("a3f8c1...", "belief", json!({
    "object": "tea",
    "confidence": 0.99
})).await?;
areev.forget("a3f8c1...").await?;

Supersede creates a new grain linked to the original in the version chain. The old grain is marked as superseded but remains in storage for auditability. Forget permanently deletes a grain. Both operations respect the sealed compliance policy — if the policy requires consent before deletion, the call will fail without it.

How do I use the low-level embedded client?

The Python SDK also provides PyO3 bindings that embed the Areev Rust engine directly in your Python process. Use this when you need local-only operation without a running server.

import areev

# Create a new GDPR-compliant database (local, no server needed)
db = areev.create("./my-data", policies=["gdpr"])

# Open an existing database
db = areev.open("./my-data")

# Create with encryption and multiple policies
db = areev.create(
    "./my-data",
    policies=["gdpr", "hipaa"],
    master_key=bytes.fromhex("a1b2c3d4..."),  # 32 bytes (64 hex chars)
    user="admin@company.com",
    vector_backend="usearch"  # "usearch" (default) or "faiss"
)

# Open with tuning parameters
db = areev.open(
    "./my-data",
    master_key=key_bytes,
    user="john",
    rrf_k=60.0,              # Reciprocal Rank Fusion constant
    recency_decay_days=14.0   # Half-life for recency scoring
)

The embedded client gives you zero-network-overhead access to the full Areev engine, including compliance checks, PII detection, and encryption — all running locally inside the Python process. This is the same engine that powers the server, exposed through PyO3 bindings.

The embedded client provides a larger API surface than the simplified Areev client: grain CRUD, recall with 15+ filter parameters, compliance operations (consent, erasure, export), PII detection, authorization tuples, and import/export.

import areev

db = areev.open("./my-data")

# Add and recall grains (same operations as the Areev client)
h = db.add("belief", {
    "subject": "john",
    "relation": "likes",
    "object": "coffee",
    "confidence": 0.95,
    "namespace": "prefs"
})

results = db.recall(
    query="preferences",
    subject="john",
    grain_type="belief",
    limit=10
)

# Compliance operations (not available in the simplified client)
db.grant_consent("john", "memory_storage")
proof = db.forget_user("john")
labels = db.detect_pii("Contact john@example.com at 555-0100")

# Authorization tuples (Zanzibar-style)
db.authz_write("user:john", "editor", "memory:prod")
allowed = db.authz_check("user:john", "editor", "memory:prod")

# Import/export .mg blobs
result = db.import_directory("/path/to/mg-files")

What exceptions can the embedded client raise?

All exceptions inherit from areev.AreevException. Catch specific subclasses for targeted error handling.

The exception hierarchy maps directly to the Rust engine’s error types. Each exception carries a descriptive message from the engine. The most common exceptions in practice are NotFoundError (grain hash does not exist), ConsentRequiredError (policy requires consent before the operation), and PolicyViolationError (write violates the sealed policy).

import areev

try:
    db = areev.open("./my-data")
    grain = db.get("nonexistent_hash")
except areev.NotFoundError:
    print("Grain does not exist")
except areev.ConsentRequiredError:
    print("User consent required before this operation")
except areev.PolicyViolationError:
    print("Operation violates the sealed policy")
except areev.CryptoError:
    print("Encryption key error (missing, destroyed, or invalid)")
except areev.AreevException as e:
    print(f"Other Areev error: {e}")
ExceptionRaised when
NotFoundErrorGrain hash or resource does not exist
ConsentRequiredErrorPolicy requires consent before the operation
PolicyViolationErrorWrite/delete violates the sealed policy
ProcessingRestrictedErrorUser has an active processing restriction
CryptoErrorKey missing, destroyed, or decryption failed
ValidationErrorInvalid hash format, missing required fields
StorageErrorDisk I/O or Fjall storage engine error
AlreadyExistsErrorDatabase or resource already exists
DatabaseNotFoundErrorNo database at the specified path
PolicyNotSealedErrorOpened a path with no sealed policy
PolicyDowngradeErrorRemoving a policy without providing a reason
  • HTTP REST — the REST API that the SDKs call under the hood
  • CLI — command-line interface for terminal usage
  • gRPC — high-performance binary protocol alternative
  • MCP — Model Context Protocol for AI agent integration