{
  "openapi": "3.1.0",
  "info": {
    "title": "SLAtech AI Platform API",
    "summary": "Conversational AI, RAG, and webhook surface for the SLAtech chatbot platform.",
    "description": "Official HTTP API for the SLAtech multi-vertical chatbot and RAG platform. This is the same surface the official JS SDK (@slatech/sdk) wraps; you can also call it directly. The API serves the network of sister sites (slatech.co.il, slatech.ru, slavin.pro, slavin.ai, slavin.org.il) and is the backend behind the public embed widget at api.slatech.ai/embed.js.\n\nAuthentication: Bearer token (API key) in the Authorization header. Get a key from the SLAtech dashboard.\n\nMulti-language: Hebrew, English, Russian, Arabic natively supported; pass `lang: 'auto'` for detection from the first user message.",
    "version": "1.0.0",
    "termsOfService": "https://www.slatech.co.il/Terms",
    "contact": {
      "name": "SLAtech LTD",
      "email": "info@slatech.co.il",
      "url": "https://www.slatech.co.il"
    },
    "license": {
      "name": "Proprietary (API access licensed per tenant)",
      "url": "https://www.slatech.co.il/Terms"
    }
  },
  "servers": [
    { "url": "https://api.slatech.ai/v1", "description": "Production" }
  ],
  "tags": [
    { "name": "conversations", "description": "Conversation lifecycle" },
    { "name": "messages", "description": "Send and stream messages" },
    { "name": "rag", "description": "Knowledge base — add/search/delete documents" },
    { "name": "webhooks", "description": "Webhook payloads (server → your endpoint)" }
  ],
  "paths": {
    "/conversations": {
      "post": {
        "tags": ["conversations"],
        "operationId": "createConversation",
        "summary": "Create a new conversation",
        "description": "Returns a conversation handle. Pass it to subsequent message calls.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateConversationRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Conversation created",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Conversation" } } }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/conversations/{conversationId}": {
      "get": {
        "tags": ["conversations"],
        "operationId": "getConversation",
        "summary": "Read a conversation and its message history",
        "parameters": [
          { "name": "conversationId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Conversation with full history",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationWithHistory" } } }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/chat/messages": {
      "post": {
        "tags": ["messages"],
        "operationId": "sendMessage",
        "summary": "Send a single message and get a full reply",
        "description": "Synchronous round-trip. Use for short replies or when you don't need streaming. For longer replies, prefer /chat/messages/stream.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendMessageRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assistant reply",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Message" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/chat/messages/stream": {
      "post": {
        "tags": ["messages"],
        "operationId": "streamMessage",
        "summary": "Stream a reply as Server-Sent Events",
        "description": "Returns text/event-stream with `data: {...}` chunks. Each chunk is a JSON `{ delta, conversationId, done }`. Terminates with `data: [DONE]`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendMessageRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SSE stream",
            "content": {
              "text/event-stream": {
                "schema": { "type": "string", "description": "Server-Sent Events stream of MessageChunk JSON objects" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/rag/documents": {
      "post": {
        "tags": ["rag"],
        "operationId": "addDocument",
        "summary": "Add or update a document in the RAG index",
        "description": "Re-sending the same documentId overwrites the existing entry. Content is chunked and embedded server-side.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AddDocumentRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Document indexed",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IndexedDocument" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/rag/documents/{documentId}": {
      "delete": {
        "tags": ["rag"],
        "operationId": "deleteDocument",
        "summary": "Remove a document from the RAG index",
        "parameters": [
          { "name": "documentId", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "204": { "description": "Deleted" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/rag/search": {
      "post": {
        "tags": ["rag"],
        "operationId": "searchKnowledge",
        "summary": "Search the RAG index without LLM generation",
        "description": "Returns top-k retrieved chunks. Use when you want raw retrieval (e.g. to display source documents to the user).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Top-k retrieved chunks",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key"
      }
    },
    "schemas": {
      "Language": {
        "type": "string",
        "enum": ["auto", "en", "he", "ru", "ar"],
        "description": "BCP-47-style locale or `auto` for first-message detection"
      },
      "CreateConversationRequest": {
        "type": "object",
        "properties": {
          "userId": { "type": "string", "description": "Your user identifier — anonymous if omitted" },
          "metadata": { "type": "object", "additionalProperties": true, "description": "Arbitrary JSON; surfaces in dashboard and webhooks" }
        }
      },
      "Conversation": {
        "type": "object",
        "required": ["conversationId", "createdAt"],
        "properties": {
          "conversationId": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "ConversationWithHistory": {
        "allOf": [
          { "$ref": "#/components/schemas/Conversation" },
          {
            "type": "object",
            "properties": {
              "messages": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/Message" }
              }
            }
          }
        ]
      },
      "Attachment": {
        "type": "object",
        "required": ["type", "url"],
        "properties": {
          "type": { "type": "string", "enum": ["image", "file"] },
          "url": { "type": "string", "format": "uri" }
        }
      },
      "SendMessageRequest": {
        "type": "object",
        "required": ["conversationId", "text"],
        "properties": {
          "conversationId": { "type": "string" },
          "text": { "type": "string" },
          "attachments": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Attachment" }
          },
          "lang": { "$ref": "#/components/schemas/Language" }
        }
      },
      "Citation": {
        "type": "object",
        "properties": {
          "documentId": { "type": "string" },
          "title": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "score": { "type": "number", "format": "float", "minimum": 0, "maximum": 1 }
        }
      },
      "Message": {
        "type": "object",
        "required": ["messageId", "conversationId", "role", "text", "createdAt"],
        "properties": {
          "messageId": { "type": "string" },
          "conversationId": { "type": "string" },
          "role": { "type": "string", "enum": ["user", "assistant"] },
          "text": { "type": "string" },
          "citations": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Citation" }
          },
          "lang": { "$ref": "#/components/schemas/Language" },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "AddDocumentRequest": {
        "type": "object",
        "required": ["documentId", "content"],
        "properties": {
          "documentId": { "type": "string", "description": "Stable identifier; re-sending overwrites" },
          "content": { "type": "string" },
          "contentType": {
            "type": "string",
            "enum": ["text/markdown", "text/plain", "text/html"],
            "default": "text/markdown"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Filterable on retrieval (e.g. section, lang, tenant)"
          }
        }
      },
      "IndexedDocument": {
        "type": "object",
        "required": ["documentId", "chunkCount"],
        "properties": {
          "documentId": { "type": "string" },
          "chunkCount": { "type": "integer" },
          "indexedAt": { "type": "string", "format": "date-time" }
        }
      },
      "SearchRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string" },
          "topK": { "type": "integer", "default": 5, "minimum": 1, "maximum": 50 },
          "filter": { "type": "object", "additionalProperties": true }
        }
      },
      "SearchResult": {
        "type": "object",
        "properties": {
          "documentId": { "type": "string" },
          "score": { "type": "number", "format": "float" },
          "chunk": { "type": "string" },
          "metadata": { "type": "object", "additionalProperties": true }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/SearchResult" }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": ["code", "message"],
        "properties": {
          "code": { "type": "string", "example": "invalid_api_key" },
          "message": { "type": "string", "example": "API key not recognized" }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "required": ["type", "conversationId", "createdAt"],
        "properties": {
          "type": {
            "type": "string",
            "enum": ["message.received", "message.completed", "conversation.escalated", "rag.document.indexed"]
          },
          "conversationId": { "type": "string" },
          "messageId": { "type": "string" },
          "documentId": { "type": "string" },
          "data": { "type": "object", "additionalProperties": true },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed input",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "RateLimited": {
        "description": "Slow down; retry after the Retry-After header value",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  },
  "security": [
    { "bearerAuth": [] }
  ],
  "externalDocs": {
    "description": "Full SDK documentation and examples",
    "url": "https://www.slatech.co.il/Glossary"
  }
}
