API Reference

Complete reference for the Kybernesis Brain HTTP API.

Table of Contents

Base URL

Production API base URL:

terminal
https://api.kybernesis.ai

Staging API base URL:

terminal
https://staging-api.kybernesis.ai

All endpoints use HTTPS. HTTP requests are automatically redirected.

Authentication

Kybernesis uses API key authentication via Bearer tokens.

Obtaining an API Key

  1. Visit https://kybernesis.ai
  2. Open Settings with Cmd+A (or Ctrl+A)
  3. Navigate to "API Access" section
  4. Click "+ Generate New API Key"
  5. Enter key name and select permissions
  6. Copy and securely store the key (shown only once)

Using API Keys

Include the API key in the Authorization header:

terminal
Authorization: Bearer kb_YOUR_API_KEY_HERE

Note: The kb_ prefix is part of the API key format.

Example Request

terminal
curl -X POST https://api.kybernesis.ai/retrieval/hybrid \
  -H "Authorization: Bearer kb_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "orgId": "00000000-0000-0000-0000-000000000000",
    "query": "authentication patterns",
    "limit": 5
  }'

Note: Organization ID (orgId) is passed in the request body, not as a header.

Rate Limits

ResourceLimitWindow
API Requests1001 minute
Hybrid Search501 minute
Upload Size50 MBper file
Memories per Org100,000total

Rate Limit Headers

Responses include rate limit information:

terminal
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1698765432

Handling Rate Limits

When rate limited, API returns 429 Too Many Requests:

terminal
{
  "error": "Rate limit exceeded",
  "retryAfter": 32
}

Use exponential backoff:

terminal
async function retryWithBackoff(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000;
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
}

Error Handling

Standard Error Response

terminal
{
  "error": "Human-readable error message",
  "code": "ERROR_CODE",
  "details": {
    "field": "Specific validation error"
  }
}

HTTP Status Codes

CodeMeaningAction
200SuccessProcess response
202Accepted (async)Job queued, poll for status
400Bad RequestFix request parameters
401UnauthorizedCheck API key
404Not FoundVerify resource ID
429Rate LimitedRetry with backoff
500Server ErrorRetry or contact support
502Bad GatewayTransient error, retry

Common Error Codes

  • INVALID_PAYLOAD: Request body validation failed
  • MISSING_ORG_ID: Organization ID required
  • MEMORY_NOT_FOUND: Memory ID doesn't exist
  • CONNECTOR_NOT_CONFIGURED: OAuth credentials missing
  • QUEUE_UNAVAILABLE: Background processing temporarily down

Ingestion Endpoints

POST /ingest/chat

Store a chat message as a memory.

Request:

terminal
POST /ingest/chat
Content-Type: application/json

{
  "message": "Our API uses JWT tokens with 1-hour expiry and refresh token rotation.",
  "orgId": "00000000-0000-0000-0000-000000000000",
  "userId": "user_abc123",
  "priority": 0.7
}

Request Fields:

  • message (string, required): Message content (max 100KB)
  • orgId (string, required): Organization UUID
  • userId (string, required): User identifier
  • priority (number, optional): Priority 0-1 (default: 0.5)

Response (202 Accepted):

terminal
{
  "status": "accepted",
  "kind": "chat",
  "messageLength": 89,
  "chunkCount": 1,
  "preview": "Our API uses JWT tokens with 1-hour expiry...",
  "cacheKey": "chat-preview:org_123:uuid",
  "processingMode": "queued"
}

Processing:

  • Message processed asynchronously
  • Auto-tags extracted from content
  • Available in search within 5-30 seconds

POST /ingest/upload

Upload a document for ingestion.

Request:

terminal
POST /ingest/upload
Content-Type: multipart/form-data

file: <binary file data>
orgId: 00000000-0000-0000-0000-000000000000
userId: user_abc123
priority: 0.6

Form Fields:

  • file (file, required): Document file (PDF, TXT, MD, DOCX, etc.)
  • orgId (string, required): Organization UUID
  • userId (string, required): User identifier
  • fileKey (string, optional): Custom file key (defaults to UUID)
  • priority (number, optional): Priority 0-1 (default: 0.5)

Supported Formats:

CategoryExtensionsNotes
Text.txt, .md, .csv, .json, .xmlPlain text and structured data
Documents.pdf, .docx, .rtfFull text extraction
Code.js, .ts, .py, .go, .java, .rsSyntax-aware processing
Spreadsheets.xlsx, .csvTabular data extraction
Presentations.pptxExtracted text only

Response (202 Accepted):

terminal
{
  "status": "accepted",
  "kind": "upload",
  "filename": "architecture-decisions.pdf",
  "size": 1234567,
  "storageKey": "uploads/a1b2c3d4-uuid"
}

Processing:

  • Document converted to text format automatically
  • Auto-tags extracted from content
  • Available in search within 1-5 minutes (depending on file size)

Processing Status

Monitor ingestion job status:

terminal
GET /api/ingestion-jobs/{jobId}

Response:

terminal
{
  "jobId": "job_abc123",
  "status": "completed",
  "orgId": "00000000-0000-0000-0000-000000000000",
  "jobType": "upload",
  "createdAt": "2025-10-24T10:00:00Z",
  "completedAt": "2025-10-24T10:02:15Z",
  "memoryId": "550e8400-e29b-41d4-a716-446655440000"
}

Status Values:

  • queued: Waiting in queue
  • processing: Currently being processed
  • completed: Successfully stored
  • failed: Processing error (see error field)

Retrieval Endpoints

POST /retrieval/hybrid

Hybrid search combining vector similarity and metadata filters.

Request:

terminal
POST /retrieval/hybrid
Content-Type: application/json

{
  "orgId": "00000000-0000-0000-0000-000000000000",
  "query": "authentication flow design decisions",
  "limit": 10,
  "tags": ["authentication", "security"],
  "includeSummaries": true
}

Request Fields:

  • orgId (string, required): Organization UUID
  • query (string, required): Search query
  • limit (number, optional): Max results 1-50 (default: 10)
  • tags (array, optional): Filter by tags (AND logic)
  • includeSummaries (boolean, optional): Include summaries (default: true)

Response (200 OK):

terminal
{
  "results": [
    {
      "memoryId": "550e8400-e29b-41d4-a716-446655440000",
      "title": "OAuth 2.0 Authentication Flow",
      "summary": "Implemented refresh token rotation with 7-day expiry. Uses PKCE for mobile clients.",
      "content": "Full content of the memory...",
      "score": 0.92,
      "tags": ["authentication", "oauth", "security"],
      "source": "upload",
      "tier": "hot",
      "createdAt": "2025-10-15T14:30:00Z",
      "updatedAt": "2025-10-20T09:15:00Z"
    }
  ],
  "timing": {
    "vectorMs": 45,
    "metadataMs": 12,
    "totalMs": 57
  }
}

Scoring:

  • Score range: 0.0-1.0
  • Combines semantic similarity with metadata relevance
  • Tag matches boost relevance
  • Tier influences ranking: hot > warm > archive

Memory Management

GET /api/memories

List all memories with pagination.

Request:

terminal
GET /api/memories?orgId=00000000-0000-0000-0000-000000000000&limit=20&offset=0

Query Parameters:

  • orgId (string, required): Organization UUID
  • limit (number, optional): Page size 1-100 (default: 20)
  • offset (number, optional): Skip N results (default: 0)
  • tier (string, optional): Filter by tier: hot, warm, archive
  • source (string, optional): Filter by source: upload, chat, connector
  • tags (string, optional): Comma-separated tag filter

Response (200 OK):

terminal
{
  "memories": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "System Architecture Overview",
      "summary": "Microservices architecture with event-driven communication...",
      "tags": ["architecture", "design", "microservices"],
      "autoTags": ["architecture", "microservices"],
      "manualTags": ["design"],
      "source": "upload",
      "tier": "hot",
      "priority": 0.8,
      "decayScore": 0.1,
      "createdAt": "2025-10-15T14:30:00Z",
      "updatedAt": "2025-10-20T09:15:00Z",
      "lastAccessedAt": "2025-10-24T10:00:00Z"
    }
  ],
  "pagination": {
    "total": 1234,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  }
}

GET /api/memories/:id

Get a single memory by ID.

Request:

terminal
GET /api/memories/550e8400-e29b-41d4-a716-446655440000

Response (200 OK):

terminal
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "OAuth 2.0 Implementation",
  "summary": "Complete OAuth 2.0 flow with PKCE...",
  "content": "Full content...",
  "tags": ["authentication", "oauth", "security"],
  "autoTags": ["authentication", "oauth"],
  "manualTags": ["security"],
  "source": "upload",
  "tier": "hot",
  "priority": 0.85,
  "decayScore": 0.12,
  "metadata": {
    "filename": "oauth-implementation.pdf",
    "byteSize": 45678,
    "mimeType": "application/pdf"
  },
  "relationships": [
    {
      "memoryId": "660e8400-e29b-41d4-a716-446655440001",
      "relation": "related",
      "weight": 0.75,
      "sharedTags": ["authentication"]
    }
  ],
  "createdAt": "2025-10-15T14:30:00Z",
  "updatedAt": "2025-10-20T09:15:00Z",
  "lastAccessedAt": "2025-10-24T10:00:00Z"
}

PATCH /api/memories/:id

Update a memory's metadata.

Request:

terminal
PATCH /api/memories/550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{
  "title": "Updated Title",
  "manualTags": ["security", "production"],
  "isPinned": true
}

Updatable Fields:

  • title (string): Memory title
  • summary (string): Manual summary override
  • manualTags (array): User-assigned tags (merged with autoTags)
  • isPinned (boolean): Pin to hot tier regardless of score
  • metadata (object): Arbitrary metadata

Response (200 OK):

terminal
{
  "memoryId": "550e8400-e29b-41d4-a716-446655440000",
  "updated": true,
  "tags": ["authentication", "oauth", "security", "production"]
}

DELETE /api/memories/:id

Delete a memory permanently.

Request:

terminal
DELETE /api/memories/550e8400-e29b-41d4-a716-446655440000

Response (200 OK):

terminal
{
  "deleted": true,
  "memoryId": "550e8400-e29b-41d4-a716-446655440000",
  "chunksDeleted": 3,
  "embeddingsDeleted": 3,
  "edgesDeleted": 2
}

Effects:

  • Permanently deletes the memory and all associated data
  • Removes all relationship connections to other memories
  • Cannot be undone—consider archive tier for soft deletion

Tag Operations

POST /api/tags/rename

Rename a tag across all memories.

Request:

terminal
POST /api/tags/rename
Content-Type: application/json

{
  "orgId": "00000000-0000-0000-0000-000000000000",
  "oldTag": "auth",
  "newTag": "authentication"
}

Response (200 OK):

terminal
{
  "renamed": true,
  "memoriesAffected": 42,
  "oldTag": "auth",
  "newTag": "authentication"
}

POST /api/tags/merge

Merge multiple tags into one.

Request:

terminal
POST /api/tags/merge
Content-Type: application/json

{
  "orgId": "00000000-0000-0000-0000-000000000000",
  "sourceTags": ["oauth", "oauth2", "oauth-2.0"],
  "targetTag": "oauth"
}

Response (200 OK):

terminal
{
  "merged": true,
  "memoriesAffected": 67,
  "sourceTags": ["oauth", "oauth2", "oauth-2.0"],
  "targetTag": "oauth"
}

DELETE /api/tags/:tag

Delete a tag from all memories.

Request:

terminal
DELETE /api/tags/deprecated-tag?orgId=00000000-0000-0000-0000-000000000000

Response (200 OK):

terminal
{
  "deleted": true,
  "tag": "deprecated-tag",
  "memoriesAffected": 12
}

POST /api/tags/:tag/color

Set display color for a tag in UI.

Request:

terminal
POST /api/tags/authentication/color
Content-Type: application/json

{
  "orgId": "00000000-0000-0000-0000-000000000000",
  "color": "#3B82F6"
}

Response (200 OK):

terminal
{
  "tag": "authentication",
  "color": "#3B82F6"
}

Connector Management

GET /connectors

List all configured connectors.

Request:

terminal
GET /connectors?orgId=00000000-0000-0000-0000-000000000000

Response (200 OK):

terminal
{
  "connectors": [
    {
      "id": "conn_google_drive_001",
      "type": "google_drive",
      "displayName": "Google Drive",
      "status": "connected",
      "connected": true,
      "syncing": false,
      "cursor": "page_token_xyz",
      "lastSyncedAt": "2025-10-24T08:00:00Z",
      "lastSyncStatus": "completed",
      "itemsProcessed": 45,
      "itemsFailed": 0,
      "credentialUpdatedAt": "2025-10-15T10:30:00Z",
      "createdAt": "2025-10-01T12:00:00Z",
      "updatedAt": "2025-10-24T08:00:00Z"
    }
  ]
}

Connector Status Values:

  • pending: OAuth not completed
  • connected: Ready to sync
  • syncing: Currently syncing
  • queued: Sync job queued
  • error: Last sync failed (see error field)

POST /connectors/:id/sync

Manually trigger a connector sync.

Request:

terminal
POST /connectors/conn_google_drive_001/sync?orgId=00000000-0000-0000-0000-000000000000

Response (200 OK):

terminal
{
  "status": "queued",
  "connector": {
    "id": "conn_google_drive_001",
    "type": "google_drive",
    "displayName": "Google Drive",
    "status": "queued"
  }
}

Processing:

  • Sync job processed asynchronously within 1-5 minutes
  • New documents are added as memories
  • Existing documents updated if modified since last sync

OAuth Flows

Google Drive

Start OAuth:

terminal
GET /connectors/google-drive/oauth/start?orgId=YOUR_ORG_ID&redirectTo=https://kybernesis.com/connectors

Callback (automatic):

terminal
GET /connectors/google-drive/oauth/callback?code=AUTH_CODE&state=STATE_TOKEN

Notion

Start OAuth:

terminal
GET /connectors/notion/oauth/start?orgId=YOUR_ORG_ID&redirectTo=https://kybernesis.com/connectors

Callback (automatic):

terminal
GET /connectors/notion/oauth/callback?code=AUTH_CODE&state=STATE_TOKEN

Note: OAuth flows are typically initiated from the web console UI, not programmatically.

Telemetry

GET /telemetry/sleep

View sleep agent execution history.

Request:

terminal
GET /telemetry/sleep?orgId=00000000-0000-0000-0000-000000000000&limit=10

Response (200 OK):

terminal
{
  "runs": [
    {
      "runId": "sleep_run_abc123",
      "orgId": "00000000-0000-0000-0000-000000000000",
      "status": "completed",
      "triggeredAt": "2025-10-24T10:00:00Z",
      "completedAt": "2025-10-24T10:03:45Z",
      "durationMs": 225000,
      "tasksCompleted": 127,
      "tasksFailed": 3,
      "notes": "Adjusted 50 memories, created 12 relationships, applied 8 tier changes"
    }
  ]
}

GET /telemetry/events

Query telemetry events.

Request:

terminal
GET /telemetry/events?orgId=00000000-0000-0000-0000-000000000000&eventType=retrieval.hybrid.success&limit=50

Query Parameters:

  • orgId (string, required): Organization UUID
  • eventType (string, optional): Filter by event type
  • limit (number, optional): Max results (default: 100)

Response (200 OK):

terminal
{
  "events": [
    {
      "eventId": "evt_abc123",
      "orgId": "00000000-0000-0000-0000-000000000000",
      "eventType": "retrieval.hybrid.success",
      "timestamp": "2025-10-24T10:15:30Z",
      "value": 57,
      "attributes": {
        "resultCount": 10,
        "queryLength": 42,
        "vectorMs": 45,
        "metadataMs": 12
      }
    }
  ]
}

MCP Endpoints

GET /mcp

MCP server manifest (for AI agent discovery).

Request:

terminal
GET /mcp

Response (200 OK):

terminal
{
  "name": "Kybernesis Brain",
  "version": "1.0.0",
  "description": "AI memory orchestration and retrieval platform",
  "protocol": "mcp",
  "server": {
    "url": "https://api.kybernesis.ai",
    "endpoints": {
      "health": "https://api.kybernesis.ai/health",
      "mcp": "https://api.kybernesis.ai/mcp",
      "rpc": "https://api.kybernesis.ai/rpc/:tool"
    }
  },
  "auth": {
    "type": "bearer",
    "required": false
  },
  "tools": [
    {
      "name": "addMemory",
      "description": "Store a new memory",
      "endpoint": "/rpc/addMemory",
      "method": "POST"
    },
    {
      "name": "searchMemory",
      "description": "Search memories using hybrid search",
      "endpoint": "/rpc/searchMemory",
      "method": "POST"
    }
  ]
}

POST /rpc/:tool

Execute MCP tool (used by AI agents).

Example: addMemory:

terminal
POST /rpc/addMemory
Content-Type: application/json

{
  "orgId": "00000000-0000-0000-0000-000000000000",
  "content": "Production database URL: postgres://prod.db.kybernesis.ai:5432",
  "title": "Production DB Config",
  "tags": ["database", "production"],
  "source": "mcp"
}

Response (200 OK):

terminal
{
  "memoryId": "550e8400-e29b-41d4-a716-446655440000",
  "chunkId": "660e8400-e29b-41d4-a716-446655440001",
  "status": "stored"
}

See MCP Setup Guide for complete MCP tool documentation.

Code Examples

JavaScript / TypeScript

terminal
import axios from 'axios';

const API_KEY = 'your-api-key-here';
const ORG_ID = '00000000-0000-0000-0000-000000000000';
const BASE_URL = 'https://api.kybernesis.ai';

const api = axios.create({
  baseURL: BASE_URL,
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'x-org-id': ORG_ID,
    'Content-Type': 'application/json'
  }
});

// Store a memory
async function storeMemory(content: string, tags: string[]) {
  const response = await api.post('/ingest/chat', {
    message: content,
    orgId: ORG_ID,
    userId: 'user_123',
    priority: 0.7
  });
  return response.data;
}

// Search memories
async function searchMemories(query: string, limit: number = 10) {
  const response = await api.post('/retrieval/hybrid', {
    orgId: ORG_ID,
    query,
    limit,
    includeSummaries: true
  });
  return response.data.results;
}

// List memories
async function listMemories(limit: number = 20, offset: number = 0) {
  const response = await api.get('/api/memories', {
    params: { orgId: ORG_ID, limit, offset }
  });
  return response.data.memories;
}

// Update memory
async function updateMemory(memoryId: string, updates: any) {
  const response = await api.patch(`/api/memories/${memoryId}`, updates);
  return response.data;
}

// Delete memory
async function deleteMemory(memoryId: string) {
  const response = await api.delete(`/api/memories/${memoryId}`);
  return response.data;
}

// Example usage
(async () => {
  // Store a memory
  const stored = await storeMemory(
    'Use bcrypt with 12 rounds for password hashing',
    ['security', 'authentication']
  );
  console.log('Stored:', stored);

  // Search for related memories
  const results = await searchMemories('password hashing best practices', 5);
  console.log('Found:', results.length, 'memories');

  // Update memory tags
  await updateMemory(results[0].memoryId, {
    manualTags: ['security', 'authentication', 'best-practices']
  });
})();

Python

terminal
import requests

API_KEY = 'your-api-key-here'
ORG_ID = '00000000-0000-0000-0000-000000000000'
BASE_URL = 'https://api.kybernesis.ai'

class KybernesisClient:
    def __init__(self, api_key: str, org_id: str):
        self.base_url = BASE_URL
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'x-org-id': org_id,
            'Content-Type': 'application/json'
        }

    def store_memory(self, content: str, tags: list = None, priority: float = 0.5):
        """Store a new memory"""
        response = requests.post(
            f'{self.base_url}/ingest/chat',
            headers=self.headers,
            json={
                'message': content,
                'orgId': ORG_ID,
                'userId': 'user_123',
                'priority': priority
            }
        )
        response.raise_for_status()
        return response.json()

    def search_memories(self, query: str, limit: int = 10, tags: list = None):
        """Search memories using hybrid search"""
        payload = {
            'orgId': ORG_ID,
            'query': query,
            'limit': limit,
            'includeSummaries': True
        }
        if tags:
            payload['tags'] = tags

        response = requests.post(
            f'{self.base_url}/retrieval/hybrid',
            headers=self.headers,
            json=payload
        )
        response.raise_for_status()
        return response.json()['results']

    def list_memories(self, limit: int = 20, offset: int = 0, tier: str = None):
        """List memories with pagination"""
        params = {
            'orgId': ORG_ID,
            'limit': limit,
            'offset': offset
        }
        if tier:
            params['tier'] = tier

        response = requests.get(
            f'{self.base_url}/api/memories',
            headers=self.headers,
            params=params
        )
        response.raise_for_status()
        return response.json()['memories']

    def update_memory(self, memory_id: str, **updates):
        """Update memory metadata"""
        response = requests.patch(
            f'{self.base_url}/api/memories/{memory_id}',
            headers=self.headers,
            json=updates
        )
        response.raise_for_status()
        return response.json()

    def delete_memory(self, memory_id: str):
        """Delete a memory permanently"""
        response = requests.delete(
            f'{self.base_url}/api/memories/{memory_id}',
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()

# Example usage
client = KybernesisClient(API_KEY, ORG_ID)

# Store a memory
stored = client.store_memory(
    'Always validate user input before database queries to prevent SQL injection',
    tags=['security', 'database'],
    priority=0.8
)
print(f"Stored memory: {stored['memoryId']}")

# Search for related memories
results = client.search_memories('SQL injection prevention', limit=5)
print(f"Found {len(results)} related memories")

# Update memory
client.update_memory(results[0]['memoryId'], isPinned=True)

cURL

terminal
# Store a memory
curl -X POST https://api.kybernesis.ai/ingest/chat \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-org-id: YOUR_ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Use environment variables for all sensitive configuration",
    "orgId": "00000000-0000-0000-0000-000000000000",
    "userId": "user_123",
    "priority": 0.7
  }'

# Search memories
curl -X POST https://api.kybernesis.ai/retrieval/hybrid \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-org-id: YOUR_ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "orgId": "00000000-0000-0000-0000-000000000000",
    "query": "environment variables security",
    "limit": 5
  }'

# List memories
curl -X GET "https://api.kybernesis.ai/api/memories?orgId=YOUR_ORG_ID&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-org-id: YOUR_ORG_ID"

# Update memory
curl -X PATCH https://api.kybernesis.ai/api/memories/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-org-id: YOUR_ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "manualTags": ["security", "configuration", "production"]
  }'

# Delete memory
curl -X DELETE https://api.kybernesis.ai/api/memories/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-org-id: YOUR_ORG_ID"

Next Steps

Support