Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Chatbot API Errors

The chatbot API has two error channels:

  • Non-2xx HTTP responses use the standard ApiError envelope.
  • POST /api/v1/chat/messages can also return a 200 SSE stream that later ends with a terminal error event.

Handle these separately. ApiError.error.code and StreamErrorEvent.code are different enums.

HTTP API errors

Before a stream starts, endpoints return non-2xx HTTP responses with this shape:

{
  "error": {
    "code": "validation",
    "message": "Validation failed",
    "params": [{ "field": "message.parts.0.text", "message": "Text is required" }]
  }
}

params is only present when the API can point to specific invalid fields.

CodeTypical statusMeaningClient handling
unauthorized401Missing, expired, or invalid authentication credentials.Request a new visitor token or ask the user to restart the session.
forbidden403Authenticated, but not allowed to access the resource.Stop the action and show a permission error.
not_found404The target resource does not exist or is unavailable.Show a not-available state; do not retry automatically.
rate_limited429Too many requests in a short period.Back off before retrying.
validation422The request body or query parameters failed validation.Fix the highlighted fields from params before retrying.
internal500Unexpected server failure before the response stream started.Show a generic error and allow retry if the action is safe.

Stream errors

POST /api/v1/chat/messages is different because it streams the assistant response. Once the HTTP response has started, the server cannot switch to a non-2xx HTTP error. Instead, the stream ends with an SSE error event:

event: error
data: {"code":"generation_failed","message":"Failed to generate a response. Please try again.","retryable":true}

The parsed event data has this shape:

{
  "code": "generation_failed",
  "message": "Failed to generate a response. Please try again.",
  "retryable": true
}
CodeWhen it happensClient handling
generation_failedResponse generation failed after the stream started.Show message; offer retry only when retryable is true.

After receiving a stream error, treat the stream as complete and disconnect. It will not be followed by a done event.

Handling both channels

Check the HTTP response first. Only start reading stream events after response.ok is true.

const response = await fetch("https://api.dialogintelligens.dk/api/v1/chat/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(requestBody),
});
 
if (!response.ok) {
  const apiError = await response.json();
  handleApiError(apiError.error.code, apiError.error.message, apiError.error.params);
  return;
}
 
await readSse(response.body, (event) => {
  if (event.event === "error") {
    handleStreamError(event.data.code, event.data.message, event.data.retryable);
    return;
  }
 
  handleStreamEvent(event);
});

Keep a generic fallback for unknown future error codes, but do not treat stream error codes as ApiError codes.