{
  "openapi": "3.1.0",
  "info": {
    "title": "Mediflo External API — v1",
    "version": "1.0.0",
    "description": "Headless configuration and operation of Mediflo voice bots.\n\nAuthentication: `Authorization: Bearer mflo_…`. Every route declares the\nscope it requires; a key without it gets 403 `API_KEY_INSUFFICIENT_SCOPE`.\n\nErrors always take the shape `{ error: { code, message, details? } }`.\nBranch on `code` — the message is localized and may change.\nValidation failures use `VALIDATION_ERROR` with `details` as an array of\n`{ field, message }`.\n\nLists always return `{ data, pagination: { page, limit, total, totalPages } }`.\n\nRate limiting is per key; a 429 carries `Retry-After` in seconds."
  },
  "servers": [
    {
      "url": "https://app.mediflo.ai/api/external/v1"
    }
  ],
  "tags": [
    {
      "name": "Bots",
      "description": "Create and configure voice bots."
    },
    {
      "name": "Bot configuration",
      "description": "The draft/publish model: edit a draft freely, publish it to make it live, roll back to any published snapshot."
    },
    {
      "name": "Workflows",
      "description": "Conversation graphs. Start from a template, validate statelessly, then activate."
    },
    {
      "name": "Procedures",
      "description": "Ordered, reusable skills a bot follows during a call — free-form or deterministic steps with tool gates."
    },
    {
      "name": "Knowledge",
      "description": "Per-bot RAG knowledge base."
    },
    {
      "name": "Locations",
      "description": "Bot prerequisite."
    },
    {
      "name": "Phone numbers",
      "description": "Read-only inventory plus the one-call inbound attach. Provisioning is not part of this API."
    },
    {
      "name": "Vocabularies",
      "description": "Read-only reference data for authoring valid payloads."
    },
    {
      "name": "Webhooks",
      "description": "Endpoints you register to receive signed events, and the delivery log with redelivery."
    },
    {
      "name": "Bot sessions",
      "description": "What actually happened on a call. Diagnostics and conversation content are separate endpoints, so you can debug without pulling caller speech."
    },
    {
      "name": "Support tickets",
      "description": "File a problem with Mediflo support, with the offending bot sessions attached so we can investigate."
    },
    {
      "name": "Cases",
      "description": "Customer cases: one record per customer issue across calls and conversations — status, priority, category, assignee, internal notes and links to the calls and conversations it came from. For business organisations with cases switched on; scopes `cases.read` / `cases.write`, granted by name only."
    },
    {
      "name": "Scheduling",
      "description": "Terminarz Mediflo: the clinic's own appointment book — visit types, specialists, free slots, bookings, reschedules and cancellations. Caller-bound integrations use `scheduling.book` / `scheduling.modify` with action tokens; staff and partner integrations use `scheduling.manage` with appointment ids and `expectedVersion`."
    },
    {
      "name": "Patients",
      "description": "Recognise a returning patient by phone number. Names come back masked and patients are named by an opaque reference."
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An external API key, sent as `Authorization: Bearer mflo_…`. Scopes are checked per route; see each operation’s description."
      }
    },
    "schemas": {
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          }
        },
        "required": [
          "page",
          "limit",
          "total",
          "totalPages"
        ]
      },
      "ValidationIssue": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "field",
          "message"
        ]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable code — branch on this, not on the message."
              },
              "message": {
                "type": "string"
              },
              "details": {}
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Bot": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "priority": {
            "type": "integer"
          },
          "maxConcurrentCalls": {
            "type": "integer"
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "WEB_CHAT",
                "VOICE_INBOUND",
                "VOICE_OUTBOUND"
              ]
            },
            "minItems": 1,
            "description": "Channels the bot serves. Binding it to the website chat adds WEB_CHAT; attaching it to a phone number adds VOICE_INBOUND; a caller-ID number implies VOICE_OUTBOUND."
          },
          "locationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ]
          },
          "phoneNumberId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "phoneNumber": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "phoneNumber": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "phoneNumber"
            ]
          },
          "currentConfigSnapshotId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Null means the bot has never been published and cannot be dispatched."
          },
          "operatingHours": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "dayOfWeek": {
                  "type": "integer"
                },
                "startTime": {
                  "type": "string"
                },
                "endTime": {
                  "type": "string"
                }
              },
              "required": [
                "dayOfWeek",
                "startTime",
                "endTime"
              ]
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "isActive",
          "priority",
          "maxConcurrentCalls",
          "country",
          "channels",
          "locationId",
          "location",
          "phoneNumberId",
          "phoneNumber",
          "currentConfigSnapshotId",
          "operatingHours",
          "createdAt",
          "updatedAt"
        ]
      },
      "BotConfig": {
        "type": "object",
        "properties": {
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Send back as `expectedUpdatedAt` for optimistic concurrency."
          },
          "agentPromptText": {
            "type": [
              "string",
              "null"
            ]
          },
          "remarksPromptText": {
            "type": [
              "string",
              "null"
            ]
          },
          "remarksLlmModelId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Post-call extraction model, configured by Mediflo (seeded when the bot is created). Required to publish."
          },
          "remarksFallbackLlmModelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "remarksTemperature": {
            "type": [
              "number",
              "null"
            ]
          },
          "remarksOutputSchemaJson": {},
          "toolsConfig": {
            "description": "MCP servers, generic HTTPS tools (http_tools), and per-tool parameter_bindings. Secret values are always masked on read."
          },
          "guardrailsConfig": {},
          "greetingConfig": {
            "description": "How a voice call opens. The shared greeting is `{type: \"static\", text, allowInterruptions}`, `{type: \"llm\", prompt, allowInterruptions}` or `{type: \"none\"}` (no scripted line — the bot improvises an opener). Optional `byDirection: {inbound?, outbound?}` overrides it per call direction; each entry is `static`, `llm` or `{type: \"off\"}`, where `off` means the bot does NOT speak first and waits for the caller — if the caller stays silent for about 4 s the bot improvises an opener so the line never dies (`none` is not allowed per direction). A missing direction key keeps the shared greeting for that direction. Web chat has no direction and ignores `byDirection`. Precedence at call time: workflow opener, then the session-init hook `opener`, then this greeting."
          },
          "channelSettings": {
            "description": "Per-channel overrides. Today only `webChat`: `greeting` (`{type: \"static\", text}` | `{type: \"llm\", prompt}` | `{type: \"none\"}`) replaces `greetingConfig` for website chat; `handoffMessage` is the notice when the bot hands the thread to a person; `guardrailFallbackMessage` replaces a blocked guardrail’s fallback on this channel. Null when unset."
          },
          "sessionInitConfig": {
            "description": "Optional per-call HTTPS hook fired once at dispatch; its JSON response merges into session variables and `opener` overrides the greeting. Fails open by contract."
          },
          "turnTakingMode": {
            "type": [
              "string",
              "null"
            ]
          },
          "promptVariableMetadata": {},
          "modelConfig": {
            "description": "The bot’s models. Configured by Mediflo: present only for a key that carries a Mediflo staff member’s authority, absent for every other key."
          },
          "currentConfigSnapshotId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "entryProcedureId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The DETERMINISTIC procedure that drives the whole call, or null. This is the DRAFT pointer; the flow the bot runs comes from the published snapshot. A bot cannot have both an entry procedure and an active workflow — publish refuses that combination."
          }
        },
        "required": [
          "botId",
          "updatedAt",
          "agentPromptText",
          "remarksPromptText",
          "remarksLlmModelId",
          "remarksFallbackLlmModelIds",
          "remarksTemperature",
          "turnTakingMode",
          "currentConfigSnapshotId",
          "entryProcedureId"
        ]
      },
      "ConfigSnapshot": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "version": {
            "type": "integer"
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "version",
          "label",
          "publishedAt"
        ]
      },
      "PublishWarning": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable identifier, e.g. PROCEDURE_TRIGGER_OVERLAP, PROCEDURE_TOOL_UNKNOWN, HTTP_TOOL_GATES_NOT_ENFORCED, PROCEDURES_CONTEXT_BUDGET_WARNING."
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation of the finding."
          },
          "procedureId": {
            "type": "string",
            "format": "uuid",
            "description": "The procedure the finding belongs to, when it names one."
          },
          "path": {
            "type": "string",
            "description": "Dotted path into the config the finding refers to."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "SkillRefWarning": {
        "type": "object",
        "properties": {
          "nodeId": {
            "type": "string",
            "description": "The workflow node carrying the pin, by its stable id."
          },
          "skillRef": {
            "type": "string",
            "format": "uuid",
            "description": "The free-form procedure (\"skill\") the node pins."
          }
        },
        "required": [
          "nodeId",
          "skillRef"
        ]
      },
      "WorkflowSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "version": {
            "type": "integer",
            "description": "Send back as `expectedVersion` on PUT for optimistic concurrency."
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "botId",
          "name",
          "description",
          "version",
          "isActive",
          "createdAt",
          "updatedAt"
        ]
      },
      "WorkflowDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WorkflowSummary"
          },
          {
            "type": "object",
            "properties": {
              "definition": {}
            }
          }
        ]
      },
      "WorkflowValidationResult": {
        "type": "object",
        "properties": {
          "valid": {
            "type": "boolean"
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string"
                },
                "nodeId": {
                  "type": "string"
                },
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "valid",
          "issues"
        ]
      },
      "Procedure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "description": "Dashboard-only label. NEVER sent to the model — the trigger is what the model sees."
          },
          "type": {
            "type": "string",
            "enum": [
              "FREE_FORM",
              "DETERMINISTIC"
            ],
            "description": "FREE_FORM is a playbook the model reaches for mid-call when its trigger matches. DETERMINISTIC is an ordered flow compiled into the call at publish; the model cannot activate one."
          },
          "trigger": {
            "type": [
              "string",
              "null"
            ],
            "description": "Natural-language activation trigger. Required for FREE_FORM, always null for DETERMINISTIC."
          },
          "content": {
            "description": "FREE_FORM: {markdown}. DETERMINISTIC: {steps: [...]} — ask / say / tell / branch / tool_call / verify_identity / sub_procedure / end_call."
          },
          "position": {
            "type": "integer",
            "description": "Manual ordering within the bot; also drives the node ids of the compiled call flow."
          },
          "enabled": {
            "type": "boolean",
            "description": "Live kill switch. A disabled procedure is dropped at dispatch even from an already-published snapshot — no re-publish needed."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "botId",
          "name",
          "type",
          "trigger",
          "position",
          "enabled",
          "createdAt",
          "updatedAt"
        ]
      },
      "ProcedureList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Procedure"
            }
          },
          "entryProcedureId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The bot’s DRAFT entry procedure. Belongs to the bot, not to a page of procedures."
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "entryProcedureId",
          "pagination"
        ]
      },
      "KnowledgeBase": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "isEnabled": {
            "type": "boolean"
          },
          "hasIndexedVersion": {
            "type": "boolean"
          },
          "settings": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "retrievalMode": {
                "type": "string",
                "enum": [
                  "auto",
                  "every_turn",
                  "off"
                ]
              },
              "requireKnowledge": {
                "type": "boolean"
              },
              "maxCharacters": {
                "type": "integer",
                "minimum": 200,
                "maximum": 20000
              },
              "maxChunks": {
                "type": "integer",
                "minimum": 1,
                "maximum": 20
              },
              "maxVectorDistance": {
                "type": "number",
                "minimum": 0,
                "maximum": 2
              },
              "searchDepth": {
                "type": "integer",
                "minimum": 1,
                "maximum": 500
              },
              "timeoutMs": {
                "type": "integer",
                "minimum": 1,
                "maximum": 5000
              },
              "requiredTimeoutMs": {
                "type": "integer",
                "minimum": 1,
                "maximum": 5000
              }
            },
            "required": [
              "enabled",
              "retrievalMode",
              "requireKnowledge",
              "maxCharacters",
              "maxChunks",
              "maxVectorDistance",
              "searchDepth",
              "timeoutMs",
              "requiredTimeoutMs"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "isEnabled",
          "hasIndexedVersion",
          "settings",
          "updatedAt"
        ]
      },
      "KnowledgeSource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sourceType": {
            "type": "string"
          },
          "articleType": {
            "type": [
              "string",
              "null"
            ]
          },
          "usageMode": {
            "type": [
              "string",
              "null"
            ]
          },
          "publishState": {
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastVerifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": [
              "string",
              "null"
            ]
          },
          "errorMessage": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "sourceType",
          "articleType",
          "usageMode",
          "publishState",
          "tags",
          "category",
          "lastVerifiedAt",
          "expiresAt",
          "title",
          "status",
          "errorMessage",
          "createdAt",
          "updatedAt"
        ]
      },
      "KnowledgeSourceDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/KnowledgeSource"
          },
          {
            "type": "object",
            "properties": {
              "bodyText": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "extractedText": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "structuredContent": {},
              "questionVariants": {},
              "characterCount": {
                "type": "integer"
              },
              "file": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "size": {
                    "type": "integer"
                  }
                },
                "required": [
                  "id",
                  "name",
                  "type",
                  "size"
                ]
              }
            },
            "required": [
              "bodyText",
              "extractedText",
              "characterCount",
              "file"
            ]
          }
        ]
      },
      "Location": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "street": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "postalCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "fullAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "timezone": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "code",
          "street",
          "city",
          "postalCode",
          "country",
          "fullAddress",
          "phone",
          "email",
          "timezone",
          "isActive",
          "instructions",
          "createdAt",
          "updatedAt"
        ]
      },
      "PhoneNumber": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "phoneNumber": {
            "type": "string"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "hasInboundFlow": {
            "type": "boolean",
            "description": "True when the number already routes through an IVR flow."
          },
          "bots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name"
              ]
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "phoneNumber",
          "displayName",
          "isActive",
          "hasInboundFlow",
          "bots",
          "createdAt"
        ]
      },
      "BotReadiness": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "boolean",
            "description": "Can the bot serve at all: published config and bot active. A chat-only bot also needs its chat widget bound. Informational checks never affect it. Does NOT imply outbound calls or website chat."
          },
          "readyForOutbound": {
            "type": "boolean",
            "description": "The bot serves VOICE_OUTBOUND, `ready` is true, and the phone chain is dispatchable. False for a chat-only bot — do not bind a number to clear it."
          },
          "readyForWebChat": {
            "type": "boolean",
            "description": "The bot serves WEB_CHAT, `ready` is true, and the chat widget is bound and able to answer. False when the bot has no website-chat channel. Binding the widget is done in the Portal."
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "WEB_CHAT",
                "VOICE_INBOUND",
                "VOICE_OUTBOUND"
              ]
            },
            "description": "The channels this verdict was computed for."
          },
          "checks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "ok": {
                  "type": "boolean"
                },
                "message": {
                  "type": "string"
                },
                "requiredFor": {
                  "type": "string",
                  "enum": [
                    "outbound",
                    "web_chat"
                  ]
                },
                "informational": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "ok",
                "message"
              ]
            }
          }
        },
        "required": [
          "ready",
          "readyForOutbound",
          "readyForWebChat",
          "channels",
          "checks"
        ]
      },
      "AttachBotResult": {
        "type": "object",
        "properties": {
          "phoneNumberId": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "flowId": {
            "type": "string",
            "format": "uuid"
          },
          "created": {
            "type": "boolean",
            "description": "False when an existing generated flow was reused."
          }
        },
        "required": [
          "phoneNumberId",
          "botId",
          "flowId",
          "created"
        ]
      },
      "ModelCatalog": {
        "type": "object",
        "properties": {
          "models": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "catalogKey": {
                  "type": "string"
                },
                "modality": {
                  "type": "string",
                  "enum": [
                    "stt",
                    "tts",
                    "llm"
                  ]
                },
                "vendor": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "providers": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "languages": {},
                "capabilities": {}
              },
              "required": [
                "catalogKey",
                "modality",
                "vendor",
                "displayName",
                "providers"
              ]
            },
            "description": "Configured by Mediflo: returned only to a key that carries a Mediflo staff member’s authority, absent for every other key."
          },
          "recommendedChains": {
            "type": "object",
            "additionalProperties": {},
            "description": "Configured by Mediflo: returned only to a key that carries a Mediflo staff member’s authority, absent for every other key."
          },
          "extractionModels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Pass as `remarksLlmModelId` on PATCH /bots/{id}/config."
                },
                "provider": {
                  "type": "string"
                },
                "modelId": {
                  "type": "string"
                },
                "displayName": {
                  "type": "string"
                },
                "supportsStructuredOutput": {
                  "type": "boolean",
                  "enum": [
                    true
                  ]
                },
                "maxContextTokens": {
                  "type": "integer"
                },
                "maxOutputTokens": {
                  "type": "integer"
                },
                "isDefault": {
                  "type": "boolean",
                  "description": "The model a newly created bot is seeded with."
                }
              },
              "required": [
                "id",
                "provider",
                "modelId",
                "displayName",
                "supportsStructuredOutput",
                "maxContextTokens",
                "maxOutputTokens",
                "isDefault"
              ]
            },
            "description": "Post-call extraction (remarks) models — a different catalog from `models`, which configures the live voice pipeline. Only structured-output-capable models are listed, because extraction runs the remarks schema as structured output, and the list is CURATED: it carries exactly the models Mediflo recommends, in that order. Writing any other model is rejected. Configured by Mediflo: returned only to a key that carries a Mediflo staff member’s authority, absent for every other key."
          },
          "recommendedDefaults": {
            "type": "object",
            "properties": {
              "modelConfig": {
                "description": "Apply verbatim as a bot `modelConfig`. Configured by Mediflo: returned only to a key that carries a Mediflo staff member’s authority, absent for every other key."
              },
              "turnTakingMode": {
                "type": "string",
                "enum": [
                  "eager",
                  "regular",
                  "lazy"
                ]
              },
              "extraction": {
                "type": "object",
                "properties": {
                  "defaultModelId": {
                    "type": "string",
                    "description": "`LlmModel.modelId` (not a catalog key)."
                  },
                  "allowedModelIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "defaultModelId",
                  "allowedModelIds"
                ],
                "description": "Configured by Mediflo: returned only to a key that carries a Mediflo staff member’s authority, absent for every other key."
              },
              "rag": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "retrievalMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "every_turn",
                      "off"
                    ]
                  },
                  "requireKnowledge": {
                    "type": "boolean"
                  },
                  "maxChunks": {
                    "type": "integer"
                  },
                  "maxCharacters": {
                    "type": "integer"
                  },
                  "maxVectorDistance": {
                    "type": "number"
                  },
                  "searchDepth": {
                    "type": "integer"
                  },
                  "timeoutMs": {
                    "type": "integer"
                  },
                  "requiredTimeoutMs": {
                    "type": "integer"
                  }
                },
                "required": [
                  "enabled",
                  "retrievalMode",
                  "requireKnowledge",
                  "maxChunks",
                  "maxCharacters",
                  "maxVectorDistance",
                  "searchDepth",
                  "timeoutMs",
                  "requiredTimeoutMs"
                ],
                "description": "Knowledge-base retrieval settings a new bot’s knowledge base is created with."
              }
            },
            "required": [
              "turnTakingMode",
              "rag"
            ],
            "description": "Mediflo’s recommended out-of-the-box settings. `POST /bots` already applies these; this block is here so an agent can re-apply or diff them without hardcoding values."
          }
        },
        "required": [
          "recommendedDefaults"
        ]
      },
      "EventTypeCatalog": {
        "type": "object",
        "properties": {
          "eventTypes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "ping",
                    "bot_call.completed",
                    "call.completed",
                    "call.updated",
                    "call.transcript.ready",
                    "call.analysis.completed",
                    "task.created",
                    "task.updated",
                    "task.deleted",
                    "task.suggestion.resolved",
                    "case.created",
                    "case.updated",
                    "case.deleted",
                    "webhook_endpoint.auto_disabled"
                  ]
                },
                "family": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "availableBlocks": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "phoneNumbers",
                      "outcome",
                      "transcript",
                      "recordingUrl",
                      "contact"
                    ]
                  }
                },
                "phiBlocks": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "phoneNumbers",
                      "outcome",
                      "transcript",
                      "recordingUrl",
                      "contact"
                    ]
                  }
                },
                "sampleEnvelope": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Prefixed `evt_sample_` so it can never be mistaken for, or collide with, a delivered event id (`evt_<uuid>`)."
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "ping",
                        "bot_call.completed",
                        "call.completed",
                        "call.updated",
                        "call.transcript.ready",
                        "call.analysis.completed",
                        "task.created",
                        "task.updated",
                        "task.deleted",
                        "task.suggestion.resolved",
                        "case.created",
                        "case.updated",
                        "case.deleted",
                        "webhook_endpoint.auto_disabled"
                      ]
                    },
                    "apiVersion": {
                      "type": "string"
                    },
                    "occurredAt": {
                      "type": "string",
                      "description": "A fixed instant, so the sample is byte-stable between reads."
                    },
                    "data": {
                      "description": "The per-event payload, with ALL content blocks present. A real delivery carries only the blocks that endpoint opted into."
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "apiVersion",
                    "occurredAt"
                  ],
                  "description": "The complete wire envelope with an obviously-fake, non-PHI payload — code against this without provoking a real event. Generated from the same module the producers are validated against, so it cannot describe a shape we do not send."
                }
              },
              "required": [
                "type",
                "family",
                "description",
                "availableBlocks",
                "phiBlocks",
                "sampleEnvelope"
              ]
            }
          },
          "payloadBlocks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "phoneNumbers",
                "outcome",
                "transcript",
                "recordingUrl",
                "contact"
              ]
            }
          },
          "phiBlocks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "eventTypes",
          "payloadBlocks",
          "phiBlocks"
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "subscribedEvents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Event types, or `[\"*\"]` for every event."
          },
          "payloadConfig": {
            "description": "Opted-in content blocks per event family, e.g. `{\"call\":[\"outcome\"]}`. `null` means core fields only."
          },
          "status": {
            "type": "string",
            "enum": [
              "ENABLED",
              "DISABLED",
              "AUTO_DISABLED"
            ]
          },
          "consecutiveFailures": {
            "type": "integer"
          },
          "lastSuccessAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastFailureAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "autoDisabledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "previousSecretExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "description": "While set and in the future, deliveries carry a SECOND `v1=` signature computed with the previous secret."
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "subscribedEvents",
          "status",
          "consecutiveFailures",
          "lastSuccessAt",
          "lastFailureAt",
          "autoDisabledAt",
          "previousSecretExpiresAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "WebhookEndpointWithSecret": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          {
            "type": "object",
            "properties": {
              "secret": {
                "type": "string",
                "description": "`whsec_…`. Shown ONCE. Store it now; it cannot be read back."
              }
            },
            "required": [
              "secret"
            ]
          }
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "endpointId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "RETRYING",
              "SUCCEEDED",
              "EXHAUSTED",
              "SKIPPED"
            ]
          },
          "attemptCount": {
            "type": "integer"
          },
          "nextAttemptAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastHttpStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lastErrorCode": {
            "type": [
              "string",
              "null"
            ],
            "description": "One of `timeout`, `network`, `redirect`, `ssrf_blocked`, `invalid_url`, `secret_unavailable`, or `http_<status>`."
          },
          "lastErrorMessage": {
            "type": [
              "string",
              "null"
            ],
            "description": "OUR diagnostic. Your endpoint’s response body is never stored or returned."
          },
          "lastLatencyMs": {
            "type": [
              "integer",
              "null"
            ]
          },
          "deliveredAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          },
          "event": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "`evt_…` — matches the delivered envelope’s `id`."
              },
              "type": {
                "type": "string",
                "enum": [
                  "ping",
                  "bot_call.completed",
                  "call.completed",
                  "call.updated",
                  "call.transcript.ready",
                  "call.analysis.completed",
                  "task.created",
                  "task.updated",
                  "task.deleted",
                  "task.suggestion.resolved",
                  "case.created",
                  "case.updated",
                  "case.deleted",
                  "webhook_endpoint.auto_disabled"
                ]
              },
              "occurredAt": {
                "type": "string"
              },
              "resourceType": {
                "type": "string"
              },
              "resourceId": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "type",
              "occurredAt",
              "resourceType",
              "resourceId"
            ]
          }
        },
        "required": [
          "id",
          "endpointId",
          "status",
          "attemptCount",
          "nextAttemptAt",
          "lastAttemptAt",
          "lastHttpStatus",
          "lastErrorCode",
          "lastErrorMessage",
          "lastLatencyMs",
          "deliveredAt",
          "createdAt",
          "event"
        ]
      },
      "WebhookDeliveryAccepted": {
        "type": "object",
        "properties": {
          "deliveryId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "deliveryId"
        ]
      },
      "WebhookDeliveredPayload": {
        "type": "object",
        "properties": {
          "deliveryId": {
            "type": "string",
            "format": "uuid"
          },
          "endpointId": {
            "type": "string",
            "format": "uuid"
          },
          "payloadConfig": {
            "description": "The endpoint’s block opt-ins AS THEY ARE NOW — we keep no history of them. If they changed after this delivery, `envelope.data` is what this endpoint would receive for this event today, not a historical record."
          },
          "isTest": {
            "type": "boolean",
            "description": "True when the delivery came from the test-send route."
          },
          "envelope": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "`evt_…` — the value that arrived in `Mediflo-Event-Id`."
              },
              "type": {
                "type": "string",
                "enum": [
                  "ping",
                  "bot_call.completed",
                  "call.completed",
                  "call.updated",
                  "call.transcript.ready",
                  "call.analysis.completed",
                  "task.created",
                  "task.updated",
                  "task.deleted",
                  "task.suggestion.resolved",
                  "case.created",
                  "case.updated",
                  "case.deleted",
                  "webhook_endpoint.auto_disabled"
                ]
              },
              "apiVersion": {
                "type": "string"
              },
              "occurredAt": {
                "type": "string"
              },
              "data": {
                "type": "object",
                "additionalProperties": {},
                "description": "Content blocks this endpoint opted into, and nothing else — never the internal superset."
              }
            },
            "required": [
              "id",
              "type",
              "apiVersion",
              "occurredAt",
              "data"
            ],
            "description": "A re-serialization, not the signed bytes: key order and spacing are not necessarily what was hashed, so never verify a signature against this."
          }
        },
        "required": [
          "deliveryId",
          "endpointId",
          "isTest",
          "envelope"
        ]
      },
      "WebhookTestEventAccepted": {
        "type": "object",
        "properties": {
          "deliveryId": {
            "type": "string",
            "format": "uuid"
          },
          "eventType": {
            "type": "string",
            "enum": [
              "ping",
              "bot_call.completed",
              "call.completed",
              "call.updated",
              "call.transcript.ready",
              "call.analysis.completed",
              "task.created",
              "task.updated",
              "task.deleted",
              "task.suggestion.resolved",
              "case.created",
              "case.updated",
              "case.deleted",
              "webhook_endpoint.auto_disabled"
            ]
          }
        },
        "required": [
          "deliveryId",
          "eventType"
        ]
      },
      "WebhookEndpointDeleted": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "deleted"
        ]
      },
      "BotSession": {
        "type": "object",
        "properties": {
          "dispatchId": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "botName": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "IN_PROGRESS",
              "COMPLETED",
              "FAILED",
              "NO_ANSWER",
              "VOICEMAIL",
              "DISCONNECTED"
            ],
            "description": "DERIVED, not stored: `IN_PROGRESS` while the call has no duration yet, otherwise mapped from `endReason`. An end reason we do not recognise reports as `COMPLETED`."
          },
          "endReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Raw reason string as the bot reported it."
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Null while the session is in progress. Derived from the submission that closes the call, so treat it as \"finished around then\", not to the millisecond."
          },
          "durationSec": {
            "type": [
              "integer",
              "null"
            ]
          },
          "phoneNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "attemptId": {
            "type": "string"
          },
          "hasTranscript": {
            "type": "boolean"
          },
          "hasRecording": {
            "type": "boolean"
          },
          "hasTelemetry": {
            "type": "boolean"
          }
        },
        "required": [
          "dispatchId",
          "botId",
          "botName",
          "status",
          "endReason",
          "startedAt",
          "endedAt",
          "durationSec",
          "phoneNumber",
          "attemptId",
          "hasTranscript",
          "hasRecording",
          "hasTelemetry"
        ]
      },
      "BotSessionDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BotSession"
          },
          {
            "type": "object",
            "properties": {
              "outcome": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": {},
                "description": "The bot's own structured result for the call, in the shape that bot's remarks schema defines."
              },
              "links": {
                "type": "object",
                "properties": {
                  "telemetry": {
                    "type": "string"
                  },
                  "transcript": {
                    "type": "string"
                  },
                  "recording": {
                    "type": "string"
                  }
                },
                "required": [
                  "telemetry",
                  "transcript",
                  "recording"
                ]
              }
            },
            "required": [
              "outcome",
              "links"
            ]
          }
        ]
      },
      "BotSessionTelemetry": {
        "type": "object",
        "properties": {
          "dispatchId": {
            "type": "string",
            "format": "uuid"
          },
          "closeReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "closeError": {
            "type": [
              "string",
              "null"
            ]
          },
          "shutdownReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "sipError": {
            "type": [
              "string",
              "null"
            ]
          },
          "userEverSpoke": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "totalSilenceTimeouts": {
            "type": [
              "number",
              "null"
            ]
          },
          "trackerDurationS": {
            "type": [
              "number",
              "null"
            ]
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "source": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "message": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "timestamp": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              },
              "required": [
                "source",
                "message",
                "timestamp"
              ]
            }
          },
          "pipelineMetrics": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {},
            "description": "Per-modality (`llm`, `stt`, `tts`, `eou`) latency and throughput. Numeric leaves only. Key names are bot-version-owned — `avg_ttft` in one generation, `avg_ttft_s` in another — so read them defensively."
          },
          "falseInterruptions": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {}
          },
          "transcriptCounters": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {},
            "description": "Speech-recognition COUNTERS (how many finals/interims). Never the recognised text."
          },
          "other": {
            "type": "object",
            "additionalProperties": {},
            "description": "A curated set of further diagnostics: call timing, silence and speech-recognition counters, detector flags, and the workflow path (nodes only, never what was collected). Best-effort and version-dependent — the named fields above are the contract."
          }
        },
        "required": [
          "dispatchId",
          "closeReason",
          "closeError",
          "shutdownReason",
          "sipError",
          "userEverSpoke",
          "totalSilenceTimeouts",
          "trackerDurationS",
          "errors",
          "pipelineMetrics",
          "falseInterruptions",
          "transcriptCounters",
          "other"
        ]
      },
      "BotSessionTranscript": {
        "type": "object",
        "properties": {
          "dispatchId": {
            "type": "string",
            "format": "uuid"
          },
          "available": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "rawFormat": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "items": {}
          },
          "segments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "speakerId": {
                  "type": "string",
                  "enum": [
                    "assistant",
                    "user",
                    "tool"
                  ]
                },
                "text": {
                  "type": "string"
                },
                "startTime": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "endTime": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "interrupted": {
                  "type": "boolean"
                },
                "confidence": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "createdAt": {
                  "type": "number"
                },
                "metrics": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": {}
                },
                "toolName": {
                  "type": "string"
                },
                "toolArguments": {
                  "type": "string"
                },
                "toolResult": {
                  "type": "string"
                },
                "toolIsError": {
                  "type": "boolean"
                },
                "toolErrorKind": {
                  "type": "string",
                  "enum": [
                    "tool_error",
                    "unhandled_exception"
                  ]
                }
              },
              "required": [
                "id",
                "speakerId",
                "text",
                "startTime",
                "endTime",
                "interrupted",
                "confidence",
                "createdAt",
                "metrics"
              ]
            }
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "dispatchId",
          "available"
        ]
      },
      "BotSessionRecording": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "dispatchId": {
                "type": "string",
                "format": "uuid"
              },
              "available": {
                "type": "boolean",
                "enum": [
                  false
                ],
                "description": "The session exists but has no stored recording — recording is disabled for the bot, or the upload never landed. No other fields are present."
              }
            },
            "required": [
              "dispatchId",
              "available"
            ]
          },
          {
            "type": "object",
            "properties": {
              "dispatchId": {
                "type": "string",
                "format": "uuid"
              },
              "available": {
                "type": "boolean",
                "enum": [
                  true
                ]
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Presigned GET straight to the object store. Valid until `expiresAt` (15 minutes); fetch it now, do not store it. Treat it as a bearer credential for call audio."
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              },
              "contentType": {
                "type": "string"
              },
              "fileName": {
                "type": "string"
              },
              "sizeBytes": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Null when the upload did not report a size."
              },
              "durationSec": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "dispatchId",
              "available",
              "url",
              "expiresAt",
              "contentType",
              "fileName",
              "sizeBytes",
              "durationSec"
            ]
          }
        ]
      },
      "TicketResourceLink": {
        "type": "object",
        "properties": {
          "resourceType": {
            "type": "string",
            "enum": [
              "BOT_SESSION",
              "TELEPHONY_CALL"
            ]
          },
          "resourceId": {
            "type": "string"
          },
          "note": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "resourceType",
          "resourceId",
          "note"
        ]
      },
      "Ticket": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "ACKNOWLEDGED",
              "IN_PROGRESS",
              "RESOLVED",
              "CLOSED"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH",
              "URGENT"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "BUG",
              "FEATURE_REQUEST",
              "QUESTION",
              "OTHER"
            ]
          },
          "awaitingResponse": {
            "type": "string",
            "enum": [
              "REPORTER",
              "SUPPORT",
              "NONE"
            ],
            "description": "Who owes the next reply."
          },
          "reportedByUserId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The person the ticket is credited to: the named reporter, else the user behind the API key (its creator) or OAuth sign-in. Null when no person is credited (a system key, or an agent report filed before 2026-10-01) or when the reporter is not shown to you. `reportedVia` always says which door it came through."
          },
          "reportedVia": {
            "type": [
              "string",
              "null"
            ],
            "description": "`external_api`, `mcp`, or null for a Portal report."
          },
          "contextUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "linkedSessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TicketResourceLink"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "title",
          "description",
          "status",
          "priority",
          "category",
          "awaitingResponse",
          "reportedByUserId",
          "reportedVia",
          "contextUrl",
          "linkedSessions",
          "createdAt",
          "updatedAt",
          "resolvedAt"
        ]
      },
      "TicketSessionsAttached": {
        "type": "object",
        "properties": {
          "ticketId": {
            "type": "string",
            "format": "uuid"
          },
          "linkedSessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TicketResourceLink"
            }
          }
        },
        "required": [
          "ticketId",
          "linkedSessions"
        ]
      },
      "CaseUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "firstName": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastName": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName"
        ]
      },
      "CaseLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "resourceType": {
            "type": "string",
            "enum": [
              "TELEPHONY_CALL",
              "BOT_SESSION",
              "EMAIL_CONVERSATION",
              "CHAT_CONVERSATION",
              "MESSAGING_CONVERSATION",
              "CONTACT_REQUEST"
            ]
          },
          "resourceId": {
            "type": "string",
            "format": "uuid",
            "description": "The linked record: a call, a bot session (dispatch id), an email, chat or messaging conversation, or a contact request."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "resourceType",
          "resourceId",
          "createdAt"
        ]
      },
      "Case": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "integer",
            "description": "Per-tenant reference number, shown in the Portal as `S-<number>` (e.g. S-1042)."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "NEW",
              "IN_PROGRESS",
              "WAITING_CUSTOMER",
              "WAITING_THIRD_PARTY",
              "RESOLVED",
              "CLOSED",
              "CANCELLED"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH",
              "URGENT"
            ]
          },
          "categoryKey": {
            "type": "string",
            "description": "Category key from the tenant’s case pack (e.g. `question`, `complaint`, `bug`, `water_leak`, `other`). Accept unknown keys: packs can grow."
          },
          "statusChangedAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "closedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "assignedToUser": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseUser"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "contact": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "firstName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lastName": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "firstName",
              "lastName"
            ]
          },
          "company": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "`null` when unset, deleted, or the tenant keeps no companies."
          },
          "topic": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "The call topic (product or service area); `null` when unset."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "color"
              ]
            }
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "status",
          "priority",
          "categoryKey",
          "statusChangedAt",
          "dueAt",
          "resolvedAt",
          "closedAt",
          "createdAt",
          "updatedAt",
          "assignedToUser",
          "contact",
          "company",
          "topic",
          "tags"
        ]
      },
      "CaseDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "integer",
            "description": "Per-tenant reference number, shown in the Portal as `S-<number>` (e.g. S-1042)."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "NEW",
              "IN_PROGRESS",
              "WAITING_CUSTOMER",
              "WAITING_THIRD_PARTY",
              "RESOLVED",
              "CLOSED",
              "CANCELLED"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH",
              "URGENT"
            ]
          },
          "categoryKey": {
            "type": "string",
            "description": "Category key from the tenant’s case pack (e.g. `question`, `complaint`, `bug`, `water_leak`, `other`). Accept unknown keys: packs can grow."
          },
          "statusChangedAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "closedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "assignedToUser": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseUser"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "contact": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "firstName": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lastName": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "firstName",
              "lastName"
            ]
          },
          "company": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "`null` when unset, deleted, or the tenant keeps no companies."
          },
          "topic": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ],
            "description": "The call topic (product or service area); `null` when unset."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "color"
              ]
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "reporterName": {
            "type": [
              "string",
              "null"
            ]
          },
          "reporterPhone": {
            "type": [
              "string",
              "null"
            ]
          },
          "locationText": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalSystem": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalRef": {
            "type": [
              "string",
              "null"
            ],
            "description": "The case’s id in your own system."
          },
          "externalUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "PORTAL",
              "CALL",
              "BOT",
              "EMAIL",
              "CHAT",
              "API",
              "MCP"
            ],
            "description": "Where the case was opened: `API` for this API, `MCP` for the MCP server, `PORTAL`, `CALL` (from a call in the Portal), and so on."
          },
          "sourceIdentifier": {
            "type": [
              "string",
              "null"
            ],
            "description": "For `CALL`, the call id; for `API` and `MCP`, the id of the API key that opened it."
          },
          "customFields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Extra fields of the tenant’s CURRENT case form — only its keys are returned, so sending this object back on PATCH always validates."
          },
          "firstResponseAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdByUser": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseUser"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseLink"
            }
          },
          "tasks": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "title": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "priority": {
                  "type": "string"
                },
                "dueDate": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "assignedToUser": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/CaseUser"
                    },
                    {
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  ]
                }
              },
              "required": [
                "id",
                "title",
                "status",
                "priority",
                "dueDate",
                "assignedToUser"
              ]
            },
            "description": "The case’s tasks, newest first. `null` unless the key also holds `tasks.read`."
          }
        },
        "required": [
          "id",
          "number",
          "title",
          "status",
          "priority",
          "categoryKey",
          "statusChangedAt",
          "dueAt",
          "resolvedAt",
          "closedAt",
          "createdAt",
          "updatedAt",
          "assignedToUser",
          "contact",
          "company",
          "topic",
          "tags",
          "description",
          "reporterName",
          "reporterPhone",
          "locationText",
          "externalSystem",
          "externalRef",
          "externalUrl",
          "source",
          "sourceIdentifier",
          "customFields",
          "firstResponseAt",
          "createdByUser",
          "links",
          "tasks"
        ]
      },
      "CaseComment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "content": {
            "type": "string"
          },
          "authorType": {
            "type": "string",
            "enum": [
              "USER",
              "SYSTEM",
              "EXTERNAL"
            ]
          },
          "authorUser": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseUser"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "authorDisplayName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "content",
          "authorType",
          "authorUser",
          "authorDisplayName",
          "createdAt"
        ]
      },
      "CaseLinkDeleted": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "deleted"
        ]
      },
      "AppointmentType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "durationMin": {
            "type": "integer"
          },
          "price": {
            "type": [
              "string",
              "null"
            ],
            "description": "Formatted price, e.g. \"150 PLN\". Null for a publicly funded visit or one with no price set — do not quote a fee when it is null."
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "specialistIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "required": [
          "id",
          "name",
          "durationMin",
          "price",
          "description",
          "specialistIds"
        ]
      },
      "Specialist": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "specialization": {
            "type": [
              "string",
              "null"
            ]
          },
          "locationIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "required": [
          "id",
          "name",
          "title",
          "specialization",
          "locationIds"
        ]
      },
      "BookingRequirements": {
        "type": "object",
        "properties": {
          "bookingEnabled": {
            "type": "boolean",
            "description": "False when no booking can succeed right now, whatever the request. Check it before collecting patient details."
          },
          "unavailableReason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "SOURCE_NOT_CONFIGURED",
              "SOURCE_CONFLICT",
              "FLAG_OFF",
              null
            ]
          },
          "requiredFields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "optionalFields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "policies": {
            "type": "object",
            "properties": {
              "minBookingNoticeMin": {
                "type": "integer"
              },
              "bookingHorizonDays": {
                "type": "integer"
              },
              "cancelNoticeMin": {
                "type": "integer"
              },
              "rescheduleNoticeMin": {
                "type": "integer"
              }
            },
            "required": [
              "minBookingNoticeMin",
              "bookingHorizonDays",
              "cancelNoticeMin",
              "rescheduleNoticeMin"
            ]
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "fullAddress": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "timezone": {
                  "type": "string"
                },
                "instructions": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "fullAddress",
                "timezone"
              ]
            }
          },
          "specialists": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "calendarSyncMode": {
                  "type": "string",
                  "enum": [
                    "linked",
                    "native"
                  ],
                  "description": "\"linked\" means this specialist's visits appear in a connected external calendar; \"native\" means Mediflo only."
                }
              },
              "required": [
                "id",
                "name",
                "calendarSyncMode"
              ]
            }
          },
          "defaultTimezone": {
            "type": "string"
          }
        },
        "required": [
          "bookingEnabled",
          "unavailableReason",
          "requiredFields",
          "optionalFields",
          "policies",
          "locations",
          "specialists",
          "defaultTimezone"
        ]
      },
      "AvailabilitySlot": {
        "type": "object",
        "properties": {
          "slotToken": {
            "type": "string",
            "description": "Opaque, signed. The ONLY accepted way to name a slot when holding, booking or rescheduling — a hand-built time is refused with SCHEDULING_INVALID_SLOT."
          },
          "start": {
            "type": "string",
            "description": "Local wall clock, YYYY-MM-DDTHH:mm."
          },
          "startIso": {
            "type": "string",
            "description": "RFC3339 with the site offset."
          },
          "spokenLabel": {
            "type": "string",
            "description": "Ready-to-read Polish label."
          },
          "durationMin": {
            "type": "integer"
          },
          "specialistId": {
            "type": "string",
            "format": "uuid"
          },
          "appointmentTypeId": {
            "type": "string",
            "format": "uuid"
          },
          "locationId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "slotToken",
          "start",
          "startIso",
          "spokenLabel",
          "durationMin",
          "specialistId",
          "appointmentTypeId",
          "locationId"
        ]
      },
      "Appointment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "start": {
            "type": "string"
          },
          "startIso": {
            "type": "string"
          },
          "spokenLabel": {
            "type": "string"
          },
          "specialist": {
            "type": "string"
          },
          "appointmentType": {
            "type": "string"
          },
          "durationMin": {
            "type": "integer"
          },
          "price": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "name",
              "address"
            ]
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "description": "The CRM contact this booking is for. Present only for bookings of non-clinic tenants, which book against a contact instead of a patient; absent otherwise."
          }
        },
        "required": [
          "id",
          "start",
          "startIso",
          "spokenLabel",
          "specialist",
          "appointmentType",
          "durationMin",
          "price",
          "location",
          "instructions",
          "status"
        ]
      },
      "ActionableAppointment": {
        "type": "object",
        "properties": {
          "actionToken": {
            "type": [
              "string",
              "null"
            ],
            "description": "Caller-bound handle, opaque and bound to tenant, appointment, the caller's phone and the appointment version, valid one hour. The `scheduling.modify` endpoints accept only this — never a bare id."
          },
          "patientMaskedName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Several people share one phone. Confirm this name with the caller before changing anything."
          },
          "start": {
            "type": "string"
          },
          "startIso": {
            "type": "string"
          },
          "spokenLabel": {
            "type": "string"
          },
          "specialist": {
            "type": "string"
          },
          "appointmentType": {
            "type": "string"
          },
          "durationMin": {
            "type": "integer"
          },
          "price": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "name",
              "address"
            ]
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "contactId": {
            "type": "string",
            "format": "uuid",
            "description": "The CRM contact this booking is for. Present only for bookings of non-clinic tenants, which book against a contact instead of a patient; absent otherwise."
          }
        },
        "required": [
          "actionToken",
          "patientMaskedName",
          "start",
          "startIso",
          "spokenLabel",
          "specialist",
          "appointmentType",
          "durationMin",
          "price",
          "location",
          "instructions",
          "status"
        ]
      },
      "PatientLookup": {
        "type": "object",
        "properties": {
          "found": {
            "type": "boolean"
          },
          "patients": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "patientRef": {
                  "type": "string",
                  "description": "Opaque, caller-bound reference. Pass it to POST /scheduling/appointments as `patientRef` instead of re-sending the patient’s details."
                },
                "maskedName": {
                  "type": "string"
                }
              },
              "required": [
                "patientRef",
                "maskedName"
              ]
            }
          },
          "upcomingAppointments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActionableAppointment"
            }
          }
        },
        "required": [
          "found",
          "patients",
          "upcomingAppointments"
        ]
      },
      "BookingOperation": {
        "type": "object",
        "properties": {
          "operationId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "COMMITTED",
              "FAILED",
              "UNCERTAIN",
              "ABANDONED"
            ]
          },
          "appointment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Appointment"
              },
              {
                "type": [
                  "object",
                  "null"
                ]
              }
            ]
          },
          "errorCode": {
            "type": "string"
          }
        },
        "required": [
          "status",
          "appointment"
        ]
      },
      "SchedulingIndeterminateAccepted": {
        "type": "object",
        "properties": {
          "operationId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "UNCERTAIN"
            ]
          }
        },
        "required": [
          "operationId",
          "status"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/bots": {
      "get": {
        "operationId": "listBots",
        "summary": "List bots",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Bots"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Bot"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createBot",
        "summary": "Create a bot",
        "description": "`locationId` is optional: omit it (or send null or an empty string) for a bot that is not tied to one location; to tie it to one, create the location via POST /locations first. `channels` defaults to the channels available to your organization (website chat and/or phone; phone when neither is set up). There is no DELETE for bots by design: they are hard-deleted, so removal stays in the Portal.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Bots"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "locationId": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "phoneNumberId": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "maxConcurrentCalls": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 5
                  },
                  "isActive": {
                    "type": "boolean",
                    "default": true
                  },
                  "priority": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 50
                  },
                  "description": {
                    "type": "string"
                  },
                  "operatingHoursStart": {
                    "type": "string"
                  },
                  "operatingHoursEnd": {
                    "type": "string"
                  },
                  "operatingDays": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    }
                  },
                  "country": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "default": "PL"
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "WEB_CHAT",
                        "VOICE_INBOUND",
                        "VOICE_OUTBOUND"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 3
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Bot"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}": {
      "get": {
        "operationId": "getBot",
        "summary": "Get a bot",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Bots"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Bot"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBot",
        "summary": "Update a bot",
        "description": "Also binds an outbound phone number via `phoneNumberId` (which adds VOICE_OUTBOUND to `channels`). The number must already exist and be connected to a trunk — provisioning is not part of this API. Removing a channel that is still in use (website-chat binding, a number routing calls to the bot, the caller-ID number) is refused with 409 BOT_CHANNEL_IN_USE. `locationId: null` — or an empty string, which is treated the same, as for `phoneNumberId` — clears the location; any other value must be a location uuid. A bot running on a Mediflo template must keep one, so clearing it is refused with 409 BOT_INSTANCE_LOCATION_REQUIRED.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Bots"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1
                  },
                  "locationId": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid"
                      },
                      {
                        "type": "string",
                        "enum": [
                          ""
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "phoneNumberId": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "maxConcurrentCalls": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 100
                  },
                  "isActive": {
                    "type": "boolean"
                  },
                  "priority": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100
                  },
                  "description": {
                    "type": "string"
                  },
                  "operatingHoursStart": {
                    "type": "string"
                  },
                  "operatingHoursEnd": {
                    "type": "string"
                  },
                  "operatingDays": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    }
                  },
                  "country": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "WEB_CHAT",
                        "VOICE_INBOUND",
                        "VOICE_OUTBOUND"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 3
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Bot"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/readiness": {
      "get": {
        "operationId": "getBotReadiness",
        "summary": "Check whether a bot can take calls",
        "description": "A checklist assembled from the publish and dispatch preconditions, for the bot’s channels. Three verdicts: `ready` (can serve at all; a chat-only bot also needs its widget), `readyForOutbound` (serves VOICE_OUTBOUND and the phone chain is dispatchable — a chat-only bot is legitimately false; do not bind a number) and `readyForWebChat` (serves WEB_CHAT and the chat widget is bound). `chat_widget_bound` is fixed in the Portal (Settings → Chat widget). When website chat has booking on, `web_chat_booking_widget` and `web_chat_booking_sms` report WEB_CHAT_BOOKING_WIDGET_MISSING and WEB_CHAT_BOOKING_SMS_MISSING; they are informational. `phone_number_attached` verifies the WHOLE outbound chain and is flagged `requiredFor: outbound` only when the bot places calls. `operating_hours_configured`, `workflow_active` and `location_set` are informational. `ai_disclosure` is an informational ADVISORY: it sweeps the prompt, greeting and active workflow for wording that tells the person they are talking to an AI (EU AI Act Article 50). It is a Polish/English keyword heuristic, so `ok: false` means \"we could not find one, please confirm\" — not a compliance finding. The obligation and the wording belong to the operator; Mediflo neither enforces nor verifies them, and this check never affects any verdict.\n\nRequired scope: `bots.read`.",
        "tags": [
          "Bots"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotReadiness"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/config": {
      "get": {
        "operationId": "getBotConfig",
        "summary": "Get the draft configuration",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Bot configuration"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotConfig"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBotConfig",
        "summary": "Edit the draft configuration",
        "description": "Send `expectedUpdatedAt` (the `updatedAt` you last read) for optimistic concurrency; a mismatch returns 409 with the authoritative config unless `forceOverwrite` is set. Editing the draft does NOT affect live calls until you publish. The bot’s models are configured by Mediflo and are not part of this body; a model change from a key without a Mediflo staff member’s authority is refused with 403 `BOT_MODEL_CONFIG_STAFF_ONLY`.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Bot configuration"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "agentPromptText": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "remarksPromptText": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "remarksOutputSchemaJson": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "additionalProperties": {}
                  },
                  "toolsConfig": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "end_call": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          },
                          "description": {
                            "type": "string",
                            "maxLength": 4000
                          },
                          "disableInterruptions": {
                            "type": "boolean"
                          },
                          "responseTimeoutSecs": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 120
                          }
                        },
                        "required": [
                          "enabled"
                        ]
                      },
                      "detected_answering_machine": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "description": {
                            "type": "string",
                            "maxLength": 4000
                          },
                          "disableInterruptions": {
                            "type": "boolean"
                          },
                          "responseTimeoutSecs": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 120
                          }
                        },
                        "required": [
                          "enabled"
                        ]
                      },
                      "transfer_to_consultant": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean",
                            "enum": [
                              true
                            ]
                          },
                          "ringTimeoutSecs": {
                            "type": "integer",
                            "minimum": 10,
                            "maximum": 120,
                            "default": 30
                          },
                          "onNoAnswer": {
                            "type": "string",
                            "enum": [
                              "offer_message",
                              "resume"
                            ],
                            "default": "resume"
                          },
                          "destination": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "consultant_queue"
                                    ]
                                  },
                                  "queueId": {
                                    "type": "string",
                                    "format": "uuid"
                                  }
                                },
                                "required": [
                                  "kind",
                                  "queueId"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "kind": {
                                    "type": "string",
                                    "enum": [
                                      "phone"
                                    ]
                                  },
                                  "mode": {
                                    "type": "string",
                                    "enum": [
                                      "warm",
                                      "cold_bridge",
                                      "cold_handoff"
                                    ]
                                  },
                                  "number": {
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "properties": {
                                          "type": {
                                            "type": "string",
                                            "enum": [
                                              "static"
                                            ]
                                          },
                                          "value": {
                                            "type": "string",
                                            "pattern": "^\\+[1-9]\\d{6,14}$"
                                          }
                                        },
                                        "required": [
                                          "type",
                                          "value"
                                        ],
                                        "additionalProperties": false
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "type": {
                                            "type": "string",
                                            "enum": [
                                              "session_variable"
                                            ]
                                          },
                                          "name": {
                                            "type": "string",
                                            "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
                                          }
                                        },
                                        "required": [
                                          "type",
                                          "name"
                                        ],
                                        "additionalProperties": false
                                      }
                                    ]
                                  },
                                  "gate": {
                                    "type": "string",
                                    "enum": [
                                      "dtmf",
                                      "amd",
                                      "dtmf_amd",
                                      "none"
                                    ],
                                    "default": "dtmf"
                                  },
                                  "voicemailRescue": {
                                    "type": "boolean",
                                    "default": true
                                  },
                                  "briefing": {
                                    "type": "object",
                                    "properties": {
                                      "preAccept": {
                                        "type": "array",
                                        "items": {
                                          "type": "string",
                                          "enum": [
                                            "clinic_only",
                                            "caller_number",
                                            "topic"
                                          ]
                                        },
                                        "default": [
                                          "clinic_only",
                                          "topic"
                                        ]
                                      },
                                      "postAccept": {
                                        "type": "string",
                                        "enum": [
                                          "none",
                                          "topic",
                                          "summary"
                                        ],
                                        "default": "topic"
                                      }
                                    }
                                  }
                                },
                                "required": [
                                  "kind",
                                  "mode",
                                  "number"
                                ],
                                "additionalProperties": false
                              }
                            ]
                          },
                          "description": {
                            "type": "string",
                            "maxLength": 4000
                          },
                          "disableInterruptions": {
                            "type": "boolean"
                          },
                          "responseTimeoutSecs": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 120
                          }
                        },
                        "required": [
                          "enabled",
                          "destination"
                        ]
                      },
                      "mcp_servers": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "name": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 120
                            },
                            "enabled": {
                              "type": "boolean"
                            },
                            "url": {
                              "type": "string",
                              "maxLength": 2000,
                              "format": "uri"
                            },
                            "transport": {
                              "type": "string",
                              "enum": [
                                "auto",
                                "streamable_http",
                                "sse"
                              ],
                              "default": "auto"
                            },
                            "allowed_tools": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "default": null
                            },
                            "async_mode": {
                              "type": "string",
                              "enum": [
                                "none",
                                "all",
                                "selected"
                              ],
                              "default": "none",
                              "description": "Which of this MCP server's tools run asynchronously — the bot keeps talking to the caller while the tool call runs, voices an interim acknowledgment for slow calls, and delivers the result when ready. 'none' (default): every call blocks the conversation. 'all': every exposed tool runs async. 'selected': only the tools listed in async_tools. Unknown values fail closed to 'none'."
                            },
                            "async_tools": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "default": null,
                              "description": "Tool names that run asynchronously when async_mode is 'selected'; null otherwise. Only tools also exposed by the server (and allowed by allowed_tools) take effect. 'selected' with an empty or null list means nothing runs async (fail closed)."
                            },
                            "discovered_tools": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 200
                                  },
                                  "description": {
                                    "type": "string",
                                    "maxLength": 2000
                                  },
                                  "input_schema": {
                                    "type": "object",
                                    "additionalProperties": {}
                                  }
                                },
                                "required": [
                                  "name"
                                ]
                              },
                              "maxItems": 500,
                              "default": []
                            },
                            "client_session_timeout_seconds": {
                              "type": "number",
                              "minimum": 1,
                              "maximum": 300
                            },
                            "parameter_bindings": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "source": {
                                          "type": "string",
                                          "enum": [
                                            "session_variable"
                                          ]
                                        },
                                        "name": {
                                          "type": "string",
                                          "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
                                        }
                                      },
                                      "required": [
                                        "source",
                                        "name"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "source": {
                                          "type": "string",
                                          "enum": [
                                            "constant"
                                          ]
                                        },
                                        "value": {
                                          "anyOf": [
                                            {
                                              "type": "string"
                                            },
                                            {
                                              "type": "number"
                                            },
                                            {
                                              "type": "boolean"
                                            }
                                          ]
                                        }
                                      },
                                      "required": [
                                        "source",
                                        "value"
                                      ]
                                    }
                                  ]
                                }
                              }
                            },
                            "response_variables": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "from": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "to": {
                                      "type": "string",
                                      "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
                                    }
                                  },
                                  "required": [
                                    "from",
                                    "to"
                                  ]
                                },
                                "maxItems": 16
                              }
                            },
                            "tool_gates": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "requires": {
                                      "type": "object",
                                      "properties": {
                                        "variable": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 64,
                                          "description": "The session fact to test: identity_verified, a declared workflow/procedure variable, or a seeded session key."
                                        },
                                        "operator": {
                                          "type": "string",
                                          "enum": [
                                            "eq",
                                            "neq",
                                            "gt",
                                            "gte",
                                            "lt",
                                            "lte",
                                            "is_true",
                                            "is_false",
                                            "is_set",
                                            "is_empty"
                                          ],
                                          "description": "Comparison to apply. The unary operators (is_true/is_false/is_set/is_empty) take no value."
                                        },
                                        "value": {
                                          "type": "string",
                                          "maxLength": 200,
                                          "description": "Value to compare against. Required for the binary operators, forbidden for the unary ones."
                                        },
                                        "label": {
                                          "type": "string",
                                          "minLength": 1,
                                          "maxLength": 80,
                                          "description": "Human wording of the fact for the default spoken denial (\"najpierw musimy ustalić: {label}\"). Without it the runner de-snake-cases the variable key, which reads badly aloud. Ignored when `message` is set."
                                        }
                                      },
                                      "required": [
                                        "variable",
                                        "operator"
                                      ],
                                      "additionalProperties": false
                                    },
                                    "message": {
                                      "type": "string",
                                      "maxLength": 300,
                                      "description": "Polish steer returned to the model when the gate denies the call. Say what must happen FIRST. Stored as a single line. Omit for the standard wording."
                                    }
                                  },
                                  "required": [
                                    "requires"
                                  ],
                                  "additionalProperties": false
                                },
                                "maxItems": 4
                              },
                              "description": "Preconditions per tool name: {\"book_visit\": [{requires: {...}, label?, message?}]}. At most 4 gates on one tool — every denial costs a conversational turn, so gates are for PHI access and irreversible actions, not for shaping the conversation. `requires.label` is the human name of the fact, spoken in the default Polish denial (\"najpierw musimy ustalić: {label}\"); without it the runner de-snake-cases the variable key, which reads badly aloud. `message` replaces the whole denial line and makes `label` unused. Prefer BOOLEAN facts with is_true/is_false: the runner evaluates is_true with truthy-string semantics (mirroring the workflow walker), so a gate on a free-text variable passes on any non-empty answer."
                            },
                            "managed": {
                              "type": "object",
                              "properties": {
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "mediflo_scheduling"
                                  ]
                                },
                                "capabilities": {
                                  "type": "object",
                                  "properties": {
                                    "browse": {
                                      "type": "boolean"
                                    },
                                    "book": {
                                      "type": "boolean"
                                    },
                                    "modify": {
                                      "type": "boolean"
                                    },
                                    "contact": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "cases": {
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "browse",
                                    "book",
                                    "modify"
                                  ]
                                },
                                "credential_ref": {
                                  "type": "string",
                                  "enum": [
                                    "scheduling-toolset"
                                  ]
                                }
                              },
                              "required": [
                                "kind",
                                "capabilities",
                                "credential_ref"
                              ],
                              "additionalProperties": false
                            },
                            "secrets": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "key": {
                                    "type": "string",
                                    "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
                                  },
                                  "value": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 4096
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "encrypted": {
                                            "type": "string",
                                            "minLength": 1
                                          },
                                          "iv": {
                                            "type": "string",
                                            "minLength": 1
                                          },
                                          "tag": {
                                            "type": "string",
                                            "minLength": 1
                                          }
                                        },
                                        "required": [
                                          "encrypted",
                                          "iv",
                                          "tag"
                                        ]
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "id",
                                  "key"
                                ]
                              },
                              "maxItems": 20,
                              "default": []
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "enabled",
                            "url"
                          ]
                        },
                        "maxItems": 10
                      },
                      "http_tools": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "name": {
                              "type": "string",
                              "pattern": "^[A-Za-z0-9_-]{1,64}$"
                            },
                            "enabled": {
                              "type": "boolean",
                              "default": true
                            },
                            "description": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 2000
                            },
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "method": {
                              "type": "string",
                              "enum": [
                                "GET",
                                "POST",
                                "PUT",
                                "PATCH",
                                "DELETE"
                              ],
                              "default": "POST"
                            },
                            "queryParams": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "key": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "key",
                                  "value"
                                ]
                              },
                              "maxItems": 10
                            },
                            "bodySchema": {
                              "type": "object",
                              "additionalProperties": {}
                            },
                            "argsOnly": {
                              "type": "boolean",
                              "default": true
                            },
                            "timeoutMs": {
                              "type": "integer",
                              "minimum": 1000,
                              "maximum": 20000,
                              "default": 8000
                            },
                            "retries": {
                              "type": "integer",
                              "minimum": 0,
                              "maximum": 2,
                              "default": 0
                            },
                            "parameter_bindings": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "object",
                                "additionalProperties": {
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "properties": {
                                        "source": {
                                          "type": "string",
                                          "enum": [
                                            "session_variable"
                                          ]
                                        },
                                        "name": {
                                          "type": "string",
                                          "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
                                        }
                                      },
                                      "required": [
                                        "source",
                                        "name"
                                      ]
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "source": {
                                          "type": "string",
                                          "enum": [
                                            "constant"
                                          ]
                                        },
                                        "value": {
                                          "anyOf": [
                                            {
                                              "type": "string"
                                            },
                                            {
                                              "type": "number"
                                            },
                                            {
                                              "type": "boolean"
                                            }
                                          ]
                                        }
                                      },
                                      "required": [
                                        "source",
                                        "value"
                                      ]
                                    }
                                  ]
                                }
                              }
                            },
                            "response_variables": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "from": {
                                    "type": "string",
                                    "minLength": 1
                                  },
                                  "to": {
                                    "type": "string",
                                    "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
                                  }
                                },
                                "required": [
                                  "from",
                                  "to"
                                ]
                              },
                              "maxItems": 16
                            },
                            "gates": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "requires": {
                                    "type": "object",
                                    "properties": {
                                      "variable": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 64,
                                        "description": "The session fact to test: identity_verified, a declared workflow/procedure variable, or a seeded session key."
                                      },
                                      "operator": {
                                        "type": "string",
                                        "enum": [
                                          "eq",
                                          "neq",
                                          "gt",
                                          "gte",
                                          "lt",
                                          "lte",
                                          "is_true",
                                          "is_false",
                                          "is_set",
                                          "is_empty"
                                        ],
                                        "description": "Comparison to apply. The unary operators (is_true/is_false/is_set/is_empty) take no value."
                                      },
                                      "value": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Value to compare against. Required for the binary operators, forbidden for the unary ones."
                                      },
                                      "label": {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 80,
                                        "description": "Human wording of the fact for the default spoken denial (\"najpierw musimy ustalić: {label}\"). Without it the runner de-snake-cases the variable key, which reads badly aloud. Ignored when `message` is set."
                                      }
                                    },
                                    "required": [
                                      "variable",
                                      "operator"
                                    ],
                                    "additionalProperties": false
                                  },
                                  "message": {
                                    "type": "string",
                                    "maxLength": 300,
                                    "description": "Polish steer returned to the model when the gate denies the call. Say what must happen FIRST. Stored as a single line. Omit for the standard wording."
                                  }
                                },
                                "required": [
                                  "requires"
                                ],
                                "additionalProperties": false
                              },
                              "maxItems": 4,
                              "description": "Preconditions on this tool (at most 4). A denied call returns a corrective message to the model instead of running — it never raises. NOT YET ENFORCED: gates take effect only once the bot-side http_tools executor ships (the runner evaluates gates at the MCP call wrapper today), so a gate declared here is stored and validated but the tool is still callable — publish warns about it. `requires.label` names the fact in the default Polish denial; `message` replaces the whole line. Prefer boolean facts: is_true uses truthy-string semantics, so a gate on free text passes on any non-empty answer."
                            },
                            "headers": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "key": {
                                    "type": "string",
                                    "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
                                  },
                                  "value": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 4096
                                      },
                                      {
                                        "type": "object",
                                        "properties": {
                                          "encrypted": {
                                            "type": "string",
                                            "minLength": 1
                                          },
                                          "iv": {
                                            "type": "string",
                                            "minLength": 1
                                          },
                                          "tag": {
                                            "type": "string",
                                            "minLength": 1
                                          }
                                        },
                                        "required": [
                                          "encrypted",
                                          "iv",
                                          "tag"
                                        ]
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "id",
                                  "key"
                                ]
                              },
                              "maxItems": 10
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "description",
                            "url"
                          ]
                        },
                        "maxItems": 10
                      }
                    },
                    "required": [
                      "end_call",
                      "detected_answering_machine"
                    ]
                  },
                  "guardrailsConfig": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "enabled": {
                        "type": "boolean"
                      },
                      "focus": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "executionMode": {
                            "type": "string",
                            "enum": [
                              "streaming",
                              "blocking"
                            ],
                            "default": "streaming"
                          },
                          "action": {
                            "type": "string",
                            "enum": [
                              "end_call",
                              "retry"
                            ],
                            "default": "end_call"
                          },
                          "fallbackMessage": {
                            "type": "string",
                            "maxLength": 1000
                          }
                        },
                        "required": [
                          "enabled"
                        ]
                      },
                      "manipulation": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "executionMode": {
                            "type": "string",
                            "enum": [
                              "streaming",
                              "blocking"
                            ],
                            "default": "streaming"
                          },
                          "action": {
                            "type": "string",
                            "enum": [
                              "end_call",
                              "retry"
                            ],
                            "default": "end_call"
                          },
                          "fallbackMessage": {
                            "type": "string",
                            "maxLength": 1000
                          }
                        },
                        "required": [
                          "enabled"
                        ]
                      },
                      "content": {
                        "type": "object",
                        "properties": {
                          "enabled": {
                            "type": "boolean"
                          },
                          "executionMode": {
                            "type": "string",
                            "enum": [
                              "streaming",
                              "blocking"
                            ],
                            "default": "streaming"
                          },
                          "action": {
                            "type": "string",
                            "enum": [
                              "end_call",
                              "retry"
                            ],
                            "default": "end_call"
                          },
                          "fallbackMessage": {
                            "type": "string",
                            "maxLength": 1000
                          },
                          "categories": {
                            "type": "object",
                            "properties": {
                              "sexual": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              },
                              "violence": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              },
                              "harassment": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              },
                              "self_harm": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              },
                              "profanity": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              },
                              "politics_religion": {
                                "type": "object",
                                "properties": {
                                  "enabled": {
                                    "type": "boolean"
                                  },
                                  "severity": {
                                    "type": "string",
                                    "enum": [
                                      "low",
                                      "medium",
                                      "high"
                                    ],
                                    "default": "medium"
                                  }
                                },
                                "required": [
                                  "enabled"
                                ]
                              }
                            },
                            "required": [
                              "sexual",
                              "violence",
                              "harassment",
                              "self_harm",
                              "profanity",
                              "politics_religion"
                            ]
                          }
                        },
                        "required": [
                          "enabled",
                          "categories"
                        ]
                      },
                      "custom": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "minLength": 1
                            },
                            "name": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 120
                            },
                            "prompt": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 4000
                            },
                            "enabled": {
                              "type": "boolean"
                            },
                            "executionMode": {
                              "type": "string",
                              "enum": [
                                "streaming",
                                "blocking"
                              ],
                              "default": "streaming"
                            },
                            "action": {
                              "type": "string",
                              "enum": [
                                "end_call",
                                "retry"
                              ],
                              "default": "end_call"
                            },
                            "fallbackMessage": {
                              "type": "string",
                              "maxLength": 1000
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "prompt",
                            "enabled"
                          ]
                        }
                      }
                    },
                    "required": [
                      "enabled",
                      "focus",
                      "manipulation",
                      "content",
                      "custom"
                    ]
                  },
                  "greetingConfig": {
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "static"
                            ]
                          },
                          "text": {
                            "type": "string",
                            "minLength": 1
                          },
                          "allowInterruptions": {
                            "type": "boolean",
                            "default": false
                          },
                          "byDirection": {
                            "type": "object",
                            "properties": {
                              "inbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              },
                              "outbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "type",
                          "text"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "llm"
                            ]
                          },
                          "prompt": {
                            "type": "string",
                            "minLength": 1
                          },
                          "allowInterruptions": {
                            "type": "boolean",
                            "default": false
                          },
                          "byDirection": {
                            "type": "object",
                            "properties": {
                              "inbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              },
                              "outbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "type",
                          "prompt"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "none"
                            ]
                          },
                          "byDirection": {
                            "type": "object",
                            "properties": {
                              "inbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              },
                              "outbound": {
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "static"
                                        ]
                                      },
                                      "text": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "text"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "llm"
                                        ]
                                      },
                                      "prompt": {
                                        "type": "string",
                                        "minLength": 1
                                      },
                                      "allowInterruptions": {
                                        "type": "boolean",
                                        "default": false
                                      }
                                    },
                                    "required": [
                                      "type",
                                      "prompt"
                                    ],
                                    "additionalProperties": false
                                  },
                                  {
                                    "type": "object",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "enum": [
                                          "off"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ],
                                    "additionalProperties": false
                                  }
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "required": [
                          "type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "channelSettings": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "webChat": {
                        "type": "object",
                        "properties": {
                          "greeting": {
                            "oneOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "static"
                                    ]
                                  },
                                  "text": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2000
                                  }
                                },
                                "required": [
                                  "type",
                                  "text"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "llm"
                                    ]
                                  },
                                  "prompt": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 2000
                                  }
                                },
                                "required": [
                                  "type",
                                  "prompt"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "enum": [
                                      "none"
                                    ]
                                  }
                                },
                                "required": [
                                  "type"
                                ]
                              }
                            ]
                          },
                          "handoffMessage": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 500
                          },
                          "guardrailFallbackMessage": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 500
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "additionalProperties": false
                  },
                  "sessionInitConfig": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "enabled": {
                        "type": "boolean",
                        "enum": [
                          true
                        ]
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "timeout_ms": {
                        "type": "integer",
                        "minimum": 1000,
                        "maximum": 15000,
                        "default": 8000
                      },
                      "secrets": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "key": {
                              "type": "string",
                              "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
                            },
                            "value": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 4096
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "encrypted": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "iv": {
                                      "type": "string",
                                      "minLength": 1
                                    },
                                    "tag": {
                                      "type": "string",
                                      "minLength": 1
                                    }
                                  },
                                  "required": [
                                    "encrypted",
                                    "iv",
                                    "tag"
                                  ]
                                }
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "key"
                          ]
                        },
                        "maxItems": 10,
                        "default": []
                      }
                    },
                    "required": [
                      "enabled",
                      "url"
                    ]
                  },
                  "turnTakingMode": {
                    "type": "string",
                    "enum": [
                      "eager",
                      "regular",
                      "lazy"
                    ]
                  },
                  "promptVariableMetadata": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "additionalProperties": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "maxLength": 100
                        },
                        "description": {
                          "type": "string",
                          "maxLength": 500
                        },
                        "defaultValue": {
                          "type": "string",
                          "maxLength": 1000
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "string",
                            "boolean",
                            "number",
                            "date",
                            "time",
                            "datetime",
                            "email",
                            "url",
                            "phone",
                            "currency"
                          ]
                        }
                      }
                    }
                  },
                  "entryProcedureId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Id of the DETERMINISTIC procedure that runs as this bot’s whole call flow. null means the bot has no entry procedure and follows its prompt (or its active legacy workflow) instead. A bot cannot have BOTH an entry procedure and an active workflow — publish refuses that combination (PROCEDURES_WORKFLOW_CONFLICT)."
                  },
                  "expectedUpdatedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "forceOverwrite": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotConfig"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope, or (`BOT_MODEL_CONFIG_STAFF_ONLY`) the body changes a model setting, which only Mediflo configures.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The draft changed since `expectedUpdatedAt`. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/config/publish": {
      "post": {
        "operationId": "publishBotConfig",
        "summary": "Publish the draft as an immutable snapshot",
        "description": "Freezes the draft and points the bot at it, including channelSettings. Required before the bot can be dispatched. Returns 400 `BOT_CONFIG_INCOMPLETE` with `missingFields` when the draft is not publishable — when `remarksLlmModelId` is among them, `details.hint` names the endpoint the id comes from. Procedure problems come back as 400 `BOT_CONFIG_PROCEDURES_INVALID` with `details.blockers`; a SUCCESSFUL publish may still carry `procedureWarnings` — read them. They include procedure findings and also chat prompt warnings, Terminarz/booking warnings (including WEB_CHAT_BOOKING_WIDGET_MISSING and WEB_CHAT_BOOKING_SMS_MISSING) and AI_DISCLOSURE_NOT_FOUND. None of those block the publish.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Bot configuration"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 255
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ConfigSnapshot"
                    },
                    "procedureWarnings": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PublishWarning"
                      },
                      "description": "Non-blocking findings from the procedure checks: overlapping triggers, a tool name that resolves to nothing, gates declared on an http tool (not enforced until the bot-side executor ships), a per-call context budget nearing the block threshold. Absent when there are none."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Another publish won the race for this snapshot version. Retry. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/config/snapshots": {
      "get": {
        "operationId": "listBotConfigSnapshots",
        "summary": "List published configuration versions",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Bot configuration"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ConfigSnapshot"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/config/rollback": {
      "post": {
        "operationId": "rollbackBotConfig",
        "summary": "Roll back to a published snapshot",
        "description": "Restores the snapshot onto the live bot and re-points the active snapshot at it — no follow-up publish needed. Conversation workflows are NOT rolled back (they are never snapshotted), but a workflow node’s `skillRef` resolves against the snapshot that is now current — so a SUCCESSFUL rollback may carry `skillRefWarnings` naming pins this older snapshot cannot serve. Those steps run without their playbook until you publish again or unpin them.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Bot configuration"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "snapshotId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "snapshotId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotConfig"
                    },
                    "skillRefWarnings": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SkillRefWarning"
                      },
                      "description": "Pins on the bot’s ACTIVE workflow that the rolled-back snapshot cannot serve. Advisory — the rollback already happened. Absent when there are none."
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/workflows": {
      "get": {
        "operationId": "listBotWorkflows",
        "summary": "List a bot’s conversation workflows",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WorkflowSummary"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createBotWorkflow",
        "summary": "Create a conversation workflow",
        "description": "Pass `template` (visit-confirmation | registration | inbound-intake | blank) to start from a working graph, or `definition` to supply your own — not both. `visit-confirmation` and `registration` are available only to tenants with the matching clinic module (visit confirmation, visit registration); for other tenants they return 404 `TENANT_MODULE_UNAVAILABLE`. A node's `skillRef` must name a skill the bot can actually serve on a call (one on its current config snapshot, or — for a never-published bot — an enabled free-form procedure); otherwise the write is refused with 400 `BOT_WORKFLOW_SKILL_REF_NOT_SERVABLE` and `details.skillRefs` names the offending nodes. A node's `overrideSystemPrompt` can only be switched on by the Mediflo team: 403 `BOT_WORKFLOW_SYSTEM_PROMPT_OVERRIDE_STAFF_ONLY` with `details.nodeIds`.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "definition": {
                    "type": "object",
                    "properties": {
                      "schemaVersion": {
                        "type": "number",
                        "enum": [
                          1
                        ]
                      },
                      "variables": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "key": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 64,
                              "pattern": "^[a-z][a-z0-9_]*$"
                            },
                            "label": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 120
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "string",
                                "number",
                                "boolean"
                              ]
                            },
                            "sensitive": {
                              "type": "boolean",
                              "default": false
                            },
                            "description": {
                              "type": "string",
                              "maxLength": 500
                            }
                          },
                          "required": [
                            "key",
                            "label",
                            "type"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 50,
                        "default": []
                      },
                      "nodes": {
                        "type": "array",
                        "items": {
                          "oneOf": [
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "start"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "say"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 4000
                                    },
                                    "waitForUserAfter": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "requiresIdentity": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "overrideSystemPrompt": {
                                      "type": "boolean"
                                    },
                                    "verbatim": {
                                      "type": "boolean"
                                    },
                                    "ragEnabled": {
                                      "type": "boolean"
                                    },
                                    "skillRef": {
                                      "type": "string",
                                      "format": "uuid"
                                    }
                                  },
                                  "required": [
                                    "instructions"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "collect"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 6500
                                    },
                                    "fields": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "key": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 64,
                                            "pattern": "^[a-z][a-z0-9_]*$"
                                          },
                                          "label": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 120
                                          },
                                          "type": {
                                            "type": "string",
                                            "enum": [
                                              "string",
                                              "number",
                                              "boolean",
                                              "date",
                                              "enum"
                                            ]
                                          },
                                          "required": {
                                            "type": "boolean",
                                            "default": true
                                          },
                                          "enumValues": {
                                            "type": "array",
                                            "items": {
                                              "type": "string",
                                              "minLength": 1
                                            },
                                            "minItems": 1
                                          },
                                          "description": {
                                            "type": "string",
                                            "maxLength": 500
                                          },
                                          "presentWhen": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 64
                                          }
                                        },
                                        "required": [
                                          "key",
                                          "label",
                                          "type"
                                        ],
                                        "additionalProperties": false
                                      },
                                      "minItems": 1,
                                      "maxItems": 20
                                    },
                                    "maxAttempts": {
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 10,
                                      "default": 3
                                    },
                                    "requiresIdentity": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "overrideSystemPrompt": {
                                      "type": "boolean"
                                    },
                                    "verbatimOpener": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000
                                    },
                                    "openerInterruptible": {
                                      "type": "boolean"
                                    },
                                    "historyMode": {
                                      "type": "string",
                                      "enum": [
                                        "full",
                                        "summary",
                                        "none"
                                      ]
                                    },
                                    "ragEnabled": {
                                      "type": "boolean"
                                    },
                                    "skillRef": {
                                      "type": "string",
                                      "format": "uuid"
                                    }
                                  },
                                  "required": [
                                    "instructions",
                                    "fields"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "identity-check"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "matchAgainst": {
                                      "type": "array",
                                      "items": {
                                        "type": "string",
                                        "enum": [
                                          "firstName",
                                          "lastName",
                                          "dateOfBirth",
                                          "phoneNumber"
                                        ]
                                      },
                                      "minItems": 1,
                                      "maxItems": 4
                                    },
                                    "maxAttempts": {
                                      "type": "integer",
                                      "minimum": 1,
                                      "maximum": 5,
                                      "default": 3
                                    },
                                    "writeVerifiedTo": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 64
                                    },
                                    "allowAuthorizedProxy": {
                                      "type": "boolean"
                                    },
                                    "instructions": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 4000
                                    },
                                    "verbatimOpener": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000
                                    },
                                    "openerInterruptible": {
                                      "type": "boolean"
                                    },
                                    "historyMode": {
                                      "type": "string",
                                      "enum": [
                                        "full",
                                        "summary",
                                        "none"
                                      ]
                                    },
                                    "ragEnabled": {
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "matchAgainst"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "decision"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 4000
                                    },
                                    "routing": {
                                      "type": "string",
                                      "enum": [
                                        "llm",
                                        "expression"
                                      ],
                                      "default": "llm"
                                    },
                                    "classifyOnly": {
                                      "type": "boolean"
                                    },
                                    "requiresIdentity": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "overrideSystemPrompt": {
                                      "type": "boolean"
                                    },
                                    "verbatimOpener": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000
                                    },
                                    "openerInterruptible": {
                                      "type": "boolean"
                                    },
                                    "historyMode": {
                                      "type": "string",
                                      "enum": [
                                        "full",
                                        "summary",
                                        "none"
                                      ]
                                    },
                                    "ragEnabled": {
                                      "type": "boolean"
                                    },
                                    "skillRef": {
                                      "type": "string",
                                      "format": "uuid"
                                    },
                                    "options": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "id": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 64
                                          },
                                          "label": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 120
                                          },
                                          "description": {
                                            "type": "string",
                                            "maxLength": 500
                                          },
                                          "expression": {
                                            "type": "object",
                                            "properties": {
                                              "variable": {
                                                "type": "string",
                                                "minLength": 1,
                                                "maxLength": 64
                                              },
                                              "operator": {
                                                "type": "string",
                                                "enum": [
                                                  "eq",
                                                  "neq",
                                                  "gt",
                                                  "gte",
                                                  "lt",
                                                  "lte",
                                                  "is_true",
                                                  "is_false",
                                                  "is_set",
                                                  "is_empty"
                                                ]
                                              },
                                              "value": {
                                                "anyOf": [
                                                  {
                                                    "type": "string",
                                                    "maxLength": 200
                                                  },
                                                  {
                                                    "type": "number"
                                                  },
                                                  {
                                                    "type": "boolean"
                                                  }
                                                ]
                                              }
                                            },
                                            "required": [
                                              "variable",
                                              "operator"
                                            ],
                                            "additionalProperties": false
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "label"
                                        ],
                                        "additionalProperties": false
                                      },
                                      "minItems": 2,
                                      "maxItems": 8
                                    }
                                  },
                                  "required": [
                                    "instructions",
                                    "options"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "tool-call"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "toolId": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 120
                                    },
                                    "arguments": {
                                      "type": "object",
                                      "additionalProperties": {}
                                    },
                                    "requiresIdentity": {
                                      "type": "boolean",
                                      "default": false
                                    },
                                    "assignments": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "from": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 200
                                          },
                                          "to": {
                                            "type": "string",
                                            "minLength": 1,
                                            "maxLength": 64
                                          }
                                        },
                                        "required": [
                                          "from",
                                          "to"
                                        ],
                                        "additionalProperties": false
                                      },
                                      "maxItems": 20
                                    }
                                  },
                                  "required": [
                                    "toolId"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "transfer-to-human"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "queueId": {
                                      "type": "string",
                                      "format": "uuid"
                                    },
                                    "summaryInstructions": {
                                      "type": "string",
                                      "maxLength": 2000
                                    },
                                    "requiresIdentity": {
                                      "type": "boolean",
                                      "default": false
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "goodbye"
                                  ]
                                },
                                "position": {
                                  "type": "object",
                                  "properties": {
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "x",
                                    "y"
                                  ]
                                },
                                "config": {
                                  "type": "object",
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "instructions": {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 2000
                                    },
                                    "resolveToStatus": {
                                      "type": "string",
                                      "enum": [
                                        "COMPLETED",
                                        "NO_ANSWER",
                                        "CANCELLED"
                                      ],
                                      "default": "COMPLETED"
                                    },
                                    "overrideSystemPrompt": {
                                      "type": "boolean"
                                    },
                                    "verbatim": {
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "instructions"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              "required": [
                                "id",
                                "kind",
                                "position",
                                "config"
                              ]
                            }
                          ]
                        },
                        "maxItems": 100
                      },
                      "edges": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "minLength": 1
                            },
                            "source": {
                              "type": "string",
                              "minLength": 1
                            },
                            "target": {
                              "type": "string",
                              "minLength": 1
                            },
                            "condition": {
                              "type": "object",
                              "properties": {
                                "optionId": {
                                  "type": "string",
                                  "minLength": 1
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "default",
                                    "option",
                                    "success",
                                    "error",
                                    "on-failure"
                                  ]
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "required": [
                            "id",
                            "source",
                            "target"
                          ],
                          "additionalProperties": false
                        },
                        "maxItems": 300
                      }
                    },
                    "required": [
                      "schemaVersion",
                      "nodes",
                      "edges"
                    ],
                    "additionalProperties": false
                  },
                  "template": {
                    "type": "string",
                    "enum": [
                      "visit-confirmation",
                      "registration",
                      "inbound-intake",
                      "blank"
                    ]
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WorkflowSummary"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-workflows/{workflowId}": {
      "get": {
        "operationId": "getBotWorkflow",
        "summary": "Get a workflow with its definition",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "workflowId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WorkflowDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "replaceBotWorkflow",
        "summary": "Replace a workflow",
        "description": "Runs the canonical validator; issues carry `nodeId` and `field`. Send `expectedVersion` (the `version` you last read) to avoid clobbering a concurrent edit — a mismatch returns 409 with both versions. A node’s `skillRef` is also checked against what the bot would actually serve: 400 `BOT_WORKFLOW_SKILL_REF_NOT_SERVABLE` with `details.skillRefs` when a pin is not on the bot’s current config snapshot (publish the bot config, or unpin it). Switching a node’s `overrideSystemPrompt` on is reserved for the Mediflo team: 403 `BOT_WORKFLOW_SYSTEM_PROMPT_OVERRIDE_STAFF_ONLY` with `details.nodeIds` (a node that already carries it may keep it or drop it).\n\nRequired scope: `bots.write`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "workflowId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000
                  },
                  "definition": {},
                  "expectedVersion": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WorkflowDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_WORKFLOW_VERSION_CONFLICT` (stale `expectedVersion`) or `BOT_WORKFLOW_NAME_CONFLICT`. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBotWorkflow",
        "summary": "Soft-delete a workflow",
        "description": "Deleting the ACTIVE workflow is allowed: it is deactivated and soft-deleted in one step, returning the bot to prompt-only mode. The workflow disappears from every list and cannot be reactivated.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "workflowId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "deleted"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-workflows/{workflowId}/activate": {
      "post": {
        "operationId": "activateBotWorkflow",
        "summary": "Make this the bot’s active workflow",
        "description": "Atomically deactivates any other workflow on the same bot. Refuses to activate a definition that fails validation, or one whose node `skillRef` the bot would not serve — 400 `BOT_WORKFLOW_SKILL_REF_NOT_SERVABLE` with `details.skillRefs`. Activation re-checks the pins even when the graph has not changed, because the bot’s snapshot may have moved since it was saved.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "workflowId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WorkflowSummary"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-workflows/{workflowId}/deactivate": {
      "post": {
        "operationId": "deactivateBotWorkflow",
        "summary": "Return the bot to prompt-only mode",
        "description": "Clears the active flag without deleting the workflow, so it can be reactivated later. Idempotent — deactivating an already-inactive workflow succeeds with `wasActive: false`. Takes effect on the next call.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "workflowId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "wasActive": {
                          "type": "boolean"
                        },
                        "workflow": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/WorkflowSummary"
                            },
                            {
                              "type": [
                                "object",
                                "null"
                              ]
                            }
                          ]
                        }
                      },
                      "required": [
                        "wasActive",
                        "workflow"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/procedures": {
      "get": {
        "operationId": "listBotProcedures",
        "summary": "List a bot’s procedures",
        "description": "A procedure is one of two things. FREE_FORM is a playbook the model reaches for MID-CALL when its `trigger` matches what the caller raised — the trigger is the only part the model ever sees, and the body is injected as a framed tool result; it steers behaviour and grants no new capability. DETERMINISTIC is an ordered flow compiled into the call itself at publish, reachable only as the bot’s entry flow or via `sub_procedure`. `content` ships in full here, so one call reads the whole set.\n\nRequired scope: `bots.read`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProcedureList"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createBotProcedure",
        "summary": "Create a procedure",
        "description": "FREE_FORM REQUIRES a `trigger`; DETERMINISTIC must have none (the model can never choose to run one). Procedures are part of the configuration snapshot: this reaches no call until POST /bots/{botId}/config/publish. To make a deterministic procedure the call flow, set `entryProcedureId` via PATCH /bots/{botId}/config afterwards.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "FREE_FORM",
                      "DETERMINISTIC"
                    ]
                  },
                  "trigger": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 240
                  },
                  "content": {},
                  "position": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "name",
                  "type"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Procedure"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_PROCEDURE_NAME_CONFLICT`, or `BOT_PROCEDURE_LIMIT_EXCEEDED` when the bot is already at the per-bot cap. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/procedures/reorder": {
      "post": {
        "operationId": "reorderBotProcedures",
        "summary": "Reorder a bot’s procedures",
        "description": "Pass EVERY non-deleted procedure id exactly once. A partial list is refused rather than merged: position also drives the node ids of the compiled call flow, so a duplicate position is a compile-level ambiguity. Order does not decide which free-form procedure the model reaches for — the trigger does.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "procedureIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 20
                  }
                },
                "required": [
                  "procedureIds"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Procedure"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`BOT_PROCEDURE_REORDER_INCOMPLETE`; `details` names the missing and the unknown ids.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-procedures/{procedureId}": {
      "get": {
        "operationId": "getBotProcedure",
        "summary": "Get a procedure",
        "description": "Required scope: `bots.read`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "procedureId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Procedure"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBotProcedure",
        "summary": "Edit a procedure",
        "description": "Only the fields you send are touched, but the WHOLE procedure is re-validated, so a rename cannot leave a body that breaks its tier’s rules. `type` cannot be changed — the content shape depends on it; delete and re-create instead. `enabled: false` is the one change that takes effect WITHOUT a publish: it is checked live at dispatch, even against an already-published snapshot.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "procedureId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "trigger": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 240
                  },
                  "content": {},
                  "position": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Procedure"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_PROCEDURE_NAME_CONFLICT`. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBotProcedure",
        "summary": "Soft-delete a procedure",
        "description": "Deleting the bot’s ENTRY procedure is REFUSED (409 `BOT_PROCEDURE_ENTRY_IN_USE`) — it is the call flow, so clear `entryProcedureId` on the bot config first. Note this differs from workflows, where deleting the active one is allowed: a bot without a workflow falls back to prompt-only, a bot without its entry procedure does not. To stop a procedure immediately without deleting it, PATCH `enabled: false`.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Procedures"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "procedureId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "deleted"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_PROCEDURE_ENTRY_IN_USE` — the bot’s `entryProcedureId` still points here. Or `BOT_MANAGED_BY_BLUEPRINT` — the bot is managed by a Mediflo template (`blueprintRole` INSTANCE): only its knowledge base and template settings (in the Portal) can change. `details` carries `botId`, `blueprintId`, `releaseId`, `blueprintKey` and `releaseVersion`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-workflows/validate": {
      "post": {
        "operationId": "validateBotWorkflow",
        "summary": "Validate a workflow definition without saving",
        "description": "Stateless. Always 200 when the request is well-formed — the verdict is in `valid`. Iterate until `valid` is true, then create or update.\n\nRequired scope: `bots.read`.",
        "tags": [
          "Workflows"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "definition": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WorkflowValidationResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/knowledge": {
      "get": {
        "operationId": "getBotKnowledge",
        "summary": "Get the bot’s knowledge-base settings",
        "description": "Required scope: `knowledge.read`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeBase"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBotKnowledge",
        "summary": "Update the knowledge-base settings",
        "description": "Required scope: `knowledge.write`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "retrievalMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "every_turn",
                      "off"
                    ]
                  },
                  "requireKnowledge": {
                    "type": "boolean"
                  },
                  "maxCharacters": {
                    "type": "integer",
                    "minimum": 200,
                    "maximum": 20000
                  },
                  "maxChunks": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20
                  },
                  "maxVectorDistance": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 2
                  },
                  "searchDepth": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500
                  },
                  "timeoutMs": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5000
                  },
                  "requiredTimeoutMs": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5000
                  }
                },
                "required": [
                  "enabled",
                  "retrievalMode",
                  "requireKnowledge",
                  "maxCharacters",
                  "maxChunks",
                  "maxVectorDistance",
                  "searchDepth",
                  "timeoutMs",
                  "requiredTimeoutMs"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeBase"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/knowledge/sources": {
      "get": {
        "operationId": "listBotKnowledgeSources",
        "summary": "List knowledge sources",
        "description": "Required scope: `knowledge.read`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/KnowledgeSource"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createBotKnowledgeSource",
        "summary": "Create a text or structured knowledge source",
        "description": "Indexing is triggered automatically. File uploads are Portal-only in v1 — this endpoint takes JSON, not multipart.\n\nRequired scope: `knowledge.write`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "text"
                    ]
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "bodyText": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500000
                  },
                  "articleType": {
                    "type": "string",
                    "enum": [
                      "text",
                      "faq",
                      "info",
                      "pricing",
                      "doctors"
                    ],
                    "default": "text"
                  },
                  "structuredContent": {},
                  "questionVariants": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 3,
                      "maxLength": 300
                    },
                    "maxItems": 12
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 48
                    },
                    "maxItems": 16
                  },
                  "usageMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "prompt"
                    ],
                    "default": "auto"
                  },
                  "publishState": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "published"
                    ],
                    "default": "published"
                  },
                  "category": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "expiresAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  }
                },
                "required": [
                  "type",
                  "title"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeSource"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bots/{botId}/knowledge/sources/{sourceId}": {
      "get": {
        "operationId": "getBotKnowledgeSource",
        "summary": "Get a knowledge source with its content",
        "description": "Required scope: `knowledge.read`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "sourceId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeSourceDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBotKnowledgeSource",
        "summary": "Update a knowledge source",
        "description": "A content change snapshots a revision and triggers reindexing; tag-only edits do neither.\n\nRequired scope: `knowledge.write`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "sourceId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "bodyText": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500000
                  },
                  "articleType": {
                    "type": "string",
                    "enum": [
                      "text",
                      "faq",
                      "info",
                      "pricing",
                      "doctors"
                    ]
                  },
                  "structuredContent": {},
                  "questionVariants": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 3,
                      "maxLength": 300
                    },
                    "maxItems": 12
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 48
                    },
                    "maxItems": 16
                  },
                  "usageMode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "prompt"
                    ]
                  },
                  "publishState": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "published"
                    ]
                  },
                  "category": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "lastVerifiedAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  },
                  "expiresAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/KnowledgeSourceDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBotKnowledgeSource",
        "summary": "Delete a knowledge source",
        "description": "Soft delete — the row is retained and the index is rebuilt without it.\n\nRequired scope: `knowledge.write`.",
        "tags": [
          "Knowledge"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "botId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "sourceId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "deleted": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "deleted"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/locations": {
      "get": {
        "operationId": "listLocations",
        "summary": "List locations",
        "description": "Required scope: `locations.read`.",
        "tags": [
          "Locations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Location"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createLocation",
        "summary": "Create a location",
        "description": "`code` must be unique within the tenant.\n\nRequired scope: `locations.write`.",
        "tags": [
          "Locations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "street": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "postalCode": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 2,
                    "default": "PL"
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255,
                    "format": "email"
                  },
                  "timezone": {
                    "type": "string",
                    "maxLength": 64,
                    "default": "Europe/Warsaw"
                  },
                  "isActive": {
                    "type": "boolean",
                    "default": true
                  },
                  "instructions": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "name",
                  "code"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Location"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/locations/{locationId}": {
      "get": {
        "operationId": "getLocation",
        "summary": "Get a location",
        "description": "Required scope: `locations.read`.",
        "tags": [
          "Locations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "locationId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Location"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateLocation",
        "summary": "Update a location",
        "description": "Required scope: `locations.write`.",
        "tags": [
          "Locations"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "locationId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "street": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "postalCode": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 2,
                    "default": "PL"
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255,
                    "format": "email"
                  },
                  "timezone": {
                    "type": "string",
                    "maxLength": 64,
                    "default": "Europe/Warsaw"
                  },
                  "isActive": {
                    "type": "boolean",
                    "default": true
                  },
                  "instructions": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Location"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/phone-numbers": {
      "get": {
        "operationId": "listPhoneNumbers",
        "summary": "List phone numbers",
        "description": "Read-only. Numbers and trunks are provisioned by Mediflo; this API binds an existing number to a bot.\n\nRequired scope: `phone-numbers.read`.",
        "tags": [
          "Phone numbers"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PhoneNumber"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/phone-numbers/{phoneNumberId}/attach-bot": {
      "post": {
        "operationId": "attachBotToPhoneNumber",
        "summary": "Route an inbound number to a bot",
        "description": "Creates (or refreshes) the generated start → dispatchBot IVR flow and activates it. Idempotent. Returns 409 `PHONE_NUMBER_HAS_CUSTOM_FLOW` when the number already routes through a hand-built flow — those are never replaced.\n\nRequired scope: `bots.write`.",
        "tags": [
          "Phone numbers"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "phoneNumberId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "botId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "botId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/AttachBotResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The number routes through a custom IVR flow.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/model-catalog": {
      "get": {
        "operationId": "listModels",
        "summary": "Recommended bot settings",
        "description": "The settings every new bot is created with (`recommendedDefaults`). The models themselves are configured by Mediflo: the model lists (`models`, `recommendedChains`, `extractionModels`) and the model part of `recommendedDefaults` are returned only to a key that carries a Mediflo staff member’s authority.\n\nRequired scope: `model-catalog.read`.",
        "tags": [
          "Vocabularies"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ModelCatalog"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/meta/event-types": {
      "get": {
        "operationId": "listWebhookEventTypes",
        "summary": "List webhook event types and payload blocks",
        "description": "Any valid API key may read this — it is contract metadata, not tenant data. The event list depends on the features enabled for your organisation: event families of areas it has not enabled (e.g. `case.*`) are left out, so do not cache the response across organisations. `phiBlocks` marks the blocks that carry personal data, including sensitive data.\n\nRequired scope: `(any valid key)`.",
        "tags": [
          "Vocabularies"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/EventTypeCatalog"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints": {
      "get": {
        "operationId": "listWebhookEndpoints",
        "summary": "List webhook endpoints",
        "description": "Required scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createWebhookEndpoint",
        "summary": "Create a webhook endpoint",
        "description": "Returns the signing `secret` ONCE — store it before you close the response. The URL must be https and must resolve to a public address; private and link-local targets are rejected at save time. Default payload is core fields only; opt into PHI-bearing content blocks explicitly via `payloadConfig`. Limit: 20 endpoints per workspace.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "subscribedEvents": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "*"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "ping",
                            "bot_call.completed",
                            "call.completed",
                            "call.updated",
                            "call.transcript.ready",
                            "call.analysis.completed",
                            "task.created",
                            "task.updated",
                            "task.deleted",
                            "task.suggestion.resolved",
                            "case.created",
                            "case.updated",
                            "case.deleted",
                            "webhook_endpoint.auto_disabled"
                          ]
                        }
                      ]
                    },
                    "minItems": 1
                  },
                  "payloadConfig": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "call": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "bot_call": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "required": [
                  "url",
                  "subscribedEvents"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{endpointId}": {
      "get": {
        "operationId": "getWebhookEndpoint",
        "summary": "Get a webhook endpoint",
        "description": "Required scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "endpointId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhookEndpoint",
        "summary": "Update a webhook endpoint",
        "description": "`status` accepts `ENABLED` and `DISABLED` only — `AUTO_DISABLED` is set by us after sustained failure. Sending `ENABLED` also clears the failure counter, so a freshly fixed endpoint is not one failure away from being disabled again.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "endpointId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2048
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "subscribedEvents": {
                    "type": "array",
                    "items": {
                      "anyOf": [
                        {
                          "type": "string",
                          "enum": [
                            "*"
                          ]
                        },
                        {
                          "type": "string",
                          "enum": [
                            "ping",
                            "bot_call.completed",
                            "call.completed",
                            "call.updated",
                            "call.transcript.ready",
                            "call.analysis.completed",
                            "task.created",
                            "task.updated",
                            "task.deleted",
                            "task.suggestion.resolved",
                            "case.created",
                            "case.updated",
                            "case.deleted",
                            "webhook_endpoint.auto_disabled"
                          ]
                        }
                      ]
                    },
                    "minItems": 1
                  },
                  "payloadConfig": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "properties": {
                      "call": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "bot_call": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ENABLED",
                      "DISABLED"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhookEndpoint",
        "summary": "Delete a webhook endpoint",
        "description": "Soft delete. Pending deliveries stop immediately; the delivery log is preserved.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "endpointId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointDeleted"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{endpointId}/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookEndpointSecret",
        "summary": "Rotate an endpoint signing secret",
        "description": "Returns the new `secret` once. The previous secret keeps signing for 24 h — during that window every delivery carries TWO `v1=` entries, so accept the request if either verifies. `previousSecretExpiresAt` tells you when the old one stops.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "endpointId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-endpoints/{endpointId}/test": {
      "post": {
        "operationId": "sendWebhookTestEvent",
        "summary": "Send a test event",
        "description": "Sends a real event through the full delivery pipeline (signature, SSRF vetting, 10 s timeout), so a green result means your endpoint will actually work. The body is optional — omit it for a plain `ping`, or name any catalogued `eventType` to receive that type’s SAMPLE payload (the same object `GET /meta/event-types` publishes as `sampleEnvelope`). Every delivery from this route carries a `Mediflo-Event-Test: true` request header, which real events never do — branch on it to drop test traffic. Repeated sends of the SAME type within one minute collapse onto a single event (each still gets its own delivery row); different types never collapse. Asynchronous: poll the returned `deliveryId` in the delivery log. The endpoint must be `ENABLED`.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "endpointId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eventType": {
                    "type": "string",
                    "enum": [
                      "ping",
                      "bot_call.completed",
                      "call.completed",
                      "call.updated",
                      "call.transcript.ready",
                      "call.analysis.completed",
                      "task.created",
                      "task.updated",
                      "task.deleted",
                      "task.suggestion.resolved",
                      "case.created",
                      "case.updated",
                      "case.deleted",
                      "webhook_endpoint.auto_disabled"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookTestEventAccepted"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries": {
      "get": {
        "operationId": "listWebhookDeliveries",
        "summary": "List webhook deliveries",
        "description": "The delivery log doubles as your analytics source — attempt counts, HTTP statuses and latencies are all here.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "endpointId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "RETRYING",
                "SUCCEEDED",
                "EXHAUSTED",
                "SKIPPED"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ping",
                "bot_call.completed",
                "call.completed",
                "call.updated",
                "call.transcript.ready",
                "call.analysis.completed",
                "task.created",
                "task.updated",
                "task.deleted",
                "task.suggestion.resolved",
                "case.created",
                "case.updated",
                "case.deleted",
                "webhook_endpoint.auto_disabled"
              ]
            },
            "required": false,
            "name": "eventType",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries/{deliveryId}": {
      "get": {
        "operationId": "getWebhookDelivery",
        "summary": "Get a webhook delivery",
        "description": "One row of the delivery log — the poll half of a test send. Same fields as the list. Your endpoint’s response body is never retained; for the CONTENT of the delivery see `/webhook-deliveries/{deliveryId}/payload`.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "deliveryId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries/{deliveryId}/payload": {
      "get": {
        "operationId": "getWebhookDeliveryPayload",
        "summary": "Get the payload a delivery carried",
        "description": "Returns the envelope CONTENT this delivery carried, as the projection for ITS endpoint — the same projection that composes real deliveries, so a content block the endpoint did not opt into is absent here exactly as it was absent on the wire. It is not an archive of the transmitted bytes: we store none, so this is rebuilt from the stored event and is a re-serialization — never verify a signature against it. `payloadConfig` is returned alongside because it is read as it is NOW; if the endpoint’s opt-ins changed after this delivery, you are seeing what it would receive today. Payloads disappear with their event after the retention window (410 once the event is pruned). Requires `webhook-payloads.read`, which is separate from `webhooks.manage` and is granted by NO wildcard — including `*` and `webhooks.*` — because for endpoints subscribed to the `outcome` or `transcript` blocks this content includes personal data, including sensitive data.\n\nRequired scope: `webhook-payloads.read`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "deliveryId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDeliveredPayload"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "410": {
            "description": "The delivery still exists, but the event it was built from has been pruned, so there is no payload left to reconstruct.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries/{deliveryId}/redeliver": {
      "post": {
        "operationId": "redeliverWebhookDelivery",
        "summary": "Redeliver a webhook delivery",
        "description": "Allowed from `SUCCEEDED`, `EXHAUSTED`, `SKIPPED` and `RETRYING`. `attemptCount` is preserved — it is the record of how hard we tried. The delivery is picked up within about 90 seconds.\n\nRequired scope: `webhooks.manage`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "deliveryId",
            "in": "path"
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDeliveryAccepted"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The delivery is still in flight (`PENDING`) and cannot be replayed yet.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-sessions": {
      "get": {
        "operationId": "listBotSessions",
        "summary": "List bot sessions",
        "description": "A bot session is one dispatch of one bot to one number — NOT a telephony call record. `status` filters on the same derived status the response reports.\n\nRequired scope: `bot-calls.read`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "botId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "IN_PROGRESS",
                "COMPLETED",
                "FAILED",
                "NO_ANSWER",
                "VOICEMAIL",
                "DISCONNECTED"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "ISO 8601. Inclusive lower bound on the session start."
            },
            "required": false,
            "description": "ISO 8601. Inclusive lower bound on the session start.",
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "ISO 8601. Inclusive upper bound on the session start."
            },
            "required": false,
            "description": "ISO 8601. Inclusive upper bound on the session start.",
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BotSession"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createBotSession",
        "summary": "Place an outbound bot call",
        "description": "PLACES A REAL PHONE CALL. Dials `phoneNumber` with the bot `botId` NOW — there is no scheduling, no retry ladder and no confirmation step; the partner owns the timing. Calls are only placed between 08:00 and 20:00 in the tenant’s timezone (`OUTSIDE_CALL_WINDOW` otherwise, window echoed in `details`); nothing is queued. `idempotencyKey` is REQUIRED and is what makes a retry safe: the same key never dials twice — a replay returns the existing session with **200** instead of **201**, and the same key with a different bot or number is refused with `IDEMPOTENCY_KEY_REUSED`. The key is consumed the moment the dispatcher accepts the request — even if the call then fails before anyone picks up (`FAILED` when the call never connects, `no_answer`, `voicemail`): a replay returns that session and never re-dials, so calling the same person again needs a NEW key. Every dispatcher-side error carries `details.dispatchId`. Use your own message or notification id. Requires the opt-in scope `bot-calls.write` (no wildcard grants it). The bot needs an outbound phone number (`BOT_NO_OUTBOUND_NUMBER`) and a published configuration (`BOT_NOT_PUBLISHED`); check `GET /bots/{botId}/readiness` → `readyForOutbound`. `context` is rendered into the bot’s prompt, greeting and workflow as `{{reason}}`, `{{message}}`, `{{appointment_date}}`, `{{appointment_time}}`, `{{appointment_doctor_name}}` (from `appointment.staffName`, or its medical alias `doctorName`), `{{appointment_service_name}}`, `{{appointment_location_name}}`, `{{appointment_address}}`, `{{appointment_external_id}}` plus `variables` verbatim; reserved names are refused as a `422 VALIDATION_ERROR` on `context.variables.<name>`. The bot must be switched on (`BOT_INACTIVE` otherwise). The response is the session as accepted by the dispatcher, still `IN_PROGRESS`: the outcome arrives on the `bot_call.completed` webhook (status completed / no_answer / voicemail / failed / stuck, `durationSec`, `outcome`, `links`) and on `GET /bot-sessions/{dispatchId}`. Mid-call actions (reschedule, cancel) are the bot’s own tools, configured on the bot. Sessions placed this way carry `attemptId` `ext-<dispatchId>`.\n\nRequired scope: `bot-calls.write`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "botId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "phoneNumber": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "description": "The number to dial, E.164."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128,
                    "description": "Caller-chosen key that makes the request safe to retry: the same key never places a second call. Use your own message/notification id."
                  },
                  "context": {
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{0,63}$",
                        "description": "Why the bot is calling, as a stable slug — e.g. `visit_reminder` or `visit_rescheduled` (clinics), `booking_reminder`, `order_status`; use the slugs the bot’s workflow expects. Rendered as `{{reason}}`; the bot prompt or workflow branches on it."
                      },
                      "message": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 1000,
                        "description": "The information to convey, in the language of the person called. Rendered as `{{message}}`."
                      },
                      "appointment": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                          },
                          "time": {
                            "type": "string",
                            "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                          },
                          "staffName": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "description": "Who the appointment is with (a staff member, specialist or consultant). Rendered as `{{appointment_doctor_name}}`."
                          },
                          "doctorName": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "description": "Medical name of `staffName` (the doctor the visit is with); same field, same `{{appointment_doctor_name}}`. Send one or the other — both are accepted only when equal."
                          },
                          "serviceName": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "locationName": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "address": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 300
                          },
                          "externalId": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 128
                          }
                        },
                        "additionalProperties": false,
                        "description": "Flattened to `{{appointment_date}}`, `{{appointment_time}}`, …"
                      },
                      "variables": {
                        "type": "object",
                        "additionalProperties": {
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 2000
                            },
                            {
                              "type": "number"
                            },
                            {
                              "type": "boolean"
                            }
                          ]
                        },
                        "description": "Extra template variables, rendered verbatim as `{{name}}`. At most 40 keys."
                      }
                    },
                    "required": [
                      "reason"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "botId",
                  "phoneNumber",
                  "idempotencyKey",
                  "context"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay: `idempotencyKey` matched a session this tenant already placed. The existing session is returned; no call was placed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`TELEPHONY_INVALID_NUMBER` — the dispatcher rejected the number as not dialable. `BOT_SESSION_CREATE_FAILED` with status 400 — the dispatcher refused the bot configuration (e.g. a required model missing on the published snapshot); `details` carries the upstream reason. Both include `details.dispatchId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "`API_KEY_INSUFFICIENT_SCOPE` — the key lacks `bot-calls.write`. `TELEPHONY_COUNTRY_NOT_ALLOWED` — the destination country is outside what this tenant may call.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "`BOT_NOT_FOUND` — no such bot in this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`BOT_SESSION_CREATE_FAILED` with status 409 — rare: the dispatcher reported this `idempotencyKey`’s dispatch id as already taken, but the session could not be read back yet. Nothing new was dialed. Retry with the SAME `idempotencyKey`: the replay returns the existing session (`200`); `details.dispatchId` is the id to check on `GET /bot-sessions/{dispatchId}`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "`VALIDATION_ERROR` (body shape, including a reserved `context.variables` name; `details` is `{ field, message }[]`), `OUTSIDE_CALL_WINDOW` (`details`: `timezone`, `window { startHour, endHour }`, `localTime`), `IDEMPOTENCY_KEY_REUSED` (`details.dispatchId` = the session that already holds the key), `BOT_INACTIVE` (the bot is switched off — the operator kill switch), `BOT_NO_OUTBOUND_NUMBER`, `BOT_NOT_PUBLISHED`. A `BOT_SESSION_CREATE_FAILED` with a 4xx status mirrors an operator-fixable refusal from the dispatcher (capacity misconfigured, trunk not usable) — `details` carries the upstream reason and `dispatchId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "`BOT_SESSION_LINE_BUSY` — the number is already being dialed or the bot is at its concurrent-call limit; retry shortly with the SAME `idempotencyKey` (if the call was already accepted you get it back as a `200` replay, never a second call; `details.dispatchId`). Also the per-key rate limit (`Retry-After`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "`BOT_SESSION_CREATE_FAILED` — the dispatcher failed or was unreachable. The request MAY have been accepted first: retry later with the SAME `idempotencyKey` — a `200` replay means it was and no second call is placed; `details.dispatchId` is the id to check on `GET /bot-sessions/{dispatchId}`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-sessions/{dispatchId}": {
      "get": {
        "operationId": "getBotSession",
        "summary": "Get a bot session",
        "description": "Adds the bot’s own structured `outcome` for the call, plus links to the telemetry, transcript and recording sub-resources.\n\nRequired scope: `bot-calls.read`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "dispatchId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-sessions/{dispatchId}/telemetry": {
      "get": {
        "operationId": "getBotSessionTelemetry",
        "summary": "Get per-call diagnostics",
        "description": "Why the call closed, what errored, how the pipeline performed. Deliberately serves NO conversation content: the transcript is a separate call, so an integration that only debugs never receives caller speech. `other` carries a curated set of further diagnostics, and runtime error messages are summarised to their type — short classified messages such as SIP statuses pass as written, and Mediflo support sees the full text; treat the named fields as the contract.\n\nRequired scope: `bot-calls.read`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "dispatchId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionTelemetry"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-sessions/{dispatchId}/transcript": {
      "get": {
        "operationId": "getBotSessionTranscript",
        "summary": "Get the conversation transcript",
        "description": "Separate from `/telemetry` on purpose. `available: false` means the session has no stored transcript. Contains what the caller and the bot said — personal data, including sensitive data.\n\nRequired scope: `bot-calls.read`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "dispatchId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionTranscript"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/bot-sessions/{dispatchId}/recording": {
      "get": {
        "operationId": "getBotSessionRecording",
        "summary": "Get a short-lived URL to the call recording",
        "description": "Separate from `/telemetry` on purpose, like `/transcript`: the audio is what the caller and the bot said — personal data, including sensitive data. Returns a presigned URL into the object store that expires after 15 minutes; the bytes are never proxied through the API. `available: false` means the session has no stored recording. A malformed or unknown `dispatchId` is a 404, identical to one that belongs to another tenant. The `bot_call.completed` webhook’s `links.recording` points here.\n\nRequired scope: `bot-calls.read`.",
        "tags": [
          "Bot sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "dispatchId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BotSessionRecording"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "The object store could not sign a URL (`BOT_SESSION_RECORDING_FETCH_FAILED`). Retry later; the body never carries the underlying error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/tickets": {
      "get": {
        "operationId": "listTickets",
        "summary": "List support tickets",
        "description": "Required scope: `tickets.read`.",
        "tags": [
          "Support tickets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "ACKNOWLEDGED",
                "IN_PROGRESS",
                "RESOLVED",
                "CLOSED"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Ticket"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createTicket",
        "summary": "File a support ticket with Mediflo",
        "description": "Attach the bot sessions that ARE the problem via `botSessionIds` — each id is validated against your tenant, and an unknown one is a 422 naming it. `reportedByUserId` is OPTIONAL: pass it when you know who is reporting (resolve one with `GET /users`) and the ticket is attributed to that person; omit it and the ticket is credited to the person who created the API key, still with `reportedVia: \"external_api\"`. Only a system key with no human creator files with no reporter.\n\nRequired scope: `tickets.write`.",
        "tags": [
          "Support tickets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "description": "Becomes the ticket subject."
                  },
                  "description": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH",
                      "URGENT"
                    ],
                    "default": "MEDIUM"
                  },
                  "reportedByUserId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "botSessionIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 20,
                    "description": "Bot sessions that ARE the problem. Max 20. Each id is validated against your tenant; an unknown id is a 422."
                  },
                  "contextUrl": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "contextMetadata": {
                    "type": "object",
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "title",
                  "description"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/tickets/{ticketId}": {
      "get": {
        "operationId": "getTicket",
        "summary": "Get a support ticket",
        "description": "Required scope: `tickets.read`.",
        "tags": [
          "Support tickets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "ticketId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/tickets/{ticketId}/sessions": {
      "post": {
        "operationId": "attachTicketSessions",
        "summary": "Attach more bot sessions to a ticket",
        "description": "The \"it keeps happening\" flow. Re-attaching a session already on the ticket is a no-op, not an error, so a retry is safe.\n\nRequired scope: `tickets.write`.",
        "tags": [
          "Support tickets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "ticketId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "botSessionIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 20
                  }
                },
                "required": [
                  "botSessionIds"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TicketSessionsAttached"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/cases": {
      "get": {
        "operationId": "listCases",
        "summary": "List customer cases",
        "description": "Newest number first, or most recently updated with `sort=updatedAt`. `status` and `category` take comma-separated lists; `open=true` keeps only open cases (NEW, IN_PROGRESS, WAITING_*); `assignedTo` takes a user id or `unassigned`; `search` matches title words or a case number (`1042`, `S-1042`); `resourceType` + `resourceId` (together) list the cases linked to one record, e.g. a call. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.read`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 10000,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "NEW",
                  "IN_PROGRESS",
                  "WAITING_CUSTOMER",
                  "WAITING_THIRD_PARTY",
                  "RESOLVED",
                  "CLOSED",
                  "CANCELLED"
                ]
              },
              "description": "Comma-separated statuses, e.g. `NEW,IN_PROGRESS`. An unknown value is a 422 `VALIDATION_ERROR` on `status`."
            },
            "required": false,
            "description": "Comma-separated statuses, e.g. `NEW,IN_PROGRESS`. An unknown value is a 422 `VALIDATION_ERROR` on `status`.",
            "style": "form",
            "explode": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "required": false,
            "name": "open",
            "in": "query"
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]*$"
              },
              "description": "Comma-separated category keys, e.g. `bug,outage`. A malformed key is a 422 `VALIDATION_ERROR` on `category`; a well-formed key no case uses simply matches nothing."
            },
            "required": false,
            "description": "Comma-separated category keys, e.g. `bug,outage`. A malformed key is a 422 `VALIDATION_ERROR` on `category`; a well-formed key no case uses simply matches nothing.",
            "style": "form",
            "explode": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "string",
                  "enum": [
                    "unassigned"
                  ]
                }
              ]
            },
            "required": false,
            "name": "assignedTo",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "contactId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "companyId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "required": false,
            "name": "search",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "TELEPHONY_CALL",
                "BOT_SESSION",
                "EMAIL_CONVERSATION",
                "CHAT_CONVERSATION",
                "MESSAGING_CONVERSATION",
                "CONTACT_REQUEST"
              ]
            },
            "required": false,
            "name": "resourceType",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "resourceId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "number",
                "updatedAt"
              ],
              "default": "number"
            },
            "required": false,
            "name": "sort",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Case"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createCase",
        "summary": "Create a customer case",
        "description": "`title` and `categoryKey` are required. Every referenced record (contact, company, topic, assignee, tags, `links`) must belong to your organisation; an unknown one is a 422 naming the field, never a hint that it exists elsewhere. `companyId` needs an organisation that keeps companies (else 404 `TENANT_MODULE_UNAVAILABLE`). The number is allocated atomically; the case's `source` is `API`. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.write`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "categoryKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z][a-z0-9_]*$"
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20000
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH",
                      "URGENT"
                    ]
                  },
                  "topicId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "contactId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "companyId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "reporterName": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "reporterPhone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "assignedToUserId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "locationText": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "externalSystem": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 100
                  },
                  "externalRef": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "externalUrl": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2048
                  },
                  "dueAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  },
                  "customFields": {
                    "type": "object",
                    "additionalProperties": {}
                  },
                  "tagIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 20
                  },
                  "links": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "resourceType": {
                          "type": "string",
                          "enum": [
                            "TELEPHONY_CALL",
                            "BOT_SESSION",
                            "EMAIL_CONVERSATION",
                            "CHAT_CONVERSATION",
                            "MESSAGING_CONVERSATION",
                            "CONTACT_REQUEST"
                          ]
                        },
                        "resourceId": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "resourceType",
                        "resourceId"
                      ],
                      "additionalProperties": false
                    },
                    "maxItems": 10
                  }
                },
                "required": [
                  "title",
                  "categoryKey"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/cases/{caseId}": {
      "get": {
        "operationId": "getCase",
        "summary": "Get a customer case",
        "description": "With its links, and its tasks when the key also holds `tasks.read`. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.read`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateCase",
        "summary": "Update a customer case",
        "description": "Only the fields you send change; `null` clears an optional field. A status change stamps `statusChangedAt`, and `resolvedAt` / `closedAt` when it reaches RESOLVED / CLOSED. `customFields` replaces the form's full set. Deleting a case stays in the Portal. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.write`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "categoryKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-z][a-z0-9_]*$"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "NEW",
                      "IN_PROGRESS",
                      "WAITING_CUSTOMER",
                      "WAITING_THIRD_PARTY",
                      "RESOLVED",
                      "CLOSED",
                      "CANCELLED"
                    ]
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20000
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH",
                      "URGENT"
                    ]
                  },
                  "topicId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "contactId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "companyId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "reporterName": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "reporterPhone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "assignedToUserId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid"
                  },
                  "locationText": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "externalSystem": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 100
                  },
                  "externalRef": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 255
                  },
                  "externalUrl": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2048
                  },
                  "dueAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time"
                  },
                  "customFields": {
                    "type": "object",
                    "additionalProperties": {}
                  },
                  "tagIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "maxItems": 20
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/cases/{caseId}/comments": {
      "get": {
        "operationId": "listCaseComments",
        "summary": "List a case’s internal notes",
        "description": "The newest 200 notes, oldest first. Not paginated. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.read`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseComment"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createCaseComment",
        "summary": "Add an internal note to a case",
        "description": "Credited to the person who created the API key; a system key writes a system note. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.write`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000
                  }
                },
                "required": [
                  "content"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseComment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/cases/{caseId}/links": {
      "post": {
        "operationId": "createCaseLink",
        "summary": "Link a call or conversation to a case",
        "description": "The record must belong to your organisation. Linking the same record again answers 200 with the existing link, so a retry is safe. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.write`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "resourceType": {
                    "type": "string",
                    "enum": [
                      "TELEPHONY_CALL",
                      "BOT_SESSION",
                      "EMAIL_CONVERSATION",
                      "CHAT_CONVERSATION",
                      "MESSAGING_CONVERSATION",
                      "CONTACT_REQUEST"
                    ]
                  },
                  "resourceId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "resourceType",
                  "resourceId"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The record was already linked; the existing link.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseLink"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseLink"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/cases/{caseId}/links/{linkId}": {
      "delete": {
        "operationId": "deleteCaseLink",
        "summary": "Remove a link from a case",
        "description": "The case keeps an `unlinked` entry in its history. A link of another case answers 404 `CASE_LINK_NOT_FOUND`. Available to organisations with customer cases switched on: an organisation whose business type has no cases gets 404 `TENANT_MODULE_UNAVAILABLE`, one where cases are not switched on yet gets 403 `FEATURE_NOT_AVAILABLE`.\n\nRequired scope: `cases.write`.",
        "tags": [
          "Cases"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "caseId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "linkId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/CaseLinkDeleted"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointment-types": {
      "get": {
        "operationId": "listSchedulingAppointmentTypes",
        "summary": "List bookable visit types",
        "description": "Only types the clinic opened to online booking. `price` is present only for privately paid visits that have one.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "specialistId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "locationId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AppointmentType"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/specialists": {
      "get": {
        "operationId": "listSchedulingSpecialists",
        "summary": "List bookable specialists",
        "description": "Required scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "locationId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "appointmentTypeId",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Specialist"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/booking-requirements": {
      "get": {
        "operationId": "getBookingRequirements",
        "summary": "Patient fields, notice policies, sites and readiness",
        "description": "Call this first. `bookingEnabled: false` means the clinic cannot take a booking right now and `unavailableReason` says why — a 200, not an error, so a client can say so rather than retry.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BookingRequirements"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/availability": {
      "get": {
        "operationId": "getSchedulingAvailability",
        "summary": "Free slots for a visit type",
        "description": "An empty `data` array is a normal answer, not an error. `degraded: true` means an external calendar was unreachable and the listed times are not yet certain — never present a degraded slot as confirmed.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "appointmentTypeId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "specialistId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "locationId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "required": true,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "required": true,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 25,
              "default": 10
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AvailabilitySlot"
                      }
                    },
                    "degraded": {
                      "type": "boolean"
                    },
                    "degradedReason": {
                      "type": "string",
                      "enum": [
                        "calendar_unreachable"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "degraded"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/holds": {
      "post": {
        "operationId": "holdSchedulingSlot",
        "summary": "Hold a slot for a few minutes",
        "description": "A hold belongs to the REQUEST that created it, and only the same owner can book it or release it. Send `X-Mediflo-Scheduling-Session` and repeat the SAME value on the POST /scheduling/appointments that consumes this hold and on DELETE /scheduling/holds/{holdId} — without the header each request is its own owner, so the hold you just created can neither be booked nor released and simply expires.\n\nRequired scope: `scheduling.book`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,128}$",
              "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header."
            },
            "required": false,
            "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header.",
            "name": "X-Mediflo-Scheduling-Session",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slotToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "slotToken"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "holdId": {
                          "type": "string"
                        },
                        "expiresAt": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "holdId",
                        "expiresAt"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/holds/{holdId}": {
      "delete": {
        "operationId": "releaseSchedulingHold",
        "summary": "Release a hold",
        "description": "Idempotent: releasing an already-expired hold succeeds, because the caller's goal is satisfied either way. Pass the same `X-Mediflo-Scheduling-Session` value you held the slot with — a hold is released only by its own owner, and without the header this request is a different owner, so the hold stays until it expires.\n\nRequired scope: `scheduling.book`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "holdId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "specialistId",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,128}$",
              "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header."
            },
            "required": false,
            "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header.",
            "name": "X-Mediflo-Scheduling-Session",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "released": {
                          "type": "boolean"
                        },
                        "holdId": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "released",
                        "holdId"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointments": {
      "post": {
        "operationId": "bookSchedulingAppointment",
        "summary": "Book an appointment",
        "description": "Pass `slotToken` or `holdId`, and `patientRef` (from /patients/lookup) or `patient`. **202** means the outcome is not yet known: the body carries an `operationId` — poll GET /scheduling/booking-operations/{operationId} and do NOT re-POST, which risks a second appointment. `idempotencyKey` is optional and exists for retries: reusing a key MUST repeat the identical request — a different body under a used key is refused with `SCHEDULING_IDEMPOTENCY_MISMATCH` (409) and books nothing. Booking with a `holdId` REQUIRES the same `X-Mediflo-Scheduling-Session` value you created the hold with: a hold belongs to the request that made it, so without the header this request is a different owner and the booking answers `SLOT_TAKEN` on the slot you are holding. Booking straight from a `slotToken` needs no hold and no header.\n\nRequired scope: `scheduling.book`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,128}$",
              "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header."
            },
            "required": false,
            "description": "Your own id for ONE booking flow (letters, digits and `._:-`, 1–128 chars). REQUIRED to use a hold: send the SAME value on POST /scheduling/holds, on the POST /scheduling/appointments that consumes the hold, and on DELETE /scheduling/holds/{holdId}. Without this header every request is its own owner and cannot touch another request’s hold — booking a `holdId` then answers `SLOT_TAKEN` and the hold can only expire. Booking straight from a `slotToken` needs no hold and no header.",
            "name": "X-Mediflo-Scheduling-Session",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slotToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "holdId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "patientRef": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "patient": {
                    "type": "object",
                    "properties": {
                      "firstName": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "lastName": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 80
                      },
                      "phone": {
                        "type": "string",
                        "pattern": "^\\+[1-9]\\d{6,14}$"
                      },
                      "alternativePhone": {
                        "type": "string",
                        "pattern": "^\\+[1-9]\\d{6,14}$"
                      },
                      "dateOfBirth": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "pesel": {
                        "type": "string",
                        "pattern": "^\\d{11}$"
                      }
                    },
                    "required": [
                      "lastName",
                      "phone"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Appointment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted, outcome not yet resolved. External success envelope `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN`. Poll GET /scheduling/booking-operations/{operationId}; do NOT retry this POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "operationId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "UNCERTAIN"
                          ]
                        }
                      },
                      "required": [
                        "operationId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listSchedulingAppointments",
        "summary": "Upcoming appointments for a phone number (deprecated)",
        "description": "Each entry carries an `actionToken` — the handle the `scheduling.modify` endpoints require — and the patient’s masked name. **Deprecated:** the phone number travels in the query string, where proxy logs and error trackers keep it. Use POST /scheduling/appointments/search, which takes the same number in a body and answers identically. This form keeps working.\n\nRequired scope: `scheduling.read`.",
        "deprecated": true,
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\+[1-9]\\d{6,14}$"
            },
            "required": true,
            "name": "contactPhone",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ActionableAppointment"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/booking-operations/{operationId}": {
      "get": {
        "operationId": "getSchedulingBookingOperation",
        "summary": "Outcome of an unresolved booking",
        "description": "The only correct way to find out what happened to a 202. `PENDING`/`UNCERTAIN` means it is still being resolved; poll, never re-book.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "operationId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/BookingOperation"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointments/search": {
      "post": {
        "operationId": "searchSchedulingAppointments",
        "summary": "Upcoming appointments for a phone number",
        "description": "Reads only — a POST because the phone number belongs in a body, not in a URL that logs keep. Each entry carries an `actionToken` — the handle the `scheduling.modify` endpoints require — and the patient’s masked name.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contactPhone": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$"
                  }
                },
                "required": [
                  "contactPhone"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ActionableAppointment"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointment-actions/reschedule": {
      "post": {
        "operationId": "rescheduleSchedulingAppointmentByToken",
        "summary": "Move the caller's own appointment",
        "description": "The caller-bound door. The `actionToken` already carries the appointment version, so no `expectedVersion` is needed. **202** is a success: `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN` — poll, do NOT retry.\n\nRequired scope: `scheduling.modify`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "actionToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "slotToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "actionToken",
                  "slotToken"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Appointment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted, outcome not yet resolved. External success envelope `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN`. Poll GET /scheduling/booking-operations/{operationId}; do NOT retry this POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "operationId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "UNCERTAIN"
                          ]
                        }
                      },
                      "required": [
                        "operationId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointment-actions/cancel": {
      "post": {
        "operationId": "cancelSchedulingAppointmentByToken",
        "summary": "Cancel the caller's own appointment",
        "description": "The caller-bound door. **202** is a success: `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN` — poll, do NOT retry.\n\nRequired scope: `scheduling.modify`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "actionToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "actionToken"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Appointment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted, outcome not yet resolved. External success envelope `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN`. Poll GET /scheduling/booking-operations/{operationId}; do NOT retry this POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "operationId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "UNCERTAIN"
                          ]
                        }
                      },
                      "required": [
                        "operationId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointments/{appointmentId}/reschedule": {
      "post": {
        "operationId": "rescheduleSchedulingAppointment",
        "summary": "Move any appointment (staff and partner keys)",
        "description": "`expectedVersion` is required: a mismatch answers `SCHEDULING_STALE_VERSION` (409) instead of overwriting a change you never read. **202** is a success: `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN` — poll, do NOT retry.\n\nRequired scope: `scheduling.manage`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "appointmentId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slotToken": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "expectedVersion": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "required": [
                  "slotToken",
                  "expectedVersion"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Appointment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted, outcome not yet resolved. External success envelope `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN`. Poll GET /scheduling/booking-operations/{operationId}; do NOT retry this POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "operationId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "UNCERTAIN"
                          ]
                        }
                      },
                      "required": [
                        "operationId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/appointments/{appointmentId}/cancel": {
      "post": {
        "operationId": "cancelSchedulingAppointment",
        "summary": "Cancel any appointment (staff and partner keys)",
        "description": "The tenant-wide door. **202** is a success: `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN` — poll, do NOT retry.\n\nRequired scope: `scheduling.manage`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "appointmentId",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expectedVersion": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "expectedVersion"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Appointment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Accepted, outcome not yet resolved. External success envelope `{ data: { operationId, status } }` where `status` is `PENDING` or `UNCERTAIN`. Poll GET /scheduling/booking-operations/{operationId}; do NOT retry this POST.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "operationId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "UNCERTAIN"
                          ]
                        }
                      },
                      "required": [
                        "operationId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/scheduling/callback-requests": {
      "post": {
        "operationId": "createSchedulingCallbackRequest",
        "summary": "Ask the clinic to call the patient back",
        "description": "Filing a contact request books nothing, so it sits on the read scope: an integration that may only browse can still escalate to a human.\n\nRequired scope: `scheduling.read`.",
        "tags": [
          "Scheduling"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  },
                  "appointmentId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "contactPhone": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$"
                  }
                },
                "required": [
                  "reason"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "contactRequestId": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "contactRequestId"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/patients/lookup": {
      "get": {
        "operationId": "lookupPatient",
        "summary": "Find a patient by phone number (deprecated)",
        "description": "An unknown number answers 200 with `found: false` — a new patient is the normal case, not an error, and a 404 here would be an existence oracle. Names are masked; patients are named by an opaque `patientRef`. **Deprecated:** the phone number (and the optional surname) travel in the query string, where proxy logs and error trackers keep them. Use POST /patients/lookup, which takes the same fields in a body and answers identically. This form keeps working.\n\nRequired scope: `patients.read`.",
        "deprecated": true,
        "tags": [
          "Patients"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\+[1-9]\\d{6,14}$"
            },
            "required": true,
            "name": "contactPhone",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 80
            },
            "required": false,
            "name": "lastName",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PatientLookup"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "lookupPatientByBody",
        "summary": "Find a patient by phone number",
        "description": "Reads only — a POST because the phone number belongs in a body, not in a URL that logs keep. An unknown number answers 200 with `found: false` — a new patient is the normal case, not an error, and a 404 here would be an existence oracle. Names are masked; patients are named by an opaque `patientRef`.\n\nRequired scope: `patients.read`.",
        "tags": [
          "Patients"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contactPhone": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$"
                  },
                  "lastName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  }
                },
                "required": [
                  "contactPhone"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/PatientLookup"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, expired or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not found within this tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed. `details` is an array of `{ field, message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "VALIDATION_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ValidationIssue"
                          }
                        }
                      },
                      "required": [
                        "code",
                        "message",
                        "details"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Per-key rate limit exceeded. Honour `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
