Configuration

Complete reference for site configuration options. All fields are validated against a Zod schema on the server. Required fields are marked; everything else has sensible defaults.

Site Config (top level)

The top-level object passed when creating or updating a site via the admin API or dashboard.

FieldTypeDefaultDescription
siteIdstringrequiredUnique identifier. Lowercase alphanumeric with hyphens only (^[a-z0-9-]+$), 1-100 chars.
allowedOriginsstring[]requiredURLs allowed to load the widget. Must be valid URLs. At least one required. The server checks the Origin header against this list.
enabledbooleantrueEnable or disable the site. Disabled sites reject all widget requests.
brandingobject{}Widget appearance and text. See branding below.
aiobjectrequiredAI provider configuration. See ai below.
guardrailsobjectrequiredSecurity and topic guardrails. See guardrails below.
knowledgeobject{}Knowledge sources for context. See knowledge below.
ticketsobject{}Ticket creation settings. See tickets below.
rateLimitobject{}Per-IP rate limiting. See rateLimit below.

branding

Controls the widget's visual appearance, text, and position. All fields are optional with sensible defaults. The branding object is sent to the client as part of the public config — no secrets are exposed.

FieldTypeDefaultDescription
namestring"Assistant"Display name shown in the widget header and used as the replacement when scrubbing AI provider names from responses. 1-100 chars.
taglinestringShort tagline below the name. Up to 200 chars. Optional.
logoUrlstring (URL)URL to a logo image displayed in the widget header. Must be a valid URL. Optional.
colors.primaryhex color#6366f1Primary accent color. Used for the header, bubble button, and user message background.
colors.primaryForegroundhex color#ffffffText color on primary-colored backgrounds (header, bubble button).
colors.backgroundhex color#ffffffWidget background color for the chat area and input bar.
colors.foregroundhex color#1f2937Primary text color used for assistant messages and general text.
colors.bubbleBackgroundhex color#f3f4f6Background color for assistant message bubbles.
colors.userBubbleBackgroundhex color#6366f1Background color for user message bubbles.
colors.userBubbleForegroundhex color#ffffffText color inside user message bubbles.
positionenum"bottom-right"Widget position: "bottom-right" or "bottom-left".
welcomeMessagestring"Hi! How can I help you today?"First message shown when the user opens the chat window. Up to 500 chars.
inputPlaceholderstring"Type your message..."Placeholder text in the message input field. Up to 200 chars.
Note: All color values must be 6-digit hex strings (e.g. #6366f1). Shorthand hex (#fff) and named colors are not accepted.

ai

Kody works with any OpenAI-compatible chat completions API. This includes Ollama, vLLM, llama.cpp, OpenAI, and many other providers. The AI config is stored server-side only — API keys are never sent to the browser.

FieldTypeDefaultDescription
baseUrlstring (URL)requiredOpenAI-compatible API base URL. Examples: http://localhost:11434/v1 (Ollama), https://api.openai.com/v1 (OpenAI).
apiKeystring"ollama"API key sent in the Authorization: Bearer header. For Ollama, any non-empty string works. Min 1 char.
modelstringrequiredModel name to request from the provider. Examples: llama3, gpt-4o, mistral. Min 1 char.
temperaturenumber0.7Sampling temperature controlling response randomness. Range: 0 (deterministic) to 2 (very creative).
maxTokensinteger1024Maximum tokens in the AI response. Range: 1-32768.
topPnumberNucleus sampling parameter. Range: 0-1. Optional. Only set this if you know what you are doing — most use cases are better served by adjusting temperature alone.
systemPromptPrefixstringCustom text appended to the auto-generated system prompt under an "ADDITIONAL INSTRUCTIONS" section. Up to 4000 chars. Use this to give the AI extra persona details or behavioral instructions.
Provider examples:
  • Ollama: baseUrl: "http://localhost:11434/v1", apiKey: "ollama"
  • OpenAI: baseUrl: "https://api.openai.com/v1", apiKey: "sk-..."
  • vLLM: baseUrl: "http://localhost:8000/v1", apiKey: "token"
  • llama.cpp: baseUrl: "http://localhost:8080/v1", apiKey: "token"

guardrails

Controls security filtering and topic restrictions. For a deep dive, see the Security page.

FieldTypeDefaultDescription
allowedTopicsstring[]requiredTopics the assistant is allowed to discuss. At least one required. Each string 1-200 chars. Injected into the system prompt as allowed topics.
topicDescriptionstringrequiredHuman-readable description of what the assistant should help with. Injected into the system prompt. 1-4000 chars.
refusalMessagestring"I can only help with topics related to this website..."Message the AI is instructed to use when refusing off-topic requests. Up to 500 chars.
blockedInputPatternsstring[][]Additional regex patterns to block in user input (on top of the 17 built-in prompt injection patterns). Each is tested case-insensitively.
blockedOutputPatternsstring[][]Regex patterns to block in AI responses. If a response matches any pattern, it is blocked entirely and not sent to the user.
maxInputLengthinteger2000Maximum user message length in characters. Range: 1-10000.
enablePromptInjectionDetectionbooleantrueEnable built-in prompt injection pattern detection. Checks for instruction overrides, role switching, mode escalation, system prompt extraction, and format injection.
enableOutputScrubbingbooleantrueScrub 30+ AI provider names from responses and detect system prompt leaks. Strongly recommended to keep enabled.

knowledge

Provides contextual information to the AI via the system prompt. For details on each source type, see Knowledge Sources.

FieldTypeDefaultDescription
sourcesKnowledgeSource[][]Array of knowledge sources. Supports 4 types: text, faq, url, file. See Knowledge Sources.
maxContextTokensinteger4000Token budget for knowledge context injected into the system prompt. Range: 100-32000. Higher values increase AI costs and latency.

tickets

Enable users to create support tickets from the chat widget. For provider-specific setup, see Ticket Providers.

FieldTypeDefaultDescription
enabledbooleanfalseEnable ticket creation from the widget. Shows a ticket button in the chat UI.
promptMessagestring"Would you like me to create a support ticket..."Message prompting the user to create a ticket. Up to 500 chars.
providersTicketProvider[][]Array of ticket providers. Supports 5 types: jira, github, linear, email, webhook. Tickets are sent to all configured providers. See Ticket Providers.
requiredFieldsstring[]["email", "description"]Fields the user must fill in to submit a ticket. Valid values: "name", "email", "subject", "description".

rateLimit

Per-IP rate limiting to protect your AI backend from abuse. All limits are enforced server-side.

FieldTypeDefaultDescription
messagesPerMinuteinteger10Max messages per IP per minute. Range: 1-120.
messagesPerHourinteger100Max messages per IP per hour. Range: 1-1000.
messagesPerDayinteger1000Max messages per IP per day. Range: 1-10000.

Embedding the Widget

There are two ways to embed the widget on your page:

1. Script tag with data attributes

<script
  src="https://api.kody.codai.app/widget.js"
  data-site-id="your-site-id"
  async
></script>

2. window.KodyConfig

<script>
  window.KodyConfig = {
    siteId: "your-site-id",
    position: "bottom-left",
    name: "Support Bot",
    primaryColor: "#10b981"
  };
</script>
<script src="https://api.kody.codai.app/widget.js" async></script>

Complete Example

A full site configuration using all available options:

{
  "siteId": "my-docs",
  "allowedOrigins": ["https://example.com", "https://www.example.com"],
  "enabled": true,
  "branding": {
    "name": "DocBot",
    "tagline": "Your documentation assistant",
    "logoUrl": "https://example.com/logo.png",
    "colors": {
      "primary": "#6366f1",
      "primaryForeground": "#ffffff",
      "background": "#ffffff",
      "foreground": "#1f2937",
      "bubbleBackground": "#f3f4f6",
      "userBubbleBackground": "#6366f1",
      "userBubbleForeground": "#ffffff"
    },
    "position": "bottom-right",
    "welcomeMessage": "Hi! Ask me anything about our docs.",
    "inputPlaceholder": "Ask a question..."
  },
  "ai": {
    "baseUrl": "http://localhost:11434/v1",
    "apiKey": "ollama",
    "model": "llama3",
    "temperature": 0.7,
    "maxTokens": 1024,
    "systemPromptPrefix": "You specialize in developer documentation. Always include code examples when relevant."
  },
  "guardrails": {
    "allowedTopics": ["documentation", "api", "setup", "troubleshooting"],
    "topicDescription": "Questions about our product documentation and API",
    "refusalMessage": "I can only help with documentation-related questions. Is there something else I can assist you with?",
    "blockedInputPatterns": [],
    "blockedOutputPatterns": [],
    "maxInputLength": 2000,
    "enablePromptInjectionDetection": true,
    "enableOutputScrubbing": true
  },
  "knowledge": {
    "sources": [
      {
        "type": "text",
        "title": "About Us",
        "content": "We build developer tools used by over 10,000 teams worldwide."
      },
      {
        "type": "faq",
        "entries": [
          {
            "question": "What are your support hours?",
            "answer": "Monday to Friday, 9am-5pm EST."
          }
        ]
      },
      {
        "type": "url",
        "url": "https://example.com/docs.md",
        "title": "Documentation",
        "refreshIntervalHours": 24
      },
      {
        "type": "file",
        "filePath": "product-guide.md",
        "title": "Product Guide"
      }
    ],
    "maxContextTokens": 4000
  },
  "tickets": {
    "enabled": true,
    "promptMessage": "Would you like me to create a support ticket for this issue?",
    "providers": [
      {
        "provider": "github",
        "owner": "your-org",
        "repo": "support",
        "token": "ghp_...",
        "labels": ["kody-ticket"]
      }
    ],
    "requiredFields": ["email", "description"]
  },
  "rateLimit": {
    "messagesPerMinute": 10,
    "messagesPerHour": 100,
    "messagesPerDay": 1000
  }
}