{
  "openapi": "3.1.0",
  "info": {
    "title": "Feedbot API",
    "version": "1",
    "description": "REST API of Feedbot AI: conversations, stats, product issues, insight reports, leads and tickets. Available on Pro and Business. Docs: https://feedbotai.com/docs/api-mcp/",
    "contact": {
      "name": "Feedbot",
      "url": "https://feedbotai.com/docs/api-mcp/"
    }
  },
  "servers": [
    {
      "url": "https://api.feedbotai.com"
    }
  ],
  "externalDocs": {
    "url": "https://feedbotai.com/docs/api-mcp/"
  },
  "security": [
    {
      "bearer": []
    },
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Bots",
      "description": "Your bots (websites and chat links)."
    },
    {
      "name": "Conversations",
      "description": "Analysed conversations, transcripts and stats."
    },
    {
      "name": "Issues",
      "description": "Product issues reported by users, and the agent-ready report."
    },
    {
      "name": "Insights",
      "description": "Insight reports."
    },
    {
      "name": "Leads",
      "description": "Visitors with buying intent; marking a lead queues it for the CRM lead webhook."
    },
    {
      "name": "Tickets",
      "description": "Requests only the team can handle (refunds, cancellations, account changes)."
    },
    {
      "name": "Meta",
      "description": "This document."
    }
  ],
  "paths": {
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenAPI",
        "summary": "This OpenAPI document (no API key needed).",
        "tags": [
          "Meta"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/bots": {
      "get": {
        "operationId": "listBots",
        "summary": "List bots",
        "tags": [
          "Bots"
        ],
        "x-feedbot-scope": "read",
        "responses": {
          "200": {
            "description": "Bots (not paginated: nextCursor is always null).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Bot"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/v1/conversations": {
      "get": {
        "operationId": "listConversations",
        "summary": "Search conversations (newest activity first; spam is never returned)",
        "tags": [
          "Conversations"
        ],
        "x-feedbot-scope": "read",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Full-text search in messages and summaries."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "support",
                "sales",
                "payments",
                "complaint",
                "feedback",
                "bug",
                "partnership",
                "useless",
                "other"
              ]
            },
            "description": "Category."
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "One tag."
          },
          {
            "name": "minPriority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "description": "Minimum priority."
          },
          {
            "name": "humanNeeded",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Only conversations that need a person."
          },
          {
            "name": "leads",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Only conversations of leads."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last message at or after (default: 30 days ago). RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last message before (a YYYY-MM-DD includes the whole day). RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Deprecated: use cursor.",
            "deprecated": true
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 50; values above 200 are lowered to 200)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The nextCursor of the previous page (opaque)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of conversations.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Conversation"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    },
                    "nextBefore": {
                      "type": "string",
                      "deprecated": true,
                      "description": "Deprecated: use nextCursor."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/v1/conversations/{id}": {
      "get": {
        "operationId": "getConversation",
        "summary": "A conversation with its analysis and transcript",
        "tags": [
          "Conversations"
        ],
        "x-feedbot-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Conversation id."
          }
        ],
        "responses": {
          "200": {
            "description": "The conversation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ConversationDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/attachments/{id}": {
      "get": {
        "operationId": "getAttachment",
        "summary": "Download a file a visitor attached",
        "description": "Redirects (302) to a download link that works for 10 minutes. Answers 410 when the file was deleted after the plan's retention period.",
        "tags": [
          "Conversations"
        ],
        "x-feedbot-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Attachment id (messages[].attachments[].id)."
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to the file.",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "410": {
            "description": "The file was deleted after the retention period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/v1/stats": {
      "get": {
        "operationId": "getStats",
        "summary": "Counts for a period (spam excluded)",
        "tags": [
          "Conversations"
        ],
        "x-feedbot-scope": "read",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Default: 30 days ago. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          }
        ],
        "responses": {
          "200": {
            "description": "Stats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Stats"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/v1/issues": {
      "get": {
        "operationId": "listIssues",
        "summary": "Product issues, highest priority first, then most reported",
        "tags": [
          "Issues"
        ],
        "x-feedbot-scope": "issues:read (read or issues:write)",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "in_progress",
                "fixed",
                "wontfix",
                "all"
              ]
            },
            "description": "Default: open and in_progress."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "bug",
                "ux",
                "feature_request",
                "content_gap",
                "pricing"
              ]
            },
            "description": "Issue type."
          },
          {
            "name": "minPriority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "description": "Only issues with at least this priority."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last reported at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 50; values above 200 are lowered to 200)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The nextCursor of the previous page (opaque)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of issues.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Issue"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/v1/issues/{id}": {
      "get": {
        "operationId": "getIssue",
        "summary": "One issue with all evidence",
        "tags": [
          "Issues"
        ],
        "x-feedbot-scope": "issues:read (read or issues:write)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Issue id."
          }
        ],
        "responses": {
          "200": {
            "description": "The issue.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Issue"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "patch": {
        "operationId": "updateIssue",
        "summary": "Update an issue (e.g. mark it fixed)",
        "tags": [
          "Issues"
        ],
        "x-feedbot-scope": "issues:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Issue id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "in_progress",
                      "fixed",
                      "wontfix"
                    ]
                  },
                  "priority": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "description": "1-5, 5 = urgent. Once set here, the AI no longer raises it on new reports."
                  },
                  "fixedNote": {
                    "type": "string"
                  },
                  "externalRef": {
                    "type": "string"
                  },
                  "notifyReporters": {
                    "type": "boolean",
                    "description": "Email the users who reported the issue (once)."
                  }
                },
                "additionalProperties": false,
                "minProperties": 1,
                "required": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated issue.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Issue"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/reports/agent.md": {
      "get": {
        "operationId": "getAgentReport",
        "summary": "Agent-ready Markdown report of issues",
        "tags": [
          "Issues"
        ],
        "x-feedbot-scope": "issues:read (read or issues:write)",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "in_progress",
                "fixed",
                "wontfix",
                "all"
              ]
            },
            "description": "Default: open and in_progress."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "bug",
                "ux",
                "feature_request",
                "content_gap",
                "pricing"
              ]
            },
            "description": "Issue type."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last reported at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 50; values above 200 are lowered to 200)."
          }
        ],
        "responses": {
          "200": {
            "description": "Markdown.",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/insights": {
      "get": {
        "operationId": "listInsights",
        "summary": "Insight reports, newest first",
        "tags": [
          "Insights"
        ],
        "x-feedbot-scope": "insights:read (read or insights:write)",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 20, max 200)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The nextCursor of the previous page (opaque)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of reports.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/InsightReport"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      },
      "post": {
        "operationId": "createInsight",
        "summary": "Generate an insight report (Pro and Business)",
        "tags": [
          "Insights"
        ],
        "x-feedbot-scope": "insights:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "botId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "from": {
                    "type": "string",
                    "description": "Default: 30 days before to. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
                  },
                  "to": {
                    "type": "string",
                    "description": "Default: now. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "botId"
                ]
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued (or the same pending report, deduplicated).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/InsightJob"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        }
      }
    },
    "/v1/insights/{id}": {
      "get": {
        "operationId": "getInsight",
        "summary": "One insight report",
        "tags": [
          "Insights"
        ],
        "x-feedbot-scope": "insights:read (read or insights:write)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Report id."
          }
        ],
        "responses": {
          "200": {
            "description": "The report.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/InsightReport"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/leads": {
      "get": {
        "operationId": "listLeads",
        "summary": "Leads, most recently seen first",
        "tags": [
          "Leads"
        ],
        "x-feedbot-scope": "leads:read",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search name, email, phone or site user id."
          },
          {
            "name": "includeAnonymous",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Also visitors with buying intent but no contact details."
          },
          {
            "name": "marked",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true: only leads marked by the team; false: only leads found by the AI score."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last seen at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 50; values above 200 are lowered to 200)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The nextCursor of the previous page (opaque)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of leads.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Lead"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/v1/leads/export.csv": {
      "get": {
        "operationId": "exportLeads",
        "summary": "Leads as CSV (up to 10,000 rows)",
        "tags": [
          "Leads"
        ],
        "x-feedbot-scope": "leads:read",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Search name, email, phone or site user id."
          },
          {
            "name": "includeAnonymous",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Also visitors with buying intent but no contact details."
          },
          {
            "name": "marked",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "true: only leads marked by the team; false: only leads found by the AI score."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Last seen at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          }
        ],
        "responses": {
          "200": {
            "description": "CSV with a UTF-8 BOM.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      }
    },
    "/v1/leads/{id}": {
      "get": {
        "operationId": "getLead",
        "summary": "Any visitor of the workspace as a lead (see leadStatus)",
        "tags": [
          "Leads"
        ],
        "x-feedbot-scope": "leads:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Visitor id."
          }
        ],
        "responses": {
          "200": {
            "description": "The lead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Lead"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/leads/{id}/status": {
      "post": {
        "operationId": "setLeadStatus",
        "summary": "Mark a visitor as a lead or not a lead",
        "tags": [
          "Leads"
        ],
        "x-feedbot-scope": "leads:write",
        "description": "Idempotent. Marking as lead queues it for the CRM lead webhook and returns at once; the delivery runs in the background and failed deliveries are retried.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Visitor id."
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "lead",
                      "not_lead"
                    ]
                  }
                },
                "additionalProperties": false,
                "required": [
                  "status"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The lead and the export state.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadStatusResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        }
      }
    },
    "/v1/ticket-types": {
      "get": {
        "operationId": "listTicketTypes",
        "summary": "Enabled ticket types",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:read",
        "responses": {
          "200": {
            "description": "Ticket types (not paginated: nextCursor is always null).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TicketType"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          }
        }
      }
    },
    "/v1/tickets": {
      "get": {
        "operationId": "listTickets",
        "summary": "Tickets, newest first",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:read",
        "parameters": [
          {
            "name": "botId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only this bot."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "in_progress",
                "done",
                "all"
              ]
            },
            "description": "Default: open and in_progress."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A ticket type key (GET /v1/ticket-types)."
          },
          {
            "name": "minPriority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            },
            "description": "Only tickets with at least this priority."
          },
          {
            "name": "assignee",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A member's email, or none for unassigned tickets."
          },
          {
            "name": "conversationId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Only tickets of this conversation."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive search in title, description and resolution."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Created at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "updatedSince",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Changed (status, fields, comments) at or after. RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Page size (default 50; values above 200 are lowered to 200)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The nextCursor of the previous page (opaque)."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of tickets.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Ticket"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as cursor to get the next page; null on the last page."
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          }
        }
      },
      "post": {
        "operationId": "createTicket",
        "summary": "Create a ticket (source api)",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "type": {
                    "type": "string",
                    "description": "An enabled ticket type key."
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "priority": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "description": "1-5, 5 = urgent (default 3)."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "conversationId",
                  "type"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    },
                    "created": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "data",
                    "created"
                  ]
                }
              }
            }
          },
          "200": {
            "description": "An open ticket of this type already exists for the conversation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    },
                    "created": {
                      "type": "boolean",
                      "const": false
                    }
                  },
                  "required": [
                    "data",
                    "created"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        }
      }
    },
    "/v1/tickets/{id}": {
      "get": {
        "operationId": "getTicket",
        "summary": "One ticket with comments",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticket id."
          }
        ],
        "responses": {
          "200": {
            "description": "The ticket.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      },
      "patch": {
        "operationId": "updateTicket",
        "summary": "Update a ticket (does not message the customer)",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticket id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "open",
                      "in_progress",
                      "done"
                    ]
                  },
                  "type": {
                    "type": "string"
                  },
                  "priority": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "description": "1-5, 5 = urgent."
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "dueAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "RFC 3339 timestamp (any offset) or YYYY-MM-DD (a UTC day)."
                  },
                  "assigneeEmail": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A workspace member's email; null unassigns."
                  }
                },
                "additionalProperties": false,
                "minProperties": 1,
                "required": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated ticket.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ticket"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "409": {
            "description": "An open ticket of that type already exists for the conversation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "ticketId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "required": [
                    "error",
                    "ticketId"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          }
        }
      }
    },
    "/v1/tickets/{id}/comments": {
      "post": {
        "operationId": "commentTicket",
        "summary": "Add an internal team comment",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticket id."
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  }
                },
                "additionalProperties": false,
                "required": [
                  "body"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The comment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/TicketComment"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        }
      }
    },
    "/v1/tickets/{id}/resolve": {
      "post": {
        "operationId": "resolveTicket",
        "summary": "Close a ticket, optionally replying to the customer",
        "tags": [
          "Tickets"
        ],
        "x-feedbot-scope": "tickets:write",
        "description": "With reply, the text is sent to the customer's chat (signed with the API key's name).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Ticket id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "description": "Required: any unique string (e.g. a UUID). Retries with the same key never send the reply twice."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reply": {
                    "type": "string",
                    "maxLength": 4000
                  },
                  "sendEmail": {
                    "type": "boolean"
                  },
                  "closeConversation": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false,
                "required": []
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ResolveResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/E401"
          },
          "402": {
            "$ref": "#/components/responses/E402"
          },
          "403": {
            "$ref": "#/components/responses/E403"
          },
          "429": {
            "$ref": "#/components/responses/E429"
          },
          "400": {
            "$ref": "#/components/responses/E400"
          },
          "404": {
            "$ref": "#/components/responses/E404"
          },
          "409": {
            "$ref": "#/components/responses/E409"
          },
          "422": {
            "$ref": "#/components/responses/E422"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key (fb_live_…) from Settings → API & MCP."
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "description": "Replays the stored response of the same request within 24 hours."
      }
    },
    "responses": {
      "E400": {
        "description": "Invalid JSON, unknown fields, an empty PATCH or an invalid query parameter.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E401": {
        "description": "Missing or invalid API key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E402": {
        "description": "The plan does not include the API or this feature.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E403": {
        "description": "The API key lacks the needed scope.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E404": {
        "description": "Not found, or the object belongs to another workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E409": {
        "description": "Conflict (see the operation).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E422": {
        "description": "The Idempotency-Key was already used for a different request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "E429": {
        "description": "Rate limit exceeded; see Retry-After.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "Bot": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "siteUrl": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "installedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "siteUrl",
          "status",
          "archivedAt",
          "installedAt",
          "createdAt"
        ]
      },
      "VisitorRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "verified": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "verified"
        ]
      },
      "Analysis": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "intent": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "priority": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5
          },
          "sentiment": {
            "type": "number"
          },
          "leadScore": {
            "type": "integer"
          },
          "humanNeeded": {
            "type": "boolean"
          },
          "resolved": {
            "type": "boolean"
          },
          "productIssues": {
            "description": "Issues the analysis found in this conversation."
          }
        },
        "required": [
          "summary",
          "category",
          "tags",
          "priority",
          "sentiment",
          "leadScore",
          "humanNeeded",
          "resolved"
        ]
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ]
          },
          "messageCount": {
            "type": "integer"
          },
          "pageUrl": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastMessageAt": {
            "type": "string",
            "format": "date-time"
          },
          "visitor": {
            "$ref": "#/components/schemas/VisitorRef"
          },
          "analysis": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Analysis"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "botId",
          "status",
          "messageCount",
          "createdAt",
          "lastMessageAt",
          "visitor",
          "analysis"
        ]
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "assistant",
              "operator"
            ]
          },
          "author": {
            "type": "string",
            "description": "Team member name (operator replies)."
          },
          "content": {
            "type": "string"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Attachment"
            },
            "description": "Files the visitor sent with the message (omitted when none)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "role",
          "content",
          "createdAt"
        ]
      },
      "ConversationDetail": {
        "type": "object",
        "properties": {
          "conversation": {
            "$ref": "#/components/schemas/Conversation"
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "truncated": {
            "type": "boolean",
            "description": "true when older messages were left out (the last 1,000 are returned)."
          }
        },
        "required": [
          "conversation",
          "messages",
          "truncated"
        ]
      },
      "Stats": {
        "type": "object",
        "properties": {
          "conversations": {
            "type": "integer"
          },
          "messages": {
            "type": "integer"
          },
          "leads": {
            "type": "integer"
          },
          "humanNeeded": {
            "type": "integer"
          },
          "resolved": {
            "type": "integer"
          },
          "avgSentiment": {
            "type": "number"
          },
          "byCategory": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "topTags": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "openIssues": {
            "type": "integer"
          },
          "ctaClicks": {
            "type": "integer"
          }
        },
        "required": [
          "conversations",
          "messages",
          "leads",
          "humanNeeded",
          "resolved",
          "avgSentiment",
          "byCategory",
          "topTags",
          "openIssues",
          "ctaClicks"
        ]
      },
      "Evidence": {
        "type": "object",
        "properties": {
          "conversationId": {
            "type": "string",
            "format": "uuid"
          },
          "quote": {
            "type": "string"
          },
          "page": {
            "type": "string"
          }
        },
        "required": [
          "conversationId",
          "quote"
        ]
      },
      "Issue": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "bug",
              "ux",
              "feature_request",
              "content_gap",
              "pricing"
            ]
          },
          "description": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          },
          "occurrences": {
            "type": "integer"
          },
          "affectedPages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "in_progress",
              "fixed",
              "wontfix"
            ]
          },
          "priority": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "1-5, 5 = urgent. Set by the AI when created; a person can change it."
          },
          "fixedNote": {
            "type": "string"
          },
          "externalRef": {
            "type": "string"
          },
          "closedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When it was last marked fixed or wontfix; null while open."
          },
          "reportsSinceClosed": {
            "type": "integer",
            "description": "New reports while it is wontfix (from user messages written after closedAt)."
          },
          "regressedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When a new report reopened it after it was marked fixed (a possible regression)."
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "botId",
          "title",
          "type",
          "description",
          "evidence",
          "occurrences",
          "affectedPages",
          "status",
          "priority",
          "firstSeenAt",
          "lastSeenAt",
          "closedAt",
          "reportsSinceClosed",
          "regressedAt"
        ]
      },
      "InsightReport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "periodFrom": {
            "type": "string",
            "format": "date-time"
          },
          "periodTo": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "type": "string",
            "enum": [
              "scheduled",
              "on_demand"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "ready",
              "error"
            ]
          },
          "content": {
            "type": "string",
            "description": "Markdown."
          },
          "agentMarkdown": {
            "type": "string"
          },
          "data": {
            "description": "Structured report data."
          },
          "conversationCount": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "botId",
          "periodFrom",
          "periodTo",
          "kind",
          "status",
          "content",
          "agentMarkdown",
          "conversationCount",
          "createdAt"
        ]
      },
      "InsightJob": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "deduplicated": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "status",
          "deduplicated"
        ]
      },
      "Lead": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The visitor id."
          },
          "name": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "company": {
            "type": "string"
          },
          "leadScore": {
            "type": "integer"
          },
          "leadStatus": {
            "type": "string",
            "enum": [
              "lead",
              "none",
              "not_lead"
            ]
          },
          "summary": {
            "type": "string"
          },
          "bot": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name"
            ]
          },
          "userId": {
            "type": "string"
          },
          "verified": {
            "type": "boolean"
          },
          "conversationsCount": {
            "type": "integer"
          },
          "conversationId": {
            "type": "string"
          },
          "lastConversationId": {
            "type": "string"
          },
          "conversationUrl": {
            "type": "string"
          },
          "pageUrl": {
            "type": "string"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "exportedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the lead was delivered to the CRM lead webhook."
          }
        },
        "required": [
          "id",
          "name",
          "firstName",
          "lastName",
          "email",
          "phone",
          "country",
          "company",
          "leadScore",
          "leadStatus",
          "summary",
          "bot",
          "userId",
          "verified",
          "conversationsCount",
          "conversationId",
          "lastConversationId",
          "conversationUrl",
          "pageUrl",
          "firstSeenAt",
          "lastSeenAt",
          "exportedAt"
        ]
      },
      "LeadStatusResult": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Lead"
          },
          "export": {
            "type": "string",
            "enum": [
              "queued",
              "skipped",
              "not_configured"
            ],
            "description": "CRM lead webhook export: queued (sent in the background, retried on failure), skipped (not_lead, or already exported) or not_configured (no enabled lead webhook, or the plan lacks webhooks)."
          },
          "exported": {
            "type": "boolean",
            "deprecated": true,
            "description": "Deprecated: whether the lead had already been exported (see data.exportedAt)."
          }
        },
        "required": [
          "data",
          "export",
          "exported"
        ]
      },
      "TicketType": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "emoji": {
            "type": "string"
          }
        },
        "required": [
          "key",
          "name",
          "description",
          "emoji"
        ]
      },
      "TicketUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "email"
        ]
      },
      "TicketComment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "body": {
            "type": "string"
          },
          "author": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "user",
                  "api"
                ]
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string"
              }
            },
            "required": [
              "type",
              "name"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "body",
          "author",
          "createdAt"
        ]
      },
      "Ticket": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "botId": {
            "type": "string",
            "format": "uuid"
          },
          "botName": {
            "type": "string"
          },
          "conversationId": {
            "type": "string",
            "format": "uuid"
          },
          "conversationUrl": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "typeName": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "in_progress",
              "done"
            ]
          },
          "priority": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "1-5, 5 = urgent. Set by the AI when created; a person can change it."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "ai",
              "bot",
              "manual",
              "api"
            ]
          },
          "assignee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TicketUser"
              },
              {
                "type": "null"
              }
            ]
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "resolution": {
            "type": "string"
          },
          "visitor": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "phone": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name",
              "email",
              "phone",
              "country"
            ]
          },
          "canReply": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TicketComment"
            },
            "description": "Only on GET /v1/tickets/{id}."
          }
        },
        "required": [
          "id",
          "botId",
          "botName",
          "conversationId",
          "conversationUrl",
          "url",
          "type",
          "typeName",
          "status",
          "priority",
          "title",
          "description",
          "source",
          "assignee",
          "dueAt",
          "resolution",
          "visitor",
          "canReply",
          "createdAt",
          "updatedAt",
          "resolvedAt"
        ]
      },
      "ResolveResult": {
        "type": "object",
        "properties": {
          "ticket": {
            "$ref": "#/components/schemas/Ticket"
          },
          "replied": {
            "type": "boolean"
          },
          "emailQueued": {
            "type": "boolean"
          },
          "emailError": {
            "type": [
              "string",
              "null"
            ]
          },
          "conversationClosed": {
            "type": "boolean"
          }
        },
        "required": [
          "ticket",
          "replied",
          "emailQueued",
          "emailError",
          "conversationClosed"
        ]
      },
      "Attachment": {
        "type": "object",
        "description": "A file the visitor attached in the chat widget. Files are deleted after the plan's retention period (expiresAt).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "contentType": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "description": "Size in bytes."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the file is deleted (omitted = kept)."
          },
          "url": {
            "type": "string",
            "description": "GET /v1/attachments/{id}: redirects to a short-lived download link (send your API key)."
          }
        },
        "required": [
          "id",
          "name",
          "contentType",
          "size",
          "url"
        ]
      }
    }
  }
}
