logicspike/docs

AI Brain

Phase 4: API Specification — AI Brain

Last Updated: 2026-04-03 Status: Draft


1. Service Overview

Property Value
Service Owner apps/brain-service
Base URL https://api.logicspike.com/brain (via Gateway)
Internal Microservice brain-service.logicspike.workers.dev
Gateway Key Header x-gateway-key
Auth RS256 JWT via Gateway

2. Authentication Requirements

Domain Auth Type Header
Chat (Copilot) JWT (user session) Authorization: Bearer <token>
Insights JWT (user session) Authorization: Bearer <token>
Memory (admin) JWT + admin permission Authorization: Bearer <token>
Usage JWT (user session) Authorization: Bearer <token>
Internal (Cron, Queues) Gateway key only x-gateway-key: <key>

3. Endpoints by Domain

3.1 Copilot Chat (Core)

💬 Send Message (Streaming)

The primary endpoint. Accepts a user message and returns a streaming response via SSE.

POST /brain/chat
Content-Type: application/json
Accept: text/event-stream

Request Body:

{
  "conversation_id": "conv_abc123",
  "message": "Why did my blog traffic drop this week?",
  "attachments": []
}
Field Type Required Description
conversation_id UUID Existing conversation to continue. If omitted, creates a new conversation.
message String User's natural language input. Max 4000 characters.
attachments Array Future: images, files. Currently unused.

Response (SSE Stream):

event: token
data: {"text": "Based on "}
 
event: token
data: {"text": "your blog analytics, "}
 
event: tool_call
data: {"name": "blog.get_analytics", "params": {"range": "7d"}}
 
event: tool_result
data: {"name": "blog.get_analytics", "result": {"views": 45, "previous": 120}}
 
event: token
data: {"text": "your traffic dropped from 120 to 45 views this week. "}
 
event: done
data: {"conversation_id": "conv_abc123", "message_id": "msg_xyz789", "usage": {"input_tokens": 2500, "output_tokens": 180, "cost_usd": 0.0042}, "decision_id": "dec_456"}

SSE Event Types:

Event Payload Description
token { text: string } A streamed text token
tool_call { name: string, params: object } Agent is calling a service tool
tool_result { name: string, result: object } Tool execution result
thinking { text: string } Agent's reasoning (optional, configurable)
done { conversation_id, message_id, usage, decision_id } Stream complete
error { code: string, message: string } Error during processing

Error Codes:

Code HTTP Description
RATE_LIMITED 429 Tenant exceeded plan's AI interaction limit
CONVERSATION_NOT_FOUND 404 Invalid conversation_id
MESSAGE_TOO_LONG 400 Message exceeds 4000 character limit
PROVIDER_UNAVAILABLE 503 All LLM providers are down
PERMISSION_DENIED 403 User lacks required permission

🔄 Confirm Action

When an agent requests user confirmation for a destructive action, the client sends approval/denial.

POST /brain/chat/confirm
Content-Type: application/json

Request Body:

{
  "conversation_id": "conv_abc123",
  "decision_id": "dec_456",
  "confirmed": true
}
Field Type Required Description
conversation_id UUID Active conversation
decision_id UUID The pending decision to confirm/deny
confirmed Boolean true to execute, false to cancel

Response:

{
  "status": "executed",
  "tool_result": {
    "name": "blog.delete_posts",
    "result": { "deleted_count": 3 }
  }
}

3.2 Conversations

📋 List Conversations

GET /brain/conversations?status=active&limit=20&offset=0

Query Parameters:

Param Type Default Description
status Enum all Filter: active, idle, closed, all
limit Integer 20 Max results (1–100)
offset Integer 0 Pagination offset

Response:

{
  "conversations": [
    {
      "id": "conv_abc123",
      "title": "Blog traffic analysis",
      "status": "active",
      "message_count": 12,
      "last_message_at": "2026-04-03T10:30:00Z",
      "started_at": "2026-04-03T10:15:00Z"
    }
  ],
  "total": 45,
  "limit": 20,
  "offset": 0
}

📜 Get Conversation History

GET /brain/conversations/:id/messages?limit=50&before=<message_id>

Query Parameters:

Param Type Default Description
limit Integer 50 Max messages (1–100)
before UUID Cursor-based pagination — messages before this ID

Response:

{
  "messages": [
    {
      "id": "msg_001",
      "role": "user",
      "content": "Why did my traffic drop?",
      "created_at": "2026-04-03T10:15:00Z"
    },
    {
      "id": "msg_002",
      "role": "assistant",
      "content": "Based on your analytics...",
      "agent_type": "analytics",
      "model": "claude-sonnet-4-6",
      "tool_calls": [
        { "name": "blog.get_analytics", "params": { "range": "7d" } }
      ],
      "created_at": "2026-04-03T10:15:03Z"
    }
  ],
  "has_more": true
}

🗑️ Close Conversation

POST /brain/conversations/:id/close

Response:

{
  "status": "closed",
  "memories_extracted": 3,
  "total_tokens": 15420,
  "total_cost_usd": 0.089
}

3.3 Insights (Proactive)

💡 List Insights

GET /brain/insights?status=unseen&priority=high&limit=10

Query Parameters:

Param Type Default Description
status Enum unseen Filter: unseen, seen, acted, dismissed, all
priority Enum all Filter: high, medium, low, all
limit Integer 10 Max results (1–50)

Response:

{
  "insights": [
    {
      "id": "ins_789",
      "type": "opportunity",
      "priority": "high",
      "title": "Your audience wants eggless cake recipes",
      "body": "40% of chatbot questions this week were about eggless cakes. You don't have a blog post on this yet.",
      "suggested_action": "blog.create_draft",
      "action_params": { "topic": "eggless cake recipes", "format": "recipe" },
      "created_at": "2026-04-03T06:00:00Z",
      "expires_at": "2026-04-10T06:00:00Z"
    }
  ],
  "unseen_count": 3
}

👁️ Mark Insight as Seen

POST /brain/insights/:id/seen

Response:

{
  "status": "seen",
  "seen_at": "2026-04-03T10:45:00Z"
}

✅ Act on Insight

Executes the suggested action for an insight.

POST /brain/insights/:id/act

Response (SSE Stream):

Same SSE format as chat — the action is executed by the relevant specialist agent, and the response is streamed back. The conversation is auto-created if one isn't active.


❌ Dismiss Insight

POST /brain/insights/:id/dismiss

Request Body:

{
  "reason": "not_relevant"
}
Field Type Required Description
reason Enum not_relevant, already_done, later, other. Used to improve future insight quality.

3.4 Memory (Admin)

These endpoints are for debugging and advanced users. Not exposed in the standard dashboard UI.

🧠 List Memories

GET /brain/memory?type=preference&entity=blog&limit=20

Query Parameters:

Param Type Default Description
type Enum all Filter: fact, preference, episode, pattern, entity, all
entity String Filter by linked entity ID
min_importance Float 0.0 Minimum importance score
limit Integer 20 Max results (1–100)

Response:

{
  "memories": [
    {
      "id": "mem_123",
      "type": "preference",
      "content": "Focus on blog only, not interested in social media currently",
      "importance": 0.82,
      "entity_ids": ["blog", "content-engine"],
      "access_count": 7,
      "source_type": "conversation",
      "created_at": "2026-03-15T10:00:00Z",
      "accessed_at": "2026-04-02T14:30:00Z"
    }
  ],
  "total": 45
}

🗑️ Delete Memory

Allows a user to explicitly tell the AI to forget something.

DELETE /brain/memory/:id

Response:

{
  "status": "deleted",
  "content": "Focus on blog only, not interested in social media currently"
}

3.5 Usage & Analytics

📊 Get AI Usage

GET /brain/usage?period=2026-04

Query Parameters:

Param Type Default Description
period String Current month YYYY-MM format

Response:

{
  "period": "2026-04",
  "plan": "pro",
  "limits": {
    "max_interactions": 5000,
    "used_interactions": 342,
    "remaining": 4658
  },
  "tokens": {
    "input": 856000,
    "output": 68400,
    "total": 924400
  },
  "cost_usd": 4.72,
  "model_breakdown": {
    "claude-haiku-4-5-20251001": { "calls": 342, "tokens": 120000, "cost": 0.12 },
    "claude-sonnet-4-6": { "calls": 280, "tokens": 780000, "cost": 4.20 },
    "claude-opus-4-6": { "calls": 12, "tokens": 24400, "cost": 0.40 }
  },
  "daily": [
    { "date": "2026-04-01", "interactions": 45, "cost_usd": 0.62 },
    { "date": "2026-04-02", "interactions": 67, "cost_usd": 0.89 },
    { "date": "2026-04-03", "interactions": 230, "cost_usd": 3.21 }
  ]
}

📈 Get AI Performance Metrics

GET /brain/usage/metrics?period=2026-04

Response:

{
  "period": "2026-04",
  "metrics": {
    "task_completion_rate": 0.78,
    "action_acceptance_rate": 0.65,
    "avg_latency_ms": 234,
    "memory_hit_rate": 0.72,
    "escalation_rate": 0.12,
    "insight_click_through_rate": 0.28,
    "total_conversations": 89,
    "total_messages": 1240,
    "total_tool_calls": 456,
    "total_insights_generated": 34,
    "total_insights_acted_on": 12
  }
}

3.6 Internal Endpoints (Service-to-Service)

These endpoints are called by CF Cron Triggers and CF Queues. Not exposed via Gateway.

⏰ Run Insight Generation (Cron)

POST /internal/insights/generate
x-gateway-key: <internal_key>

Triggers the insight engine for all active tenants. Called by Cron Trigger every 6 hours.


🔄 Process Memory Consolidation (Queue Consumer)

POST /internal/memory/consolidate
x-gateway-key: <internal_key>

Request Body (from CF Queue):

{
  "tenant_id": "tnt_123",
  "conversation_id": "conv_abc123",
  "tasks": ["merge_duplicates", "extract_entities", "compute_importance"]
}

📉 Run Memory Decay (Cron)

POST /internal/memory/decay
x-gateway-key: <internal_key>

Triggers periodic memory decay and pruning for all tenants. Called by Cron Trigger every 6 hours.


4. Generic Error Response Format

All error responses follow this structure:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "You've used 5000 of 5000 AI interactions this month. Upgrade your plan for more.",
    "details": {
      "plan": "pro",
      "limit": 5000,
      "used": 5000,
      "resets_at": "2026-05-01T00:00:00Z"
    }
  }
}

Standard Error Codes:

Code HTTP Status Description
RATE_LIMITED 429 AI interaction limit exceeded for current plan
INVALID_INPUT 400 Malformed request body
CONVERSATION_NOT_FOUND 404 Conversation ID does not exist or belongs to another tenant
INSIGHT_NOT_FOUND 404 Insight ID does not exist or belongs to another tenant
MEMORY_NOT_FOUND 404 Memory ID does not exist or belongs to another tenant
PERMISSION_DENIED 403 User lacks required PBAC permission
PROVIDER_UNAVAILABLE 503 All LLM providers failed (circuit breaker open)
CONFIRMATION_REQUIRED 202 Action requires user confirmation before execution
CONVERSATION_LIMIT 409 User already has an active conversation (close it first)
PLAN_FEATURE_UNAVAILABLE 403 Feature not available on current plan (e.g., opus model on Free)
AI Brain