16. AI & Assistant
16.1 Generate Reply Draft
POST /api/v1/ai/reply-draft
Generate AI-powered reply to message.
Request Body:
{
"conversationId": "conv-001",
"messageId": "msg-001",
"tone": "professional"
}
Response:
{
"draft": "Thank you for your inquiry! We'd be happy to help you with...",
"confidence": 0.87
}
16.2 Generate Summary
POST /api/v1/ai/summary
Generate AI summary of conversation.
Request Body:
{
"conversationId": "conv-001"
}
Response:
{
"summary": "Customer inquired about premium plan pricing. Interested in features comparison with competitors.",
"keyPoints": [
"Interest in premium plan",
"Wants feature comparison",
"Budget around $500/month"
]
}
16.3 Analyze Sentiment
POST /api/v1/ai/sentiment
Analyze sentiment of message/conversation.
Request Body:
{
"text": "I'm really happy with your service! Great support team."
}
Response:
{
"sentiment": "positive",
"score": 0.92,
"emotions": ["happy", "satisfied"]
}
16.4 List AI Providers
GET /api/v1/ai/providers
Returns the providers (anthropic, gemini, openai, qwen, kimi) with their base URL and the current organization's API-key status. The key is only returned masked — never the real key.
Response:
[
{ "id": "openai", "name": "OpenAI", "baseUrl": "https://api.openai.com", "hasKey": true, "keyMask": "••••f5QA" },
{ "id": "anthropic", "name": "Anthropic", "baseUrl": "https://api.anthropic.com", "hasKey": false, "keyMask": "" }
]
16.5 Update Provider API Key / Base URL
PUT /api/v1/ai/providers/:id
Permission: settings:edit. Sets or clears the API key (encrypted at rest with AES-GCM) and base URL for a provider, per organization. Values set here take precedence over .env. Send an empty apiKey to clear the key (falls back to .env).
Request Body:
{
"apiKey": "sk-proj-...",
"baseUrl": "https://api.openai.com"
}
Response:
{ "ok": true }
16.6 List Provider Models
GET /api/v1/ai/providers/:id/models
Fetches the model list directly from the provider's API (using the configured key + base URL). If the provider does not support listing or the key is invalid, an empty array is returned with error (the UI then allows typing the model name manually).
Response:
{
"models": [
{ "title": "gpt-4o-mini", "value": "gpt-4o-mini" },
{ "title": "gpt-5.4-nano", "value": "gpt-5.4-nano" }
]
}
Error response (still HTTP 200):
{ "models": [], "error": "API key not configured" }