logicspike/docs

Contact Intelligence

Phase 4: API Specification — Contact Intelligence

Last Updated: 2026-04-03 Status: Draft


1. Service Overview

Property Value
Service Owner apps/contact-intelligence
Base URL https://api.logicspike.com/contact-intel (via Gateway)
Internal Microservice contact-intelligence.logicspike.workers.dev
Gateway Key Header x-gateway-key
Primary Consumer Chat Engine (service-to-service)
Secondary Consumer AI Brain (via brain tools)

2. Authentication Requirements

Domain Auth Type Header Consumer
Context Retrieval Gateway key x-gateway-key Chat Engine
Ingestion Gateway key x-gateway-key Chat Engine
Contact Management JWT (user session) Authorization: Bearer <token> AI Brain / Dashboard
Outreach Management JWT (user session) Authorization: Bearer <token> AI Brain / Dashboard
Analytics JWT (user session) Authorization: Bearer <token> AI Brain
Internal (Cron, Queues) Gateway key x-gateway-key CF Cron / CF Queues

3. Endpoints by Domain

3.1 Context & Ingestion (Chat Engine — Hot Path)

🔍 Get Contact Context

The primary hot-path endpoint. Called by Chat Engine on every incoming message. Returns memories, emotional state, and relationship context for a contact.

GET /contact-intel/context/:contact_id
x-gateway-key: <key>

Query Parameters:

Param Type Default Description
message String Current user message (used for mood classification and memory relevance scoring)
memory_limit Integer 10 Max memories to return
min_importance Float 0.3 Minimum importance threshold for memories

Response:

{
  "contact": {
    "id": "ct_arjun",
    "display_name": "Arjun",
    "language": "en",
    "channel": "whatsapp"
  },
  "state": {
    "mood": "neutral",
    "energy": "medium",
    "conversation_style": "playful",
    "relationship_stage": "established",
    "active_streak": 20,
    "total_messages": 245,
    "total_sessions": 22,
    "last_active_at": "2026-04-02T22:30:00Z"
  },
  "memories": [
    {
      "id": "mem_001",
      "type": "fact",
      "content": "Has a golden retriever named Bruno",
      "importance": 0.88,
      "entity_ids": ["pet:bruno"],
      "retrieval_score": 0.92
    },
    {
      "id": "mem_002",
      "type": "preference",
      "content": "Likes playful banter and humor",
      "importance": 0.80,
      "entity_ids": [],
      "retrieval_score": 0.78
    }
  ],
  "relationship": {
    "days_since_first_contact": 20,
    "stage": "established",
    "trust_level": "high"
  }
}

Error Codes:

Code HTTP Description
CONTACT_NOT_FOUND 404 Contact ID does not exist for this tenant

Performance SLA: < 30ms p95


📥 Ingest Interaction

Called by Chat Engine after generating a response. Triggers memory extraction, mood update, and deferred processing.

POST /contact-intel/ingest
x-gateway-key: <key>
Content-Type: application/json

Request Body:

{
  "tenant_id": "tnt_ravi",
  "contact_id": "ct_arjun",
  "user_message": "Ugh, Bruno ate my shoes again",
  "ai_response": "Nooo not again! Bruno has a shoe addiction at this point...",
  "detected_mood": "frustrated",
  "detected_energy": "medium",
  "session_id": "sess_abc123"
}
Field Type Required Description
tenant_id UUID Business tenant
contact_id UUID End-user contact
user_message String The user's message
ai_response String The AI's generated response
detected_mood Enum Pre-classified mood (if Chat Engine classified it). If omitted, Contact Intelligence classifies.
detected_energy Enum Pre-classified energy
session_id UUID Groups messages into sessions

Response:

{
  "status": "accepted",
  "memories_extracted": 2,
  "state_updated": true,
  "triggers_created": 0,
  "deferred_tasks_queued": 3
}

Performance SLA: < 50ms (returns 202 Accepted, deferred work is async)


➕ Create Contact

Creates a new contact profile. Called by Chat Engine on first interaction from an unknown external ID.

POST /contact-intel/contacts
x-gateway-key: <key>
Content-Type: application/json

Request Body:

{
  "tenant_id": "tnt_ravi",
  "external_id": "wa_919876543210",
  "channel": "whatsapp",
  "display_name": "Arjun"
}

Response:

{
  "id": "ct_arjun",
  "tenant_id": "tnt_ravi",
  "external_id": "wa_919876543210",
  "channel": "whatsapp",
  "display_name": "Arjun",
  "state": {
    "mood": "neutral",
    "energy": "medium",
    "conversation_style": "casual",
    "relationship_stage": "new",
    "active_streak": 0,
    "total_messages": 0
  },
  "created_at": "2026-04-03T22:15:00Z"
}

3.2 Contact Management (AI Brain / Dashboard)

📋 List Contacts

GET /contact-intel/contacts?sort=engagement&stage=established&limit=20

Query Parameters:

Param Type Default Description
sort Enum recent recent, engagement, churn_risk, messages
stage Enum all Filter: new, building, established, deep, fading, dormant, all
churn_risk_min Float Filter contacts above this churn risk
limit Integer 20 Max results (1–100)
offset Integer 0 Pagination offset

Response:

{
  "contacts": [
    {
      "id": "ct_arjun",
      "display_name": "Arjun",
      "channel": "whatsapp",
      "relationship_stage": "established",
      "active_streak": 20,
      "total_messages": 245,
      "churn_risk": 0.12,
      "mood": "happy",
      "last_active_at": "2026-04-02T22:30:00Z"
    }
  ],
  "total": 234,
  "limit": 20,
  "offset": 0
}

👤 Get Contact Profile

Full profile including memories, state, entities, and recent triggers.

GET /contact-intel/contacts/:id/profile

Response:

{
  "contact": {
    "id": "ct_arjun",
    "display_name": "Arjun",
    "channel": "whatsapp",
    "language": "en",
    "created_at": "2026-03-15T22:15:00Z"
  },
  "state": {
    "mood": "happy",
    "energy": "high",
    "relationship_stage": "established",
    "active_streak": 20,
    "total_messages": 245,
    "total_sessions": 22,
    "churn_risk": 0.12,
    "preferred_hours": ["22:00", "23:00"]
  },
  "memories": {
    "total": 48,
    "by_type": { "fact": 15, "preference": 8, "episode": 20, "pattern": 5 },
    "top": [
      { "type": "fact", "content": "Software engineer at Infosys", "importance": 0.85 },
      { "type": "fact", "content": "Has a golden retriever named Bruno", "importance": 0.88 },
      { "type": "pattern", "content": "Usually chats between 10pm-12am", "importance": 0.75 }
    ]
  },
  "entities": [
    { "id": "pet:bruno", "type": "pet", "display_name": "Bruno", "memory_count": 12 },
    { "id": "workplace:infosys", "type": "workplace", "display_name": "Infosys", "memory_count": 5 }
  ],
  "recent_outreach": [
    { "type": "scheduled", "message": "Good morning! Hope the presentation goes well...", "sent_at": "2026-04-01T08:00:00Z", "status": "sent" }
  ]
}

🗑️ Delete Contact (GDPR)

Deletes a contact and ALL associated data (memories, state, triggers, logs).

DELETE /contact-intel/contacts/:id

Response:

{
  "status": "deleted",
  "deleted": {
    "memories": 48,
    "entities": 7,
    "triggers": 3,
    "interaction_logs": 245
  }
}

📦 Export Contact Data (GDPR)

GET /contact-intel/contacts/:id/export

Response: Full JSON export of all contact data — profile, state, memories, entities, triggers, interaction logs.


3.3 Outreach Management

📨 Schedule Outreach

Manually schedule a proactive message to a contact.

POST /contact-intel/outreach
Content-Type: application/json

Request Body:

{
  "contact_id": "ct_arjun",
  "trigger_type": "scheduled",
  "channel": "whatsapp",
  "generate_with_llm": true,
  "llm_context": "Arjun was upset about missing a promotion. Send a supportive check-in.",
  "scheduled_at": "2026-04-04T08:00:00Z"
}

Response:

{
  "id": "trg_789",
  "status": "pending",
  "scheduled_at": "2026-04-04T08:00:00Z",
  "will_generate": true
}

📋 List Outreach Triggers

GET /contact-intel/outreach?contact_id=ct_arjun&status=pending

Query Parameters:

Param Type Default Description
contact_id UUID Filter by contact
status Enum all pending, sent, failed, cancelled, all
trigger_type Enum all scheduled, inactivity, milestone, recurring, all
limit Integer 20 Max results

❌ Cancel Outreach Trigger

POST /contact-intel/outreach/:id/cancel

Response:

{
  "status": "cancelled",
  "trigger_id": "trg_789"
}

⚙️ Get Outreach Config

GET /contact-intel/outreach/config

Response:

{
  "inactivity_enabled": true,
  "inactivity_days": 3,
  "inactivity_max_attempts": 2,
  "milestone_enabled": true,
  "recurring_enabled": false,
  "recurring_cron": null,
  "quiet_hours_start": "23:00",
  "quiet_hours_end": "07:00"
}

⚙️ Update Outreach Config

PATCH /contact-intel/outreach/config
Content-Type: application/json

Request Body:

{
  "inactivity_days": 5,
  "recurring_enabled": true,
  "recurring_cron": "0 8 * * *",
  "quiet_hours_start": "22:00"
}

3.4 Analytics (AI Brain)

GET /contact-intel/analytics/trends?days=7

Response:

{
  "period_days": 7,
  "active_users": 234,
  "active_users_change": 0.12,
  "new_users": 28,
  "churned_users": 3,
  "total_messages": 8400,
  "avg_session_duration_min": 23,
  "avg_messages_per_session": 18,
  "retention_7day": 0.82,
  "retention_30day": 0.58,
  "daily": [
    { "date": "2026-04-01", "active": 198, "new": 5, "messages": 1150 },
    { "date": "2026-04-02", "active": 210, "new": 4, "messages": 1230 }
  ]
}

⚠️ Get Churn Risk Report

GET /contact-intel/analytics/churn?threshold=0.6&limit=20

Response:

{
  "threshold": 0.6,
  "at_risk_count": 8,
  "contacts": [
    {
      "id": "ct_deepak",
      "display_name": "Deepak",
      "churn_risk": 0.89,
      "last_active_at": "2026-03-29T18:00:00Z",
      "days_inactive": 5,
      "relationship_stage": "fading",
      "last_mood": "bored",
      "outreach_status": "none_sent"
    }
  ]
}

😊 Get Mood Distribution

GET /contact-intel/analytics/moods?days=7

Response:

{
  "period_days": 7,
  "total_classifications": 8400,
  "distribution": {
    "happy": 0.35,
    "neutral": 0.28,
    "excited": 0.12,
    "playful": 0.08,
    "sad": 0.06,
    "anxious": 0.04,
    "frustrated": 0.04,
    "bored": 0.02,
    "angry": 0.01
  },
  "trend": "positive"
}

3.5 Memory Management

🧠 List Contact Memories

GET /contact-intel/contacts/:id/memories?type=fact&limit=20

Query Parameters:

Param Type Default Description
type Enum all fact, preference, episode, pattern, all
min_importance Float 0.0 Minimum importance threshold
entity String Filter by entity ID (e.g., pet:bruno)
limit Integer 20 Max results

🗑️ Delete Memory

Allows business owner (via Brain) or contact ("forget this") to delete a specific memory.

DELETE /contact-intel/contacts/:id/memories/:memory_id

🗑️ Delete All Memories (Forget Me)

Complete memory wipe for a contact.

DELETE /contact-intel/contacts/:id/memories

Response:

{
  "status": "deleted",
  "memories_deleted": 48,
  "entities_deleted": 7,
  "state_reset": true
}

3.6 Internal Endpoints (Cron & Queue)

⏰ Fire Outreach Triggers (Cron)

POST /internal/outreach/fire
x-gateway-key: <key>

Called every 15 minutes by Cron Trigger. Scans for pending triggers whose scheduled_at has passed, inactivity thresholds reached, or milestones hit.


🔄 Process Deferred Consolidation (Queue Consumer)

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

Request Body (from CF Queue):

{
  "tenant_id": "tnt_ravi",
  "contact_id": "ct_arjun",
  "tasks": ["embed_memories", "merge_duplicates", "extract_entities", "check_triggers"]
}

📉 Run Churn Scoring & Memory Decay (Cron)

POST /internal/maintenance
x-gateway-key: <key>

Called every 6 hours. Recomputes churn_risk for all active contacts, decays unaccessed memories, prunes low-importance memories.


4. Generic Error Response Format

{
  "error": {
    "code": "CONTACT_NOT_FOUND",
    "message": "Contact ct_xyz does not exist for this tenant.",
    "details": {}
  }
}

Standard Error Codes:

Code HTTP Description
CONTACT_NOT_FOUND 404 Contact ID does not exist for this tenant
OUTREACH_DISABLED 409 Contact has outreach disabled — cannot schedule triggers
TRIGGER_NOT_FOUND 404 Outreach trigger ID does not exist
RATE_LIMITED 429 Too many requests to this endpoint
INVALID_INPUT 400 Malformed request body
PERMISSION_DENIED 403 User lacks required PBAC permission
QUIET_HOURS 409 Cannot schedule outreach during configured quiet hours
MAX_ATTEMPTS_REACHED 409 Inactivity outreach limit already reached for this contact
Contact Intelligence