Skip to Content
Docs are evolving — expect frequent updates.
AI Chat

AI Chat

Chat with the Kruncher.ai AI agent to ask questions about projects, analyses, market trends, and investment decisions. Build conversational experiences with context awareness and conversation history.

Endpoint

POST https://api.kruncher.ai/api/integration/chat

Headers

HeaderRequiredDescription
AuthorizationYesYour API key (format: YOUR_API_KEY)
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
querystringYesThe message or question to send to the AI agent
sessionIdstring (UUID)NoSession ID for conversation continuity. Omit for new conversation
projectIdstring (UUID)NoProject context for focused questions. Limits analysis scope
analysisIdstring (UUID)NoAnalysis context for specific analysis questions

Use Cases

  • Project Q&A: Ask questions about specific projects and investment decisions
  • Analysis Insights: Request detailed explanations of analysis results
  • Market Research: Ask about market trends, competitors, and industry insights
  • Due Diligence: Get AI assistance with due diligence questions
  • Conversation History: Maintain context across multiple messages in a session
  • Multi-context Analysis: Combine project and analysis context for comprehensive answers

Quick Start

cURL

CODE
curl -X POST "https://api.kruncher.ai/api/integration/chat" \
  -H "Authorization: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What are the key risks for this project based on the analysis?"
  }'

Response:

CODE
{
  "success": true,
  "data": {
    "response": "Based on the analysis, the key risks are: 1) Market concentration risk with 60% of revenue from top 3 customers...",
    "structuredData": {
      "riskFactors": ["market_concentration", "customer_dependency", "regulatory"],
      "severity": ["high", "medium", "medium"]
    },
    "status": "completed",
    "customerchatsId": "chat_abc123xyz",
    "sessionId": "session_def456uvw"
  }
}

Code Examples

JavaScript/Node.js

CODE
const API_KEY = "YOUR_API_KEY_HERE";
const BASE_URL = "https://api.kruncher.ai/api";
 
async function sendChatMessage(query, sessionId = null, projectId = null) {
  const payload = {
    query
  };
 
  // Add optional parameters
  if (sessionId) payload.sessionId = sessionId;
  if (projectId) payload.projectId = projectId;
 
  const response = await fetch(`${BASE_URL}/integration/chat`, {
    method: "POST",
    headers: {
      "Authorization": `${API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(payload)
  });
 
  if (!response.ok) {
    throw new Error(`Failed to send message: ${response.statusText}`);
  }
 
  return await response.json();
}
 
// Usage - simple question
async function main() {
  try {
    const result = await sendChatMessage(
      "What are the main growth drivers for this company?"
    );
 
    console.log("AI Response:", result.data.response);
    console.log("Session ID:", result.data.sessionId);
  } catch (error) {
    console.error("Error:", error.message);
  }
}
 
main();

Conversation with Session

CODE
class ChatSession {
  constructor(apiKey, projectId = null, analysisId = null) {
    this.apiKey = apiKey;
    this.baseUrl = "https://api.kruncher.ai/api";
    this.projectId = projectId;
    this.analysisId = analysisId;
    this.sessionId = null;
    this.history = [];
  }
 
  async sendMessage(query) {
    const payload = {
      query
    };
 
    if (this.sessionId) {
      payload.sessionId = this.sessionId;
    }
    if (this.projectId) {
      payload.projectId = this.projectId;
    }
    if (this.analysisId) {
      payload.analysisId = this.analysisId;
    }
 
    const response = await fetch(`${this.baseUrl}/integration/chat`, {
      method: "POST",
      headers: {
        "Authorization": `${this.apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(payload)
    });
 
    if (!response.ok) {
      throw new Error(`Chat failed: ${response.statusText}`);
    }
 
    const result = await response.json();
    const chatData = result.data;
 
    // Update session ID for follow-up messages
    this.sessionId = chatData.sessionId;
 
    // Store in history
    this.history.push({
      userMessage: query,
      aiResponse: chatData.response,
      timestamp: new Date().toISOString(),
      chatId: chatData.customerchatsId
    });
 
    return chatData;
  }
 
  async askFollowUp(question) {
    if (!this.sessionId) {
      throw new Error("No active session. Start with sendMessage()");
    }
    return this.sendMessage(question);
  }
 
  getHistory() {
    return this.history;
  }
 
  clearHistory() {
    this.history = [];
  }
}
 
// Usage
async function chatWithContext() {
  const session = new ChatSession(
    "YOUR_API_KEY_HERE",
    "project_id_here", // Set project context
    null // No specific analysis
  );
 
  try {
    // First message - starts new session
    let result = await session.sendMessage("What is the market size for this company?");
    console.log("AI:", result.response);
 
    // Follow-up question - uses same session
    result = await session.sendMessage("What's the competitive landscape?");
    console.log("AI:", result.response);
 
    // Another follow-up
    result = await session.sendMessage("What are the growth opportunities?");
    console.log("AI:", result.response);
 
    // View conversation history
    console.log("Chat History:", session.getHistory());
  } catch (error) {
    console.error("Error:", error.message);
  }
}
 
chatWithContext();

Python

CODE
import requests
from typing import Optional, Dict, List
 
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "https://api.kruncher.ai/api"
 
def send_chat_message(
    query: str,
    session_id: Optional[str] = None,
    project_id: Optional[str] = None,
    analysis_id: Optional[str] = None
) -> Dict:
    """Send a message to the AI chat agent."""
    
    url = f"{BASE_URL}/integration/chat"
    
    headers = {
        "Authorization": f"{API_KEY}",
        "Content-Type": "application/json"
    }
    
    payload = {
        "query": query
    }
    
    # Add optional parameters
    if session_id:
        payload["sessionId"] = session_id
    if project_id:
        payload["projectId"] = project_id
    if analysis_id:
        payload["analysisId"] = analysis_id
    
    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    
    return response.json()
 
# Usage - simple question
def main():
    try:
        result = send_chat_message(
            "What are the main growth drivers for this company?"
        )
        
        print("AI Response:", result['data']['response'])
        print("Session ID:", result['data']['sessionId'])
    except Exception as error:
        print(f"Error: {error}")
 
if __name__ == "__main__":
    main()

Python - Conversation Manager

CODE
import requests
from typing import Optional, Dict, List
from datetime import datetime
 
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "https://api.kruncher.ai/api"
 
class ChatSession:
    """Manage multi-turn conversations with the AI agent."""
    
    def __init__(
        self,
        api_key: str = API_KEY,
        project_id: Optional[str] = None,
        analysis_id: Optional[str] = None
    ):
        self.api_key = api_key
        self.base_url = BASE_URL
        self.project_id = project_id
        self.analysis_id = analysis_id
        self.session_id = None
        self.history = []
    
    def send_message(self, query: str) -> Dict:
        """Send a message and maintain session."""
        
        headers = {
            "Authorization": f"{self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "query": query
        }
        
        if self.session_id:
            payload["sessionId"] = self.session_id
        if self.project_id:
            payload["projectId"] = self.project_id
        if self.analysis_id:
            payload["analysisId"] = self.analysis_id
        
        response = requests.post(
            f"{self.base_url}/integration/chat",
            json=payload,
            headers=headers
        )
        response.raise_for_status()
        
        result = response.json()
        chat_data = result['data']
        
        # Update session ID for follow-ups
        self.session_id = chat_data['sessionId']
        
        # Store in history
        self.history.append({
            'user_message': query,
            'ai_response': chat_data['response'],
            'timestamp': datetime.now().isoformat(),
            'chat_id': chat_data['customerchatsId'],
            'structured_data': chat_data.get('structuredData')
        })
        
        return chat_data
    
    def ask_followup(self, question: str) -> Dict:
        """Ask a follow-up question in the same session."""
        if not self.session_id:
            raise ValueError("No active session. Start with send_message()")
        return self.send_message(question)
    
    def get_history(self) -> List[Dict]:
        """Get conversation history."""
        return self.history
    
    def print_conversation(self):
        """Print formatted conversation."""
        print("\n" + "="*60)
        print("CONVERSATION HISTORY")
        print("="*60)
        
        for i, msg in enumerate(self.history, 1):
            print(f"\n[Message {i}]")
            print(f"User: {msg['user_message']}")
            print(f"AI: {msg['ai_response'][:200]}...")
            print(f"Time: {msg['timestamp']}")
    
    def clear_history(self):
        """Clear conversation history."""
        self.history = []
 
# Usage
def main():
    # Create session with project context
    session = ChatSession(
        api_key=API_KEY,
        project_id="project_uuid_here"
    )
    
    try:
        # First message
        result = session.send_message("What is the market size?")
        print(f"✓ Response: {result['response'][:100]}...")
        
        # Follow-up question
        result = session.ask_followup("What about the competitive landscape?")
        print(f"✓ Response: {result['response'][:100]}...")
        
        # Another follow-up
        result = session.ask_followup("What are growth opportunities?")
        print(f"✓ Response: {result['response'][:100]}...")
        
        # Print full conversation
        session.print_conversation()
        
    except Exception as error:
        print(f"❌ Error: {error}")
 
if __name__ == "__main__":
    main()

Response Structure

Success Response (200 OK)

CODE
{
  "success": true,
  "data": {
    "response": "The AI agent's response text goes here. This can be a detailed answer to the question asked.",
    "structuredData": {
      "topics": ["market_analysis", "competitive_landscape"],
      "confidence": 0.95,
      "sources": ["analysis_1", "market_data"]
    },
    "status": "completed",
    "customerchatsId": "chat_abc123xyz789",
    "sessionId": "session_def456uvw123"
  }
}

Response Fields

FieldTypeDescription
responsestringThe AI agent’s response text
structuredDataobjectOptional structured data extracted from response
statusstringStatus of the chat (completed, processing, error)
customerchatsIdstringUnique chat message ID for reference
sessionIdstringSession ID for follow-up messages

Error Responses

400 Bad Request - Invalid Query

CODE
{
  "success": false,
  "error": "Query cannot be empty"
}

404 Not Found - Project/Analysis Not Found

CODE
{
  "success": false,
  "error": "Project not found"
}

429 Too Many Requests - Credit Limit Reached

CODE
{
  "success": false,
  "error": "Credit limit exceeded. Upgrade your plan or wait for reset."
}

Common Patterns

Pattern 1: Simple Q&A

CODE
async function askQuestion(question) {
  const response = await sendChatMessage(question);
  return response.data.response;
}
 
// Usage
const answer = await askQuestion("Is this company profitable?");
console.log(answer);

Pattern 2: Project-Focused Analysis

CODE
async function analyzeProject(projectId, question) {
  const response = await sendChatMessage(question, null, projectId);
  return response.data;
}
 
// Usage
const analysis = await analyzeProject(
  "proj_123",
  "What are the main risks for this project?"
);

Pattern 3: Multi-Turn Conversation

CODE
session = ChatSession(project_id="proj_123")
 
# Ask series of questions
questions = [
    "What is the company's current valuation?",
    "How does it compare to competitors?",
    "What are the growth opportunities in the next 5 years?"
]
 
for question in questions:
    response = session.send_message(question)
    print(f"Q: {question}\nA: {response['response']}\n")

Pattern 4: Analysis Deep-Dive

CODE
class AnalysisChatSession {
  constructor(apiKey, projectId, analysisId) {
    this.session = new ChatSession(apiKey, projectId, analysisId);
  }
 
  async exploreFindings() {
    const questions = [
      "What are the key findings from this analysis?",
      "What assumptions were made?",
      "How confident are these findings?",
      "What are the next steps?"
    ];
 
    const findings = {};
 
    for (const q of questions) {
      const response = await this.session.sendMessage(q);
      findings[q] = response.response;
    }
 
    return findings;
  }
}

Credit Usage

Free Tier

  • 40 messages per month
  • Includes project and analysis context
  • Full conversation history support

Plan Limits

PlanMonthly MessagesPrice
Free40$0
Pro500$99/month
EnterpriseUnlimitedCustom

Checking Credits

CODE
// Response includes credit information in headers
const response = await fetch(url, options);
const creditsRemaining = response.headers.get('X-Credits-Remaining');
const creditsReset = response.headers.get('X-Credits-Reset-Date');
 
console.log(`Credits remaining: ${creditsRemaining}`);
console.log(`Resets on: ${creditsReset}`);

Best Practices

Question Quality

  • Be specific and detailed in your questions
  • Provide context when relevant
  • Use follow-up questions for clarification
  • Ask one question per message

Session Management

  • Reuse session IDs for follow-up questions
  • Include project/analysis context for better answers
  • Store session IDs to resume conversations later
  • Clear history when starting new analysis

Error Handling

  • Handle credit limit exceeded (429) gracefully
  • Implement retry logic for transient errors
  • Log chat IDs for audit trail
  • Validate query before sending

Performance

  • Batch related questions into a single session
  • Cache responses for similar questions
  • Monitor credit usage across your application
  • Implement rate limiting on client side

Error Handling

Handling Empty Query

CODE
async function sendMessage(query) {
  if (!query || query.trim().length === 0) {
    throw new Error("Query cannot be empty");
  }
  
  return await sendChatMessage(query);
}

Handling Credit Limits

CODE
def send_with_fallback(session, query):
    try:
        return session.send_message(query)
    except requests.HTTPError as e:
        if e.response.status_code == 429:
            print("❌ Credit limit reached")
            print("   Upgrade your plan or wait for reset")
            return None
        raise

Handling Invalid Project/Analysis

CODE
async function chatWithContext(projectId, analysisId, query) {
  try {
    const response = await sendChatMessage(query, null, projectId, analysisId);
    return response.data.response;
  } catch (error) {
    if (error.message.includes("not found")) {
      console.error("Project or analysis not found. Check IDs.");
      // Fallback to general question
      return await sendChatMessage(query);
    }
    throw error;
  }
}

Troubleshooting

”Query cannot be empty” Error

  • Verify query string is not empty
  • Check for whitespace-only queries
  • Validate input before sending

”Credit limit exceeded” Error

  • Upgrade to a higher plan
  • Wait for monthly credit reset
  • Check credit usage in settings

”Project not found” Error

  • Verify project ID is correct format
  • Check project still exists
  • Try query without project context

Slow Responses

  • Try simpler, more specific questions
  • Check API status page
  • Implement timeout handling
  • Consider batch processing

Need Help?

  • Questions about answers? Ask a follow-up question in the same session
  • Finding a project ID? Use Get Project Details
  • Want better answers? Provide more context with project or analysis ID
  • Credit questions? Check your account settings
Last updated on