{
  "info": {
    "name": "QSC Quickstart",
    "description": "End-to-end workflow: define the schema, feed documents, then search — plus chat with a QSC Agent.\n\nImport an environment and set:\n- baseUrl\n- tenant / code\n- token (admin token — schema)\n- feedingToken (feeding token — data operations and scheduling)\n- chatTenant / chatCode (agent config tenant/code)\n- chatToken (agent-server static token)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    { "key": "baseUrl", "value": "<base-url>" },
    { "key": "tenant", "value": "<your-tenant>" },
    { "key": "code", "value": "<your-code>" },
    { "key": "token", "value": "<your-admin-token>" },
    { "key": "feedingToken", "value": "<your-feeding-token>" },
    { "key": "chatTenant", "value": "<your-agent-tenant>" },
    { "key": "chatCode", "value": "<your-agent-code>" },
    { "key": "chatToken", "value": "<your-agent-server-token>" }
  ],
  "item": [
    {
      "name": "1 – Schema",
      "description": "Define the field schema of the search app.",
      "item": [
        {
          "name": "Update schema",
          "request": {
            "method": "PUT",
            "header": [
              { "key": "X-QSC-Token", "value": "{{token}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/searchapp/schema/{{tenant}}/{{code}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "searchapp", "schema", "{{tenant}}", "{{code}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fields\": [\n    {\n      \"code\": \"name\",\n      \"dataType\": \"string\",\n      \"searchMode\": \"balanced\",\n      \"weight\": 3,\n      \"display\": true,\n      \"facet\": false,\n      \"sort\": false,\n      \"suggest\": true,\n      \"navigation\": false,\n      \"semantic\": false\n    },\n    {\n      \"code\": \"brand\",\n      \"dataType\": \"string\",\n      \"searchMode\": \"balanced\",\n      \"weight\": 2,\n      \"display\": true,\n      \"facet\": true,\n      \"sort\": false,\n      \"suggest\": false,\n      \"navigation\": false,\n      \"semantic\": false\n    },\n    {\n      \"code\": \"description\",\n      \"dataType\": \"string\",\n      \"searchMode\": \"balanced\",\n      \"weight\": 1,\n      \"display\": true,\n      \"facet\": false,\n      \"sort\": false,\n      \"suggest\": false,\n      \"navigation\": false,\n      \"semantic\": true\n    },\n    {\n      \"code\": \"price\",\n      \"dataType\": \"double\",\n      \"searchMode\": \"off\",\n      \"display\": true,\n      \"facet\": true,\n      \"sort\": true\n    }\n  ]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Defines the field schema for the search app. Run this first."
          },
          "response": []
        },
        {
          "name": "Schedule feeding job",
          "request": {
            "method": "PUT",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/job/{{tenant}}/{{code}}/feeding/_schedule",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "job", "{{tenant}}", "{{code}}", "feeding", "_schedule"]
            },
            "description": "Must be called after every schema update to trigger re-indexing."
          },
          "response": []
        }
      ]
    },
    {
      "name": "2 – Feeding",
      "description": "Push documents into the index. Uses the feeding token.",
      "item": [
        {
          "name": "Full feed – Start",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/data/fullfeed/start/{{tenant}}/{{code}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "data", "fullfeed", "start", "{{tenant}}", "{{code}}"]
            },
            "description": "Opens a full-feed cycle. Send all your documents next, then call 'Full feed – End'."
          },
          "response": []
        },
        {
          "name": "Bulk update",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/data/bulk/qsc/{{tenant}}/{{code}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "data", "bulk", "qsc", "{{tenant}}", "{{code}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "[\n  {\n    \"header\": { \"id\": \"product-1\", \"action\": \"update\" },\n    \"payload\": {\n      \"name\": \"Running Shoes Pro\",\n      \"brand\": \"Acme\",\n      \"description\": \"Lightweight trail running shoes.\",\n      \"price\": 129.99\n    }\n  },\n  {\n    \"header\": { \"id\": \"product-2\", \"action\": \"update\" },\n    \"payload\": {\n      \"name\": \"Trail Boots X\",\n      \"brand\": \"Acme\",\n      \"description\": \"Durable boots for rough terrain.\",\n      \"price\": 89.99\n    }\n  },\n  {\n    \"header\": { \"id\": \"product-3\", \"action\": \"update\" },\n    \"payload\": {\n      \"name\": \"City Sneaker\",\n      \"brand\": \"Stride\",\n      \"description\": \"Comfortable everyday sneaker.\",\n      \"price\": 59.99\n    }\n  }\n]",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Sends multiple documents in one request. Each entry has a header (id + action) and a payload (document fields)."
          },
          "response": []
        },
        {
          "name": "Full feed – End",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": { "raw": { "language": "json" } }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/data/fullfeed/end/{{tenant}}/{{code}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "data", "fullfeed", "end", "{{tenant}}", "{{code}}"]
            },
            "description": "Closes the full-feed cycle and swaps the index. Documents not sent since Start are removed."
          },
          "response": []
        },
        {
          "name": "Update single document",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/data/qsc/{{tenant}}/{{code}}/product-1",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "data", "qsc", "{{tenant}}", "{{code}}", "product-1"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"header\": { \"id\": \"product-1\", \"action\": \"update\" },\n  \"payload\": {\n    \"name\": \"Running Shoes Pro\",\n    \"brand\": \"Acme\",\n    \"description\": \"Lightweight trail running shoes with superior grip.\",\n    \"price\": 129.99\n  }\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Creates or updates a single document."
          },
          "response": []
        },
        {
          "name": "Delete document",
          "request": {
            "method": "DELETE",
            "header": [
              { "key": "X-QSC-Token", "value": "{{feedingToken}}" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/data/qsc/{{tenant}}/{{code}}/product-1",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "data", "qsc", "{{tenant}}", "{{code}}", "product-1"]
            },
            "description": "Marks a document for deletion from the index."
          },
          "response": []
        }
      ]
    },
    {
      "name": "3 – Search",
      "description": "Query the indexed documents. No token required.",
      "item": [
        {
          "name": "Search with filter (GET)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/search/{{tenant}}/{{code}}?q=shoes&page=1&rows=10&f.brand=Acme",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "search", "{{tenant}}", "{{code}}"],
              "query": [
                { "key": "q", "value": "shoes" },
                { "key": "page", "value": "1" },
                { "key": "rows", "value": "10" },
                { "key": "f.brand", "value": "Acme" }
              ]
            },
            "description": "Search with a term filter via GET query parameters."
          },
          "response": []
        },
        {
          "name": "Search with filters and sort (POST)",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/search/{{tenant}}/{{code}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "search", "{{tenant}}", "{{code}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"q\": \"shoes\",\n  \"page\": 1,\n  \"rows\": 10,\n  \"sort\": {\n    \"sort\": \"pricedesc\"\n  },\n  \"filters\": {\n    \"brand\": {\n      \"values\": [\"Acme\"]\n    }\n  }\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Search with filter and sort via POST body."
          },
          "response": []
        },
        {
          "name": "Suggest",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/search/suggest/{{tenant}}/{{code}}?q=runn&rows=5",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "search", "suggest", "{{tenant}}", "{{code}}"],
              "query": [
                { "key": "q", "value": "runn" },
                { "key": "rows", "value": "5" }
              ]
            },
            "description": "Autocomplete suggestions for a partial query."
          },
          "response": []
        }
      ]
    },
    {
      "name": "4 – Chat",
      "description": "Talk to a QSC Agent, served by the agent-server backend. Uses baseUrl but a different token (chatToken) and agent identity (chatTenant/chatCode).",
      "item": [
        {
          "name": "Init session",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{chatToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/agent/chat/{{chatTenant}}/{{chatCode}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "agent", "chat", "{{chatTenant}}", "{{chatCode}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"init\",\n  \"sessionId\": \"{{$guid}}\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Starts a session and returns the configured welcome message and model list. Run this first and reuse the sessionId in subsequent calls."
          },
          "response": []
        },
        {
          "name": "Chat",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{chatToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/agent/chat/{{chatTenant}}/{{chatCode}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "agent", "chat", "{{chatTenant}}", "{{chatCode}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"What running shoes do you have under 100 euros?\",\n  \"sessionId\": \"{{$guid}}\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Sends a message and gets a single JSON response back."
          },
          "response": []
        },
        {
          "name": "Chat with attachment",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{chatToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/agent/chat/{{chatTenant}}/{{chatCode}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "agent", "chat", "{{chatTenant}}", "{{chatCode}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"What's in this image?\",\n  \"sessionId\": \"{{$guid}}\",\n  \"model\": \"haystack:gpt-4o-mini\",\n  \"attachments\": [\n    {\n      \"name\": \"pixel.png\",\n      \"mimeType\": \"image/png\",\n      \"data\": \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGNgAAACAAEAyPw4gwAAAABJRU5ErkJggg==\"\n    }\n  ]\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Sends a message with an inline base64 attachment (a 1x1 pixel PNG placeholder). Attachments are only supported for haystack: models — point chatTenant/chatCode at an agent config using a vision-capable haystack: model."
          },
          "response": []
        },
        {
          "name": "Streaming chat",
          "request": {
            "method": "POST",
            "header": [
              { "key": "X-QSC-Token", "value": "{{chatToken}}" },
              { "key": "Content-Type", "value": "application/json" }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/agent/chat/streaming/{{chatTenant}}/{{chatCode}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "agent", "chat", "streaming", "{{chatTenant}}", "{{chatCode}}"]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"text\": \"What running shoes do you have under 100 euros?\",\n  \"sessionId\": \"{{$guid}}\"\n}",
              "options": { "raw": { "language": "json" } }
            },
            "description": "Same as Chat, but the body is a stream of newline-delimited JSON objects — delta chunks followed by one final message."
          },
          "response": []
        }
      ]
    }
  ]
}
