Integration Quick Start

In this guide, you'll authenticate with a Bearer token, POST a minimal body to https://api.korinai.com/api/chat that includes participantEmail and messages, and stream responses with SSE to render output as it arrives. We’ll also cover optional fields: roomId for persistence, and previousMessages for context.

Overview

Call the KorinAI Chat API directly from your app using a Bearer token and a minimal payload containing participantEmail and messages. The API streams responses over Server‑Sent Events (SSE) so you can render tokens incrementally. Use user/session tokens client‑side; use API keys only on trusted servers. Optionally include roomId to persist the conversation and previousMessages to supply context.

Key Features

  • Simple POST to https://api.korinai.com/api/chat.
  • Streaming by default (SSE) for responsive UIs.
  • Required participantEmail (the user/agent to chat with; see below).
  • Optional roomId (persistence) and previousMessages (context).

Getting Started

  1. Sign in to the dashboard.
  2. Create a token in Dashboard → Settings → API Keys (or use a user/session token from your auth layer).
  3. (Optional) In Your Agents, select the agent you want to run as (you’ll pass their participantEmail).

Quick Start

Call the API with a Bearer token. You can use either a user/session token (client) or an API key (server/trusted integration).

Embed the Chat Widget

If you want a drop‑in UI for websites, include our CDN script and initialize:

html
<script src="https://cdn.jsdelivr.net/npm/@korinai/embed@latest/dist/embed.js"></script>
<div id="korin-floating-chat"></div>
<script>
  window.KorinAI.init({
    target: "#korin-floating-chat",
    baseUrl: "https://api.korinai.com",
    chatApi: "https://api.korinai.com/api/chat",
    language: "en",
    props: { title: "Chat with KorinAI" }
  });
</script>

Node.js Fetch Example

ts
// sseParser.ts
export async function parseKorinSSE(stream: ReadableStream<Uint8Array>) {
  const reader = stream.getReader();
  const decoder = new TextDecoder();
  let buffer = "";
  let finalText = "";
  let metadata: any = undefined;

  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(6);
      if (data === "[DONE]") return { text: finalText, metadata };
      try {
        const evt = JSON.parse(data);
        if (evt.type === "text-start") finalText = "";
        else if (evt.type === "text-delta") finalText += evt.delta || "";
        else if (evt.type === "message-metadata")
          metadata = evt.messageMetadata;
        else if (evt.type === "error")
          throw new Error(evt.errorText || "Stream error");
      } catch {}
    }
  }
  return { text: finalText, metadata };
}

type MinimalMessage = {
  role: "user" | "assistant" | "system";
  content: string;
};

async function sendMessage(
  token: string,
  prompt: string,
  options: {
    participantEmail: string; // REQUIRED: who to chat with (see note below)
    roomId?: string;
    previousMessages?: MinimalMessage[]; // optional history for context
  }
) {
  const res = await fetch("https://api.korinai.com/api/chat", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({
      participantEmail: options.participantEmail,
      messages: [
        ...(options?.previousMessages || []),
        { role: "user", content: prompt },
      ],
      ...(options?.roomId ? { roomId: options.roomId } : {}),
    }),
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  if (!res.body) throw new Error("No response body");
  return await parseKorinSSE(res.body);
}

Minimal request body

Send the smallest valid payload. Add fields only as needed.

json
{
  "participantEmail": "user@example.com",
  "messages": [{ "role": "user", "content": "Hello!" }]
}

For persistence and context, you can also include:

json
{
  "roomId": "room_abc123",
  "messages": [
    { "role": "user", "content": "Hi" },
    { "role": "assistant", "content": "Hello!" }
  ]
}

Request body fields

  • participantEmail (required): Email of the participant to chat with. Use the authenticated user’s email to chat with yourself; or use another user’s email to chat with that user/agent.
  • messages: Ordered chat turns. Include previous messages to provide context; the last one is usually the new user prompt.
  • roomId (optional): Associate the exchange with a conversation for naming and history.

Example Response

Responses are streamed as Server-Sent Events (SSE). Parse chunks incrementally; your UI can render as they arrive. For one-shot usage, buffer the stream and parse the final assistant message.

Troubleshooting

  • 401 Unauthorized: ensure the token is valid.
  • 403 Insufficient credits: check credit balance and plan.
  • No streaming: read from response.body.getReader() and append decoded chunks.
  • Tools don’t trigger: include a valid participantEmail with tools enabled.

Related Topics


Prefer ready‑made UI components? Check out Korin UI.