Formats, streaming, errors
Request & response formats
5.1 Standard Request Format
API Key (AI / OpenAI-compat):
x-api-key: your-api-key-here
Content-Type: application/json
JWT (SPA / admin / agents):
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
Body (JSON, camelCase):
{
"prompt": "Your query here",
"projectId": 1,
"providerId": 12,
"stream": false
}
5.2 Standard AI Response Format
Success:
{
"success": true,
"content": "AI response text here",
"errorMessage": null,
"provider": "Azure",
"providerId": 12,
"executionDuration": "00:00:02.345",
"requestId": 12345,
"inputTokens": 25,
"outputTokens": 150
}
Validation / problem details may also use ASP.NET Core’s default error shapes (title, errors, traceId) on admin APIs.
5.3 Response Fields (AI)
| Field | Type | Description |
|---|---|---|
success | boolean | Outcome |
content | string | Model text (null on error) |
errorMessage | string | Error description |
provider | string | Provider type used |
providerId | integer | Instance id |
executionDuration | string | HH:mm:ss.fff |
requestId | integer | For logging / voting |
inputTokens / outputTokens | integer | Token counts |
audioDuration | number | Seconds (audio) |
chatId | GUID string | Chat session |
messageIndex | integer | Turn index |
sessionEnded | boolean | Chat closed |
5.4 File Upload Format
Content-Type: multipart/form-data. Field names are camelCase (providerId, projectId, noLog, files, audio, …).
curl -X POST https://your-kroov-host/api/ai/queryImage \
-H "x-api-key: your-api-key" \
-F "file=@image.png" \
-F "prompt=Analyze this image" \
-F "projectId=1" \
-F "providerId=12"
Streaming API
6.1 Server-Sent Events (SSE)
Used by:
| Surface | Endpoint | Auth |
|---|---|---|
AI chat / query (stream: true) | POST /api/ai/chat or /query | API Key |
| Agent runs | GET /api/agent-runs/{id}/events?after= | Admin JWT |
| Interactive sessions | GET /api/sessions/{id}/events?after= | JWT |
Headers (client):
Accept: text/event-stream
Typical AI chat events:
| Event / data | Meaning |
|---|---|
content | Text delta |
toolCalls | Tool invocations / results |
status | Round progress |
tokens | Cumulative token counts |
error | Terminal error |
[DONE] | Stream end |
Resumable streams (runs / sessions): pass after=<lastEventId> to continue after reconnect.
6.2 Client-Side Handling (AI SSE)
const response = await fetch('https://your-kroov-host/api/ai/chat', {
method: 'POST',
headers: {
'x-api-key': apiKey,
'Content-Type': 'application/json',
'Accept': 'text/event-stream'
},
body: JSON.stringify({
messageUser: 'Summarize the key points',
projectId: 1,
providerId: 12,
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (!line.startsWith('data:')) continue;
const data = line.slice(5).trim();
if (data === '[DONE]') return;
try {
const evt = JSON.parse(data);
if (evt.content) process.stdout?.write?.(evt.content);
} catch { /* ignore keep-alives */ }
}
}
6.3 WebSocket realtime STT
See AI & OpenAI-compatible → WebSocket — Live realtime transcription for the message protocol.
Error handling
7.1 HTTP Status Codes
| Code | Meaning | Typical cause |
|---|---|---|
200 | OK | Success |
202 | Accepted | Webhook accepted for async processing |
204 | No Content | CSP report stored |
400 | Bad Request | Validation / malformed body |
401 | Unauthorized | Missing/invalid API key, JWT, webhook signature, unknown connection |
403 | Forbidden | Project access denied; non-admin on AdminOnly route |
404 | Not Found | Unknown id |
409 | Conflict | Duplicate name; second approval; optimistic conflict |
413 | Payload Too Large | Upload over limit |
429 | Too Many Requests | If rate limiting is enabled in a given deployment |
500 | Internal Server Error | Unexpected failure |
502 | Bad Gateway | Upstream AI provider failure |
503 | Service Unavailable | Feature disabled / KB not supported / hosted MCP unavailable |
7.2 Feature-gate 503 examples
{ "error": "Event automations are disabled on this deployment." }
{ "message": "Internal knowledge bases require PostgreSQL with pgvector." }
Call GET /api/features before enabling UI affordances.
7.3 Retry Strategy
| Status | Retry? | Guidance |
|---|---|---|
408 / 429 / 502 / 503 | Yes | Exponential backoff with jitter |
500 | Cautious | Retry idempotent GETs; use idempotency keys on creates where supported |
400 / 401 / 403 / 404 / 409 | No | Fix request / credentials |
Idempotency:
- MCP instance create: optional
Idempotency-Keyheader - Agent runs:
idempotencyKeyin body - Scheduled task occurrences: unique
(ScheduledTaskId, IdempotencyKey)per slot - Automation webhooks: dedupe on external delivery id
7.4 Error Logging
Always capture: HTTP status, requestId (when present), correlation / trace id, timestamp, endpoint, project id. Never log API keys, JWTs, webhook secrets, or raw sensitive data beyond what your compliance policy allows.