MemoryRouterMemoryRouter

Transfer and Graft

Copy memories between Memory Keys. Transfer all memories, or graft only the memories that match a search.

Transfer and Graft

Transfer and Graft copy memories from one Memory Key to another.

Both operations are non-destructive. The source vault is never changed.

Use them when you need to move memory between keys:

  • Transfer: copy every memory from one key to another. Use this for migrations, backups, and full vault duplication.
  • Graft: search one key, filter by similarity score, and copy only matching memories to another key. Use this to seed a team or org key from a personal key without copying unrelated memories.

The authenticated key is always the source key. destination_key is the key that receives the copied memories.

Base URL: https://api.memoryrouter.ai


Always start with dry_run: true.

A dry run returns the memories that would be copied, including snippets, scores for graft, count, and estimated tokens. It does not write to the destination.

curl -X POST https://api.memoryrouter.ai/v1/memory/graft \
  -H "Authorization: Bearer $SOURCE_MEMORY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_key": "mk_destination",
    "queries": ["architecture decisions", "deployment process", "customer context"],
    "threshold": 0.5,
    "limit": 50,
    "dry_run": true
  }'

Response:

{
  "dry_run": true,
  "operation": "graft",
  "source_key": "mk_abc…123456",
  "destination_key": "mk_def…789012",
  "queries": ["architecture decisions", "deployment process", "customer context"],
  "threshold": 0.5,
  "limit": 50,
  "count": 3,
  "estimated_tokens": 420,
  "memories": [
    {
      "id": 184,
      "snippet": "[USER] We decided to keep auth in the worker and avoid client-side provider keys...",
      "role": "user",
      "timestamp": 1781191200000,
      "score": 0.78,
      "estimated_tokens": 86
    }
  ]
}

If the preview looks right, send the same request with dry_run: false or omit dry_run.


Transfer all memories

POST /v1/memory/transfer

Copies every memory in the source key's core vault to the destination key.

curl -X POST https://api.memoryrouter.ai/v1/memory/transfer \
  -H "Authorization: Bearer $SOURCE_MEMORY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_key": "mk_destination",
    "dry_run": true
  }'

Request body

FieldTypeRequiredDescription
destination_keystringYesWritable Memory Key that receives the copied memories.
dry_runbooleanNoIf true, preview only. No memories are written.
embeddingsstringNoEmbedding model vault to transfer. Defaults to the API default.

Successful write response

{
  "dry_run": false,
  "operation": "transfer",
  "source_key": "mk_abc…123456",
  "destination_key": "mk_def…789012",
  "copied": 128,
  "deduped_or_skipped": 0,
  "failed": 0,
  "estimated_tokens": 18420,
  "provenance": {
    "origin_key": "mk_abc…123456",
    "transferred_at": "2026-06-11T17:30:00.000Z"
  }
}

Graft selected memories

POST /v1/memory/graft

Runs one or more semantic searches against the source key. Memories with a score greater than or equal to threshold are copied to the destination key.

curl -X POST https://api.memoryrouter.ai/v1/memory/graft \
  -H "Authorization: Bearer $SOURCE_MEMORY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destination_key": "mk_org_team",
    "queries": [
      "business strategy for MemoryRouter",
      "Claude Code integration decisions",
      "customer onboarding lessons"
    ],
    "threshold": 0.55,
    "limit": 75,
    "dry_run": false
  }'

Request body

FieldTypeRequiredDescription
destination_keystringYesWritable Memory Key that receives the copied memories.
queriesstring[]YesOne or more semantic search queries. Empty arrays are rejected.
thresholdnumberNoMinimum similarity score from 0 to 1. Defaults to 0.5.
limitnumberNoMax results per query. Defaults to 50. Max 500.
dry_runbooleanNoIf true, preview only. No memories are written.
embeddingsstringNoEmbedding model vault to search and graft. Defaults to the API default.

Successful write response

{
  "dry_run": false,
  "operation": "graft",
  "source_key": "mk_abc…123456",
  "destination_key": "mk_org…789012",
  "queries": [
    "business strategy for MemoryRouter",
    "Claude Code integration decisions",
    "customer onboarding lessons"
  ],
  "threshold": 0.55,
  "limit": 75,
  "copied": 24,
  "deduped_or_skipped": 3,
  "failed": 0,
  "estimated_tokens": 6120,
  "provenance": {
    "origin_key": "mk_abc…123456",
    "transferred_at": "2026-06-11T17:30:00.000Z"
  }
}

Threshold guidance

Start broad, then tighten.

ThresholdBehaviorUse
0.4 to 0.5Broad recallFirst-pass discovery, messy personal vaults, exploratory dry runs
0.5 to 0.65BalancedTeam/org seeding from personal memory
0.65 and upStrictSensitive grafts where precision matters more than coverage

Use multiple focused queries instead of one vague query. For example, use deployment process, customer objections, and pricing decisions instead of business stuff.


Dedupe behavior

Transfer and Graft are safe to re-run.

The destination vault dedupes by memory content hash. If the same memory is copied again, it is skipped instead of written a second time. The response reports skipped duplicates in deduped_or_skipped.

This makes retry safe after partial failure.


Provenance behavior

Copied memories are stamped with provenance metadata:

  • origin_key: a safe truncated form of the source key
  • transferred_at: the time the copy operation wrote the memory

Provenance is stored as metadata on the copied memory. It is not added to the memory text, so it does not pollute future retrieval context.


Permissions

The authenticated key is the source key.

Source requirements:

  • The source key must be valid and active.
  • :read source keys are allowed because they can read memory.
  • :off source keys are rejected.

Destination requirements:

  • destination_key must be valid and active.
  • destination_key must be writable.
  • mk_xxx:read is rejected.
  • mk_xxx:off is rejected.
  • Source and destination cannot be the same key.

Any key can copy to any other key if the caller has the source key and the destination key is writable. There are no personal/org walls.


Errors

StatusWhen
400Missing or invalid destination_key, same source and destination, empty graft queries, invalid threshold, read-only destination, off destination
401Missing or invalid source key auth
403Source key has memory disabled with :off
413Source vault is too large for a single transfer request
500Unexpected transfer or graft failure

Example same-key error:

{
  "error": "destination_key must be different from the source key"
}

When to use each

Use Transfer when:

  • You are migrating a key.
  • You want a full backup copy.
  • You are consolidating all memories into a new key.

Use Graft when:

  • You want to seed a team or org key from personal memory.
  • You need only business memories, project memories, or client memories.
  • You want to avoid copying unrelated personal context.

For team onboarding, the best pattern is:

  1. Each team member runs a dry-run graft from their personal key into the shared org key.
  2. They tune queries and threshold until the preview is clean.
  3. They run the real graft.
  4. The org key starts useful on day one.

On this page