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
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Your API key (format: YOUR_API_KEY) |
Content-Type | Yes | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The message or question to send to the AI agent |
sessionId | string (UUID) | No | Session ID for conversation continuity. Omit for new conversation |
projectId | string (UUID) | No | Project context for focused questions. Limits analysis scope |
analysisId | string (UUID) | No | Analysis 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
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:
{
"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
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
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
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
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)
{
"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
| Field | Type | Description |
|---|---|---|
response | string | The AI agent’s response text |
structuredData | object | Optional structured data extracted from response |
status | string | Status of the chat (completed, processing, error) |
customerchatsId | string | Unique chat message ID for reference |
sessionId | string | Session ID for follow-up messages |
Error Responses
400 Bad Request - Invalid Query
{
"success": false,
"error": "Query cannot be empty"
}404 Not Found - Project/Analysis Not Found
{
"success": false,
"error": "Project not found"
}429 Too Many Requests - Credit Limit Reached
{
"success": false,
"error": "Credit limit exceeded. Upgrade your plan or wait for reset."
}Common Patterns
Pattern 1: Simple Q&A
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
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
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
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
| Plan | Monthly Messages | Price |
|---|---|---|
| Free | 40 | $0 |
| Pro | 500 | $99/month |
| Enterprise | Unlimited | Custom |
Checking Credits
// 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
async function sendMessage(query) {
if (!query || query.trim().length === 0) {
throw new Error("Query cannot be empty");
}
return await sendChatMessage(query);
}Handling Credit Limits
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
raiseHandling Invalid Project/Analysis
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;
}
}Related Endpoints
- Get Project Details - View project information
- Get Analysis Results - View analysis output
- Project Status - Check project status
- Configuration - View available contexts
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