Skip to content

Migration from VectorDB

beginner

Move from Pinecone, Weaviate, or ChromaDB to Engramma. Map concepts, export data, and start using cognitive memory in under an hour.

What you'll build

A migration script that moves your vectors and metadata from your current vector database to Engramma — plus a concept mapping to understand what you gain.

Prerequisites

RequirementDetails
AccountStarter tier or above (for bulk import)
API keyFrom your dashboard
HTTP clientcurl, Python requests, or JavaScript fetch
Existing dataAn active Pinecone, Weaviate, or ChromaDB instance
Time~30-60 minutes (depends on data volume)

Concept mapping

Your existing knowledge translates directly:

Vector DB conceptEngramma equivalentWhat changes
Vector/EmbeddingPatternEngramma also stores text, not just vectors
Index/CollectionMemory SpaceOne per API key (or use metadata for namespaces)
NamespaceMetadata tagsUse metadata fields to segment data
Cosine similaritysimilarity scoreReturned on each result (0-1 range)
UpsertStoreReturns pattern_id plus usage stats
QueryRetrieveReturns similarity + text + metadata
MetadataMetadataCarries over directly
ConsolidationNew: memory quality improves over time
Duplicate mergingNew: automatic deduplication via threshold

Migration strategies

There are two paths depending on what data you have:

StrategyEndpointWhen to use
Text-based (preferred)/v1/memory/text/storeYou have the original text — let Engramma re-embed with its own 384-dim model
Embedding-based (fallback)/v1/memory/storeYou only have pre-computed embeddings and no source text
Tip

Prefer text-based migration whenever possible. Engramma uses a 384-dimension embedding model internally. Re-embedding your text ensures optimal retrieval quality.

Steps

1

Export from your current database

Extract your vectors, text, and metadata from Pinecone, Weaviate, or ChromaDB.
2

Choose a migration strategy

If you have raw text, use the text-based path (POST /v1/memory/text/batch-store). If you only have embeddings, use the embedding-based path (POST /v1/memory/batch/store).
3

Import into Engramma

Batch-store your data into Engramma using HTTP requests.
4

Consolidate

Run consolidation and merge-duplicates to let the engine organize and deduplicate.
5

Validate

Run your existing queries against Engramma and compare results.

Text-based migration (preferred)

Use this when you have the original text content. Engramma will re-embed each item with its own model.

Single item store

import requests

API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"

response = requests.post(
    f"{BASE_URL}/v1/memory/text/store",
    headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
    json={
        "text": "Our deployment process uses blue-green deploys on Kubernetes.",
        "metadata": {"source": "wiki", "category": "devops"}
    }
)

result = response.json()
# {
#   "success": true,
#   "pattern_id": "pat_abc123",
#   "embedding_dim": 384,
#   "patterns_used": 42,
#   "patterns_limit": 10000
# }
print(f"Stored as {result['pattern_id']}")

Batch store (up to 50 items per request)

import requests

API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"

items = [
    {"text": "Q2 revenue was $4.2M, up 18% YoY.", "metadata": {"type": "finance"}},
    {"text": "Main risk: supply chain delays in APAC region.", "metadata": {"type": "risk"}},
    {"text": "Billing system owned by the Payments team.", "metadata": {"type": "ownership"}}
]

response = requests.post(
    f"{BASE_URL}/v1/memory/text/batch-store",
    headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
    json={"items": items}
)

result = response.json()
# {
#   "stored": 3,
#   "failed": 0,
#   "pattern_ids": ["pat_abc123", "pat_def456", "pat_ghi789"],
#   "latency_ms": 45.2
# }
print(f"Stored {result['stored']} items in {result['latency_ms']}ms")

Embedding-based migration (fallback)

Use this when you only have pre-computed embeddings without the original text. This uses the low-level vector endpoints that accept raw key/value arrays.

Warning

The low-level endpoints (/v1/memory/store, /v1/memory/batch/store) accept raw embedding vectors. You will not be able to use the text retrieval endpoint for these entries — use /v1/memory/query with a raw embedding vector instead.

import requests

API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"

# Single raw embedding store
embedding = [0.12, -0.34, 0.56, ...]  # your pre-computed vector
value = [0.12, -0.34, 0.56, ...]       # can be the same or associated data

response = requests.post(
    f"{BASE_URL}/v1/memory/store",
    headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
    json={"key": embedding, "value": value}
)

print(response.json())

Full migration from Pinecone

import os
import pinecone
import requests

# Source: Pinecone
pinecone.init(api_key=os.environ["PINECONE_API_KEY"])
index = pinecone.Index("my-index")

# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Export from Pinecone (paginated)
results = index.query(
    vector=[0.0] * 1536,  # dummy vector to fetch all
    top_k=100,
    include_metadata=True,
    include_values=True,
    namespace=""
)

# Separate text-based vs embedding-only items
text_items = []
embedding_items = []

for match in results.matches:
    text = match.metadata.get("text", "")
    if text:
        text_items.append({
            "text": text,
            "metadata": {**match.metadata, "source": "pinecone_migration"}
        })
    else:
        embedding_items.append({
            "key": match.values,
            "value": match.values
        })

# Batch-store text items (50 at a time)
for i in range(0, len(text_items), 50):
    batch = text_items[i:i+50]
    resp = requests.post(
        f"{BASE_URL}/v1/memory/text/batch-store",
        headers=HEADERS,
        json={"items": batch}
    )
    result = resp.json()
    print(f"Text batch: stored {result['stored']}, failed {result['failed']}")

# Store raw embeddings one by one (low-level endpoint)
for item in embedding_items:
    requests.post(
        f"{BASE_URL}/v1/memory/store",
        headers=HEADERS,
        json=item
    )

print(f"Migrated {len(text_items)} text items + {len(embedding_items)} embeddings from Pinecone")

Full migration from Weaviate

import os
import weaviate
import requests

# Source: Weaviate
weaviate_client = weaviate.Client("http://localhost:8080")

# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Export from Weaviate
result = weaviate_client.query.get(
    "Document", ["content", "title", "category"]
).with_limit(1000).do()

documents = result["data"]["Get"]["Document"]

# Build batch items
items = []
for doc in documents:
    items.append({
        "text": doc["content"],
        "metadata": {
            "title": doc.get("title"),
            "category": doc.get("category"),
            "source": "weaviate_migration"
        }
    })

# Batch-store (50 at a time)
for i in range(0, len(items), 50):
    batch = items[i:i+50]
    resp = requests.post(
        f"{BASE_URL}/v1/memory/text/batch-store",
        headers=HEADERS,
        json={"items": batch}
    )
    result = resp.json()
    print(f"Batch {i//50 + 1}: stored {result['stored']}, failed {result['failed']}")

print(f"Migrated {len(documents)} documents from Weaviate")

Full migration from ChromaDB

import os
import chromadb
import requests

# Source: ChromaDB
chroma = chromadb.Client()
collection = chroma.get_collection("my-collection")

# Destination: Engramma
API_KEY = os.environ["ENGRAMMA_API_KEY"]
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Export from ChromaDB
results = collection.get(
    include=["documents", "metadatas", "embeddings"]
)

# Separate text-based vs embedding-only items
text_items = []
embedding_items = []

for i, doc in enumerate(results["documents"]):
    metadata = results["metadatas"][i] if results["metadatas"] else {}
    metadata["source"] = "chromadb_migration"

    if doc:
        text_items.append({"text": doc, "metadata": metadata})
    elif results["embeddings"] and results["embeddings"][i]:
        embedding_items.append({
            "key": results["embeddings"][i],
            "value": results["embeddings"][i]
        })

# Batch-store text items (50 at a time)
for i in range(0, len(text_items), 50):
    batch = text_items[i:i+50]
    resp = requests.post(
        f"{BASE_URL}/v1/memory/text/batch-store",
        headers=HEADERS,
        json={"items": batch}
    )
    result = resp.json()
    print(f"Text batch: stored {result['stored']}, failed {result['failed']}")

# Store raw embeddings (low-level endpoint)
for item in embedding_items:
    requests.post(
        f"{BASE_URL}/v1/memory/store",
        headers=HEADERS,
        json=item
    )

print(f"Migrated {len(text_items)} text items + {len(embedding_items)} embeddings from ChromaDB")

Post-migration consolidation

After importing all data, run consolidation to organize memories and merge near-duplicates:

import requests

API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Step 1: Full consolidation (reorganizes and strengthens patterns)
resp = requests.post(
    f"{BASE_URL}/v1/memory/consolidation/sleep",
    headers=HEADERS,
    json={"mode": "full"}
)
print("Consolidation:", resp.json())

# Step 2: Merge near-duplicates (threshold 0-1, lower = more aggressive)
resp = requests.post(
    f"{BASE_URL}/v1/memory/consolidation/merge-duplicates",
    headers=HEADERS,
    json={"threshold": 0.85}
)
print("Merge duplicates:", resp.json())

Validating your migration

After importing and consolidating, verify that your existing queries work as expected:

import requests

API_KEY = "your-engramma-api-key"
BASE_URL = "https://api.engramma-memory.com"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}

# Run your most important queries and compare
test_queries = [
    "What is our deployment process?",
    "Who is responsible for the billing system?",
    "What are the main risks in Q2?"
]

for query in test_queries:
    resp = requests.post(
        f"{BASE_URL}/v1/memory/text/retrieve",
        headers=HEADERS,
        json={"query": query, "top_k": 5}
    )
    data = resp.json()
    # {
    #   "results": [
    #     {"text": "...", "metadata": {...}, "similarity": 0.94, "pattern_id": "pat_..."},
    #     ...
    #   ],
    #   "latency_ms": 2.3
    # }
    print(f"\nQuery: {query} ({data['latency_ms']}ms)")
    for r in data["results"]:
        print(f"  [{r['similarity']:.2f}] {r['text'][:80]}...")

What you gain after migration

Before (Vector DB)After (Engramma)
Cosine similarity onlysimilarity score with optimized 384-dim embeddings
Static storageSelf-improving via consolidation cycles
Manual deduplicationAutomatic merging via merge-duplicates endpoint
No lifecycle managementFull consolidation with sleep/merge modes
Separate embedding pipelineBuilt-in embedding (just send text)
Custom infrastructureManaged API with usage tracking (patterns_used/patterns_limit)
Tip

After migration, run consolidation periodically. The merge-duplicates endpoint with a threshold of 0.85 is a good starting point — it will merge items that are near-identical without being too aggressive.

Next steps