Skip to main content
You can import reference material into a Knowledge Base in two ways. The right choice depends on volume.

MCP tool

crystal_import_knowledge — for moderate amounts of material. Embedding and graph enrichment happen synchronously as part of the import.

HTTP bulk-insert

POST /api/knowledge-bases/:id/bulk-insert — for high-volume migrations. Rows are inserted immediately; embedding and enrichment run in the background.

Method 1: crystal_import_knowledge tool

Use the MCP tool when importing a few dozen chunks or fewer. Each chunk is embedded and graph-enriched as it is written, so results are immediately searchable.
{
  "tool": "crystal_import_knowledge",
  "arguments": {
    "knowledgeBaseId": "jx7k2m9p4n8q",
    "chunks": [
      {
        "title": "Rate limits",
        "content": "The capture endpoint accepts up to 60 requests per minute per API key.",
        "tags": ["api", "rate-limiting"]
      },
      {
        "title": "Authentication",
        "content": "All endpoints require an Authorization: Bearer header with a valid API key.",
        "tags": ["api", "auth"]
      }
    ]
  }
}
The tool maps to POST /api/knowledge-bases/:knowledgeBaseId/import under the hood. Embedding and salience scoring run synchronously, so larger batches take longer. For anything over a few hundred chunks, use the bulk-insert endpoint instead.

Method 2: HTTP bulk import

For large migrations — thousands of chunks or more — use the HTTP endpoints directly. The bulk-insert endpoint writes rows without blocking on embedding, so it completes quickly even for large payloads. Embedding and graph enrichment are scheduled automatically and finish in the background.

Full bulk import flow

1

Create a Knowledge Base

Create the KB first if you don’t have one yet.
curl -X POST https://your-deployment.convex.site/api/knowledge-bases \
  -H "Authorization: Bearer mc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Product documentation",
    "description": "Public-facing docs for the v2 API",
    "scope": "acme-corp"
  }'
{
  "knowledgeBaseId": "jx7k2m9p4n8q"
}
Save the returned knowledgeBaseId — you’ll need it for the import steps.
2

Import with embedding (normal ingest)

For moderate batches where you want chunks to be immediately searchable, use the /import endpoint. Embedding and enrichment run synchronously.
curl -X POST https://your-deployment.convex.site/api/knowledge-bases/jx7k2m9p4n8q/import \
  -H "Authorization: Bearer mc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "chunks": [
      {
        "content": "The capture endpoint stores a memory with the provided title and content.",
        "metadata": {
          "title": "POST /api/mcp/capture",
          "sourceUrl": "https://docs.acme.com/api/capture"
        }
      }
    ]
  }'
{
  "knowledgeBaseId": "jx7k2m9p4n8q",
  "importedCount": 1,
  "memoryIds": ["mem_abc123"],
  "memoryCount": 1,
  "totalChars": 76
}
3

Bulk insert (high-volume backfill)

For large datasets, use the /bulk-insert endpoint. Rows are written immediately without embedding overhead. Embedding and graph enrichment are automatically scheduled as background jobs.
curl -X POST https://your-deployment.convex.site/api/knowledge-bases/jx7k2m9p4n8q/bulk-insert \
  -H "Authorization: Bearer mc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "chunks": [
      {
        "title": "Quickstart guide",
        "content": "Install Memory Crystal with: curl -fsSL https://memorycrystal.ai/crystal | bash",
        "chunkIndex": 0,
        "totalChunks": 42
      },
      {
        "title": "Authentication overview",
        "content": "All API endpoints require an Authorization: Bearer header.",
        "chunkIndex": 1,
        "totalChunks": 42
      }
    ]
  }'
{
  "importedCount": 2,
  "memoryIds": ["mem_def456", "mem_ghi789"]
}
The bulk-insert endpoint accepts a maximum of 100 chunks per request. For larger datasets, split your payload into batches of 100 and send multiple requests.

Background enrichment

After bulk insert, embedding and graph backfill run automatically via background jobs. You don’t need to trigger these manually. The backfill scheduler retries automatically if the embedding provider is temporarily unavailable.
Freshly bulk-inserted chunks are not immediately searchable. Allow a few minutes after insert for the background embedding jobs to complete before querying the KB.

Scoping imports

When you create a Knowledge Base, you can set a scope to restrict access to a specific workspace, client, or agent lane. Chunks inherit the scope of their parent KB.
curl -X POST https://your-deployment.convex.site/api/knowledge-bases \
  -H "Authorization: Bearer mc_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Client-specific runbook",
    "scope": "client:globex"
  }'
Only agents operating in the client:globex channel will see this KB when listing or querying. KBs without a scope are visible to all your agents.
If you want a KB accessible only to a specific agent, set agentIds when creating it. The agentId is derived from the prefix of the channel string before the first colon — for example, my-agent:session-1 has agent ID my-agent.