{
  "openapi": "3.1.0",
  "info": {
    "title": "ChatWithHuman.ai API",
    "version": "2.4.1",
    "summary": "Route AI agent sessions to verified human experts, billed per minute.",
    "description": "Human-in-the-loop escalation for AI agents.\n\nRoutes are mounted under `/api` on the site origin. Agent-facing session routes accept `Authorization: Bearer <API key>` (keys are prefixed `cwh_live_`, created via `POST /api/keys` or the dashboard) or a signed-in browser session; account routes need the session cookie.\n\nPricing: each session has a tier chosen at creation — `standard` ($10/min, 1000 cents) or `priority` ($25/min, 2500 cents, guaranteed fast human response). Billing runs from status `connected` to `closed` in whole minutes (1-minute minimum); the invoice is minutes × tier rate with no platform fee (`platformFeeCents` is 0). Enterprise (from $250,000/year) is contract-billed and has no API tier.\n\nSales: `POST /api/sales-chat` (AI sales assistant, JSON or SSE; scripted lead capture when no model key is configured) and `POST /api/leads` (structured lead, no chat) — public, rate-limited per IP. Responses include a human handoff contact (text or call Chris Mai, 415-375-5872).\n\nNot live yet: webhook delivery (`webhook_url` is stored only — use the SSE stream), spending caps, sandbox keys, MCP.",
    "contact": {
      "name": "ChatWithHuman.ai",
      "url": "https://chatwithhuman.chrismai.ai"
    },
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://chatwithhuman.chrismai.ai",
      "description": "Site origin (routes are under /api)"
    }
  ],
  "externalDocs": {
    "description": "Developer docs",
    "url": "https://chatwithhuman.chrismai.ai/docs"
  },
  "tags": [
    {
      "name": "sessions",
      "description": "Escalation sessions between an agent and a human operator"
    },
    {
      "name": "scheduling",
      "description": "Operators, availability and bookings"
    },
    {
      "name": "keys",
      "description": "API key management"
    },
    {
      "name": "billing",
      "description": "Metering, usage and invoices"
    },
    {
      "name": "checkout",
      "description": "Stripe checkout"
    },
    {
      "name": "auth",
      "description": "Session auth (better-auth)"
    },
    {
      "name": "system",
      "description": "Health and status"
    },
    {
      "name": "sales",
      "description": "AI sales chat and lead capture (Enterprise from $250,000/year, or any plan question)"
    }
  ],
  "paths": {
    "/api/sessions": {
      "post": {
        "tags": [
          "sessions"
        ],
        "operationId": "createSession",
        "summary": "Escalate: create a session (queued for a human)",
        "description": "Creates a queued escalation session. Choose the pricing tier with `tier` (`standard` $10/min default, `priority` $25/min). The response echoes `tier` and `rate_cents_per_minute`. The returned session_id is used for messages, events and status changes.",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session queued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateSessionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "get": {
        "tags": [
          "sessions"
        ],
        "operationId": "listSessions",
        "summary": "List sessions (operator queue)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChatSession"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sessions/history": {
      "get": {
        "tags": [
          "sessions"
        ],
        "operationId": "sessionHistory",
        "summary": "Search past sessions with duration and invoice",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Comma-separated: queued, connected, closed, or \"all\"",
            "schema": {
              "type": "string",
              "examples": [
                "closed"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Created on/after (date)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Created on/before (date, inclusive)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionHistoryPage"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sessions/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Session id",
          "schema": {
            "type": "string",
            "examples": [
              "ses_x9k2m"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "sessions"
        ],
        "operationId": "getSession",
        "summary": "Get a session with its full transcript",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ChatSession"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tier": {
                          "$ref": "#/components/schemas/Tier"
                        },
                        "messages": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/ChatMessage"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "tags": [
          "sessions"
        ],
        "operationId": "updateSession",
        "summary": "Change session status (connect = billing starts, close = invoice)",
        "description": "Setting `connected` records billingStartedAt and a session_start billing event. Setting `closed` computes whole minutes since billingStartedAt (minimum 1), writes a session_end event and creates a session invoice at the session tier rate (standard 1000 / priority 2500 cents per minute, no platform fee). Emits an SSE `status` event.",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSessionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatSession"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sessions/{id}/messages": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Session id",
          "schema": {
            "type": "string",
            "examples": [
              "ses_x9k2m"
            ]
          }
        }
      ],
      "post": {
        "tags": [
          "sessions"
        ],
        "operationId": "postMessage",
        "summary": "Send a message into a session",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostMessageRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Message stored and broadcast",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostMessageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sessions/{id}/events": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Session id",
          "schema": {
            "type": "string",
            "examples": [
              "ses_x9k2m"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "sessions"
        ],
        "operationId": "sessionEvents",
        "summary": "Server-Sent Events stream for a session",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "description": "Each event is `data: <json>`. Types: `message` ({type, message}), `status` ({type, status}), `ping` every 20 s.",
        "responses": {
          "200": {
            "description": "Event stream",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "data: {\"type\":\"status\",\"status\":\"connected\"}\n\n"
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/operators": {
      "get": {
        "tags": [
          "scheduling"
        ],
        "operationId": "listOperators",
        "summary": "List human operators",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Operator"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/operators/status": {
      "patch": {
        "tags": [
          "scheduling"
        ],
        "operationId": "setOperatorStatus",
        "summary": "Set an operator online/offline",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "operator_id",
                  "is_online"
                ],
                "properties": {
                  "operator_id": {
                    "type": "string"
                  },
                  "is_online": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Operator"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/schedule": {
      "get": {
        "tags": [
          "scheduling"
        ],
        "operationId": "getSchedule",
        "summary": "Bookings, operators and availability",
        "security": [],
        "parameters": [
          {
            "name": "operator_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Schedule"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "scheduling"
        ],
        "operationId": "bookSession",
        "summary": "Book a session with an operator in advance",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Booked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduledSession"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/keys": {
      "get": {
        "tags": [
          "keys"
        ],
        "operationId": "listKeys",
        "summary": "List the signed-in user's API keys (hash never returned)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiKey"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "keys"
        ],
        "operationId": "createKey",
        "summary": "Create an API key (raw key returned once, prefix cwh_live_)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "default": "Default"
                  },
                  "agentId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedApiKey"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/keys/{keyId}": {
      "parameters": [
        {
          "name": "keyId",
          "in": "path",
          "required": true,
          "description": "Key id",
          "schema": {
            "type": "string",
            "examples": [
              "key_0123456789abcdef"
            ]
          }
        }
      ],
      "delete": {
        "tags": [
          "keys"
        ],
        "operationId": "revokeKey",
        "summary": "Revoke an API key",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "keyId": {
                      "type": "string"
                    },
                    "revoked": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/billing/usage": {
      "get": {
        "tags": [
          "billing"
        ],
        "operationId": "getUsage",
        "summary": "Invoices plus all-time and 30-day totals",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/billing/meter": {
      "post": {
        "tags": [
          "billing"
        ],
        "operationId": "recordMeterEvent",
        "summary": "Record a billing event for a session",
        "security": [
          {
            "bearerApiKey": []
          },
          {
            "sessionCookie": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId",
                  "eventType"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string"
                  },
                  "eventType": {
                    "type": "string",
                    "enum": [
                      "session_start",
                      "minute_tick",
                      "session_end"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "eventType": {
                      "type": "string"
                    },
                    "minutesElapsed": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/billing/invoices/{invoiceId}": {
      "parameters": [
        {
          "name": "invoiceId",
          "in": "path",
          "required": true,
          "description": "Invoice id",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "billing"
        ],
        "operationId": "getInvoice",
        "summary": "Invoice with its billing events",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BillingEvent"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/billing/invoices/{invoiceId}/charge": {
      "parameters": [
        {
          "name": "invoiceId",
          "in": "path",
          "required": true,
          "description": "Invoice id",
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "tags": [
          "billing"
        ],
        "operationId": "chargeInvoice",
        "summary": "Charge an invoice to the signed-in user's saved card (Stripe)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    },
                    "charge": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/stripe/config": {
      "get": {
        "tags": [
          "checkout"
        ],
        "operationId": "stripeConfig",
        "summary": "Whether payments are configured (publishable key, mode)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configured": {
                      "type": "boolean"
                    },
                    "mode": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "publishableKey": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "webhookSigning": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/stripe/products": {
      "get": {
        "tags": [
          "checkout"
        ],
        "operationId": "listProducts",
        "summary": "Active Stripe products with their default price",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "configured": {
                      "type": "boolean"
                    },
                    "products": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "images": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "priceId": {
                            "type": "string"
                          },
                          "amount": {
                            "type": "integer"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "recurring": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "interval": {
                                "type": "string"
                              },
                              "intervalCount": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Stripe unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/stripe/create-checkout-session": {
      "post": {
        "tags": [
          "checkout"
        ],
        "operationId": "createCheckoutSession",
        "summary": "Create a Stripe Checkout session (single price or cart)",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "priceId": {
                    "type": "string"
                  },
                  "quantity": {
                    "type": "integer",
                    "default": 1
                  },
                  "lineItems": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "priceId",
                        "quantity"
                      ],
                      "properties": {
                        "priceId": {
                          "type": "string"
                        },
                        "quantity": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "sessionId": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/stripe/session/{sessionId}": {
      "parameters": [
        {
          "name": "sessionId",
          "in": "path",
          "required": true,
          "description": "Stripe Checkout session id (cs_…)",
          "schema": {
            "type": "string",
            "examples": [
              "cs_test_123"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "checkout"
        ],
        "operationId": "getCheckoutSession",
        "summary": "Verify a Checkout session after redirect",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "session": {
                      "type": "object",
                      "properties": {
                        "customerName": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "amountTotal": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "currency": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "paymentStatus": {
                          "type": "string"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "mode": {
                          "type": "string"
                        },
                        "lineItems": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "quantity": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "amount": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/stripe/webhook": {
      "post": {
        "tags": [
          "checkout"
        ],
        "operationId": "stripeWebhook",
        "summary": "Stripe webhook receiver (verifies stripe-signature)",
        "security": [],
        "parameters": [
          {
            "name": "stripe-signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Stripe Event"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "boolean"
                    },
                    "type": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          },
          "503": {
            "description": "STRIPE_WEBHOOK_SECRET not set",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/{path}": {
      "parameters": [
        {
          "name": "path",
          "in": "path",
          "required": true,
          "description": "better-auth endpoint (wildcard, may contain slashes): get-session, sign-in/email, sign-up/email, sign-out",
          "schema": {
            "type": "string",
            "examples": [
              "get-session"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "auth"
        ],
        "operationId": "authGet",
        "summary": "better-auth GET handler (e.g. get-session)",
        "security": [],
        "responses": {
          "200": {
            "description": "better-auth response"
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "tags": [
          "auth"
        ],
        "operationId": "authPost",
        "summary": "better-auth POST handler (sign-in, sign-up, sign-out)",
        "security": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "better-auth response; sets session cookie"
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/sales-chat": {
      "get": {
        "tags": [
          "sales"
        ],
        "operationId": "salesChatConfig",
        "summary": "Sales chat mode (llm | scripted), lead fields, handoff contact and limits",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesChatConfig"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "sales"
        ],
        "operationId": "salesChat",
        "summary": "Send one message to the AI sales assistant (lead qualification + human handoff)",
        "security": [],
        "description": "Public; no API key. Omit `conversation_id` to start (201), then pass the returned id on every turn (200). The assistant answers only from published pricing/docs and collects name, company, email, use_case, volume and timeline; you may also send known fields directly in `lead`. Every lead and transcript is stored for sales follow-up. Without a model key (or on model error / daily cap) a scripted lead-capture flow replies (`mode: \"scripted\"`). Send `Accept: text/event-stream` or `\"stream\": true` for SSE: events `meta` {conversation_id, mode}, `delta` {text}, `reset` {} (discard partial text after a model error), `done` (the same object as the JSON response). Rate limit: 30 requests / 10 min per IP (headers RateLimit-Limit, RateLimit-Remaining, Retry-After); 40 messages per conversation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesChatRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Assistant reply (existing conversation). With Accept: text/event-stream the body is an SSE stream instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesChatResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "201": {
            "description": "Assistant reply (new conversation created)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesChatResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "message longer than 2000 characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (per IP) or conversation message limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/leads": {
      "post": {
        "tags": [
          "sales"
        ],
        "operationId": "createLead",
        "summary": "Submit a sales lead directly (for agents and forms)",
        "security": [],
        "description": "Public; no API key. Requires a valid `email` and `name` or `company`. Stored with source `leads_api`; continue the conversation with POST /api/sales-chat using the returned conversation_id if you like. Rate limit: 10 requests / 10 min per IP.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lead stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/admin/leads/{leadId}": {
      "parameters": [
        {
          "name": "leadId",
          "in": "path",
          "required": true,
          "description": "Lead / conversation id",
          "schema": {
            "type": "string",
            "examples": [
              "lead_3f9c0d1e2a4b5c6d7e8f9a0b"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "sales"
        ],
        "operationId": "adminGetLead",
        "summary": "Full lead + transcript (admins only; linked from lead alert emails)",
        "security": [
          {
            "sessionCookie": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "leadId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "role": {
                            "type": "string",
                            "enum": [
                              "user",
                              "assistant"
                            ]
                          },
                          "content": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in / missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Not an admin",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "system"
        ],
        "operationId": "health",
        "summary": "Liveness probe",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "const": "ok"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Unavailable"
          }
        }
      }
    },
    "/api/status": {
      "get": {
        "tags": [
          "system"
        ],
        "operationId": "status",
        "summary": "Service health checks (API, Database, Authentication, Chat Sessions, Webhook Handler)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "cwh_live_…",
        "description": "API key from POST /api/keys (shown once). Checked by sha256 hash against active keys."
      },
      "sessionCookie": {
        "type": "apiKey",
        "in": "cookie",
        "name": "better-auth.session_token",
        "description": "Browser session from /api/auth (better-auth)."
      }
    },
    "responses": {
      "Error": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "LeadFields": {
        "type": "object",
        "description": "Lead details stated by the prospect (all optional strings).",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "company": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "use_case": {
            "type": "string",
            "maxLength": 2000,
            "description": "What their agents would hand off to humans"
          },
          "volume": {
            "type": "string",
            "maxLength": 200,
            "description": "Expected sessions or minutes per month"
          },
          "timeline": {
            "type": "string",
            "maxLength": 200
          }
        }
      },
      "SalesPlan": {
        "type": "string",
        "enum": [
          "enterprise",
          "priority",
          "standard",
          "general"
        ],
        "description": "Plan the prospect asked about; general = site-wide launcher."
      },
      "Handoff": {
        "type": "object",
        "required": [
          "name",
          "phone",
          "display",
          "methods"
        ],
        "description": "Human handoff contact.",
        "properties": {
          "name": {
            "type": "string",
            "examples": [
              "Chris Mai"
            ]
          },
          "phone": {
            "type": "string",
            "examples": [
              "+14153755872"
            ]
          },
          "display": {
            "type": "string",
            "examples": [
              "415-375-5872"
            ]
          },
          "methods": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "text",
                "call"
              ]
            }
          },
          "sms": {
            "type": "string"
          },
          "tel": {
            "type": "string"
          }
        }
      },
      "SalesChatRequest": {
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "conversation_id": {
            "type": "string",
            "description": "From a previous response; omit to start a conversation",
            "examples": [
              "lead_3f9c0d1e2a4b5c6d7e8f9a0b"
            ]
          },
          "plan": {
            "$ref": "#/components/schemas/SalesPlan"
          },
          "lead": {
            "$ref": "#/components/schemas/LeadFields"
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Same as Accept: text/event-stream"
          },
          "source": {
            "type": "string",
            "enum": [
              "widget",
              "api"
            ],
            "default": "api"
          },
          "website": {
            "type": "string",
            "maxLength": 0,
            "description": "Honeypot — must be empty or omitted"
          }
        }
      },
      "SalesChatResponse": {
        "type": "object",
        "required": [
          "conversation_id",
          "mode",
          "reply",
          "lead",
          "missing",
          "lead_complete",
          "status",
          "handoff_offered",
          "handoff"
        ],
        "properties": {
          "conversation_id": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "llm",
              "scripted"
            ]
          },
          "reply": {
            "type": "string"
          },
          "lead": {
            "$ref": "#/components/schemas/LeadFields"
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "company",
                "email",
                "use_case",
                "volume",
                "timeline"
              ]
            }
          },
          "lead_complete": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "qualified",
              "handoff_requested"
            ]
          },
          "handoff_offered": {
            "type": "boolean"
          },
          "handoff": {
            "$ref": "#/components/schemas/Handoff"
          },
          "fallback_reason": {
            "type": "string",
            "enum": [
              "llm_error",
              "llm_daily_cap"
            ],
            "description": "Present when a configured model was not used for this turn"
          }
        }
      },
      "SalesChatConfig": {
        "type": "object",
        "required": [
          "mode",
          "fields",
          "plans",
          "handoff",
          "limits"
        ],
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "llm",
              "scripted"
            ]
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalesPlan"
            }
          },
          "handoff": {
            "$ref": "#/components/schemas/Handoff"
          },
          "limits": {
            "type": "object",
            "properties": {
              "requests_per_10_min": {
                "type": "integer"
              },
              "max_message_chars": {
                "type": "integer"
              },
              "max_turns": {
                "type": "integer"
              }
            }
          }
        }
      },
      "LeadRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/LeadFields"
          },
          {
            "type": "object",
            "required": [
              "email"
            ],
            "properties": {
              "plan": {
                "$ref": "#/components/schemas/SalesPlan"
              },
              "notes": {
                "type": "string",
                "maxLength": 2000
              },
              "website": {
                "type": "string",
                "maxLength": 0,
                "description": "Honeypot — must be empty or omitted"
              }
            }
          }
        ],
        "examples": [
          {
            "name": "Alice Chen",
            "company": "Example Corp",
            "email": "alice@example.com",
            "use_case": "Escalate compliance questions from our support agent",
            "volume": "20,000 minutes/month",
            "timeline": "Q1",
            "plan": "enterprise"
          }
        ]
      },
      "LeadResponse": {
        "type": "object",
        "required": [
          "lead_id",
          "conversation_id",
          "status",
          "plan",
          "lead",
          "missing",
          "handoff"
        ],
        "properties": {
          "lead_id": {
            "type": "string"
          },
          "conversation_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "qualified"
            ]
          },
          "plan": {
            "$ref": "#/components/schemas/SalesPlan"
          },
          "lead": {
            "$ref": "#/components/schemas/LeadFields"
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "next": {
            "type": "string"
          },
          "handoff": {
            "$ref": "#/components/schemas/Handoff"
          }
        }
      },
      "SessionStatus": {
        "type": "string",
        "enum": [
          "queued",
          "connected",
          "closed"
        ]
      },
      "Tier": {
        "type": "string",
        "enum": [
          "standard",
          "priority"
        ],
        "description": "standard = $10/min (1000 cents); priority = $25/min (2500 cents)."
      },
      "CreateSessionRequest": {
        "type": "object",
        "required": [
          "agent_id"
        ],
        "properties": {
          "agent_id": {
            "type": "string",
            "description": "Your registered agent identifier.",
            "examples": [
              "agent_abc123"
            ]
          },
          "context": {
            "type": "string",
            "description": "Plain-text summary of the issue for the human expert.",
            "examples": [
              "User is asking about a refund for order #8821"
            ]
          },
          "tier": {
            "type": "string",
            "enum": [
              "standard",
              "priority"
            ],
            "default": "standard",
            "description": "Pricing tier: standard = $10/min (1000 cents), priority = $25/min (2500 cents) with guaranteed fast human response. Takes precedence over `priority`."
          },
          "priority": {
            "description": "Legacy alias: \"high\" or true selects the priority tier; \"normal\" or false selects standard.",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "normal",
                  "high"
                ]
              },
              {
                "type": "boolean"
              }
            ],
            "default": "normal"
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "Stored with the session. Webhook delivery is planned, not live — use GET /api/sessions/{id}/events."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Echoed back in the response."
          }
        }
      },
      "CreateSessionResponse": {
        "type": "object",
        "required": [
          "session_id",
          "status",
          "eta_seconds",
          "billing_started",
          "tier",
          "rate_cents_per_minute"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "examples": [
              "ses_x9k2m"
            ]
          },
          "status": {
            "type": "string",
            "const": "queued"
          },
          "eta_seconds": {
            "type": "integer",
            "examples": [
              12
            ]
          },
          "billing_started": {
            "type": "boolean",
            "const": false
          },
          "tier": {
            "$ref": "#/components/schemas/Tier"
          },
          "rate_cents_per_minute": {
            "type": "integer",
            "enum": [
              1000,
              2500
            ]
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ChatSession": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "sessionId": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/SessionStatus"
          },
          "priority": {
            "type": "string",
            "enum": [
              "normal",
              "high"
            ],
            "description": "Stored tier: normal = standard, high = priority."
          },
          "context": {
            "type": [
              "string",
              "null"
            ]
          },
          "webhookUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "operatorId": {
            "type": [
              "string",
              "null"
            ]
          },
          "billingStartedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "closedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ChatMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "sessionId": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "agent",
              "human",
              "system"
            ]
          },
          "content": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UpdateSessionRequest": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/SessionStatus"
          },
          "operator_id": {
            "type": "string"
          }
        }
      },
      "PostMessageRequest": {
        "type": "object",
        "required": [
          "content"
        ],
        "properties": {
          "content": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "agent",
              "human",
              "system"
            ],
            "default": "human"
          }
        }
      },
      "PostMessageResponse": {
        "type": "object",
        "properties": {
          "message_id": {
            "type": "string",
            "examples": [
              "msg_7"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SessionHistoryPage": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "sessionId": {
                  "type": "string"
                },
                "agentId": {
                  "type": "string"
                },
                "operatorId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "status": {
                  "$ref": "#/components/schemas/SessionStatus"
                },
                "priority": {
                  "type": "string"
                },
                "tier": {
                  "$ref": "#/components/schemas/Tier"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "billingStartedAt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "closedAt": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "durationMinutes": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "invoice": {
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "invoiceId": {
                          "type": "string"
                        },
                        "totalMinutes": {
                          "type": "integer"
                        },
                        "totalCents": {
                          "type": "integer"
                        },
                        "status": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          }
        }
      },
      "Operator": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "operatorId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "isOnline": {
            "type": "boolean"
          },
          "lastSeenAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          }
        }
      },
      "ScheduledSession": {
        "type": "object",
        "properties": {
          "bookingId": {
            "type": "string"
          },
          "operatorId": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "scheduledAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationMinutes": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "cancelled",
              "completed"
            ]
          },
          "context": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "BookingRequest": {
        "type": "object",
        "required": [
          "operator_id",
          "agent_id",
          "scheduled_at"
        ],
        "properties": {
          "operator_id": {
            "type": "string"
          },
          "agent_id": {
            "type": "string"
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_minutes": {
            "type": "integer",
            "examples": [
              15,
              30,
              60
            ]
          },
          "context": {
            "type": "string"
          }
        }
      },
      "Schedule": {
        "type": "object",
        "properties": {
          "sessions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduledSession"
            }
          },
          "operators": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Operator"
            }
          },
          "availabilityWindows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "operatorId": {
                  "type": "string"
                },
                "dayOfWeek": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 6
                },
                "startTime": {
                  "type": "string"
                },
                "endTime": {
                  "type": "string"
                }
              }
            }
          },
          "availabilityBlocks": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "operatorId": {
                  "type": "string"
                },
                "startsAt": {
                  "type": "string"
                },
                "endsAt": {
                  "type": "string"
                },
                "reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "keyId": {
            "type": "string"
          },
          "keyPrefix": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "agentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "isActive": {
            "type": "boolean"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          }
        }
      },
      "CreatedApiKey": {
        "type": "object",
        "properties": {
          "keyId": {
            "type": "string"
          },
          "keyPrefix": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "rawKey": {
            "type": "string",
            "description": "cwh_live_… — shown once",
            "examples": [
              "cwh_live_…"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "invoiceId": {
            "type": "string"
          },
          "sessionId": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "operatorId": {
            "type": [
              "string",
              "null"
            ]
          },
          "totalMinutes": {
            "type": "integer"
          },
          "ratePerMinute": {
            "type": "string",
            "description": "Dollars per minute for the session tier",
            "examples": [
              "10.0000",
              "25.0000"
            ]
          },
          "subtotalCents": {
            "type": "integer"
          },
          "platformFeeCents": {
            "type": "integer",
            "description": "Always 0 (no platform fee)",
            "examples": [
              0
            ]
          },
          "totalCents": {
            "type": "integer"
          },
          "currency": {
            "type": "string",
            "examples": [
              "usd"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "paid",
              "void"
            ]
          },
          "paidAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string"
          }
        }
      },
      "BillingEvent": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "agentId": {
            "type": "string"
          },
          "eventType": {
            "type": "string",
            "enum": [
              "session_start",
              "minute_tick",
              "session_end"
            ]
          },
          "minutesElapsed": {
            "type": "integer"
          },
          "ratePerMinute": {
            "type": "string"
          },
          "amountCents": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string"
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "invoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "totals": {
            "type": "object",
            "properties": {
              "totalSessions": {
                "type": "integer"
              },
              "totalMinutes": {
                "type": "integer"
              },
              "totalCents": {
                "type": "integer"
              }
            }
          },
          "last30Days": {
            "type": "object",
            "properties": {
              "sessions": {
                "type": "integer"
              },
              "minutes": {
                "type": "integer"
              },
              "revenueCents": {
                "type": "integer"
              }
            }
          }
        }
      },
      "StatusResponse": {
        "type": "object",
        "properties": {
          "overall": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "outage"
            ]
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "operational",
                    "degraded",
                    "outage"
                  ]
                },
                "latencyMs": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "checkedAt": {
                  "type": "string"
                },
                "detail": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}
