{
  "openapi": "3.1.0",
  "info": {
    "title": "BoltReply.io API",
    "version": "1.0.0",
    "description": "HTTP API for BoltReply.io, AI review-response software by GrowLocal. Use it to draft on-brand replies to Google, Yelp, TripAdvisor, Booking.com, Airbnb, Amazon, Facebook, App Store, and Google Play reviews. Authenticated `/api/v1` operations require a Supabase Bearer token from a BoltReply.io session. Public `/api/tools` operations are rate-limited and do not require auth. There is no public MCP server; call these HTTPS endpoints (or load this document for function calling). Docs: /docs/api",
    "contact": {
      "name": "GrowLocal / BoltReply.io",
      "email": "admin@boltreply.io",
      "url": "https://www.boltreply.io/developers"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.boltreply.io/terms-of-service"
    }
  },
  "servers": [
    {
      "url": "https://www.boltreply.io",
      "description": "Production (www.boltreply.io)"
    },
    {
      "url": "https://boltreply.io",
      "description": "Apex domain (canonicalizes to www)"
    }
  ],
  "tags": [
    {
      "name": "Discovery",
      "description": "Machine-readable entry points for agents"
    },
    {
      "name": "Public tools",
      "description": "Unauthenticated, rate-limited generators for demos and lead capture"
    },
    {
      "name": "AI replies",
      "description": "Authenticated review-reply generation used by the Chrome extension"
    },
    {
      "name": "Account",
      "description": "Current user, answering mode, and business profile"
    },
    {
      "name": "Prompts",
      "description": "Pro Mode custom prompts keyed by review rating"
    },
    {
      "name": "Jobs",
      "description": "History of completed AI generation jobs"
    },
    {
      "name": "Billing",
      "description": "Stripe checkout and customer portal"
    },
    {
      "name": "Contact",
      "description": "Human support inbox for GrowLocal / BoltReply.io"
    }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiJson",
        "summary": "Download the OpenAPI 3.1 specification (JSON)",
        "description": "Returns this specification. Use it to populate LLM function-calling tools. CORS is open. Prefer this URL over guessing endpoints.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/openapi.yaml": {
      "get": {
        "operationId": "getOpenApiYaml",
        "summary": "Download the OpenAPI 3.1 specification (YAML)",
        "description": "Same contract as getOpenApiJson, serialized as YAML for Swagger/OpenAPI UIs.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI document",
            "content": {
              "application/yaml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api": {
      "get": {
        "operationId": "getApiIndex",
        "summary": "API discovery document",
        "description": "Small JSON index pointing agents at OpenAPI, authentication docs, and the primary generate operation. Unknown /api paths return the ApiError schema instead of HTML.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Discovery payload",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "operationId": "getApiV1Index",
        "summary": "Authenticated API v1 index",
        "description": "Lists the v1 operations an agent should register as tools after the user signs in.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "v1 index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai/generate": {
      "post": {
        "operationId": "generateReviewReply",
        "summary": "Generate an on-brand review reply",
        "description": "Primary BoltReply.io function. Drafts a review response from review_text using Simple Mode (saved business profile) or Pro Mode (custom prompt for the rating band). Deducts one credit. Requires a Bearer token. Do not call this to write reviews as a customer; it replies as the business.",
        "tags": [
          "AI replies"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Customer review to answer",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateReplyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated reply and credit balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateReplyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai/generate-prompt": {
      "post": {
        "operationId": "generateCustomPrompt",
        "summary": "Generate a Pro Mode system prompt",
        "description": "Creates a rating-band system prompt from the saved business profile. Requires a profile first. Use when the user wants Pro Mode prompts rather than a one-off reply.",
        "tags": [
          "AI replies"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Rating band to target",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GeneratePromptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prompt text",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeneratePromptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai/improve-prompt": {
      "post": {
        "operationId": "improveCustomPrompt",
        "summary": "Rewrite a Pro Mode prompt",
        "description": "Improves an existing custom prompt for bad, neutral, or positive reviews. Does not publish a customer-facing reply.",
        "tags": [
          "AI replies"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Prompt text to improve",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImprovePromptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Improved prompt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImproveTextResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai/improve-field": {
      "post": {
        "operationId": "improveBusinessProfileField",
        "summary": "Rewrite a business-profile field",
        "description": "Improves a named onboarding field (products, brand voice, CTAs) so Simple Mode replies stay on-brand.",
        "tags": [
          "AI replies"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Field name and current text",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImproveFieldRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Improved field text",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImproveTextResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "operationId": "getCurrentUser",
        "summary": "Get the signed-in BoltReply.io user",
        "description": "Returns profile, credits, answering mode, and subscription fields for the Bearer token.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updateCurrentUser",
        "summary": "Update the signed-in user",
        "description": "Patch name, company, phone, or answering_mode_selected (`simple` | `pro`).",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Fields to update",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me/answering-mode": {
      "get": {
        "operationId": "getAnsweringMode",
        "summary": "Get Simple vs Pro answering mode",
        "description": "Lightweight endpoint used by the Chrome extension on every review page.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current mode",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnsweringModeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me/business-profile": {
      "get": {
        "operationId": "getBusinessProfile",
        "summary": "Get the saved business profile",
        "description": "Simple Mode reads this profile (name, categories, tone, CTAs, brand voice).",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile or null if onboarding is incomplete",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessProfileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "upsertBusinessProfile",
        "summary": "Create or replace the business profile",
        "description": "Required fields: business_name, business_main_category, main_products_services, country, state_province.",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Business profile used for Simple Mode replies",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessProfileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessProfileResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me/prompts": {
      "get": {
        "operationId": "listPrompts",
        "summary": "List Pro Mode prompts",
        "description": "Returns custom prompts for the user, newest first.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Prompt list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPrompt",
        "summary": "Create a Pro Mode prompt",
        "description": "Stores prompt content plus a rating (0–5) used to pick the prompt for a review.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Prompt to store",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PromptWriteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created prompt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me/prompts/{id}": {
      "get": {
        "operationId": "getPrompt",
        "summary": "Get one Pro Mode prompt",
        "description": "Fetch a single prompt by id. 404 if it is missing or belongs to another user.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Prompt UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Prompt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "updatePrompt",
        "summary": "Update a Pro Mode prompt",
        "description": "Replace content and/or rating for an existing prompt.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Prompt UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Updated prompt fields",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PromptWriteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated prompt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deletePrompt",
        "summary": "Delete a Pro Mode prompt",
        "description": "Permanently deletes the prompt. Subsequent Pro Mode generations need another prompt in that rating band.",
        "tags": [
          "Prompts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Prompt UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs": {
      "get": {
        "operationId": "listJobs",
        "summary": "List completed AI jobs",
        "description": "Paginated history of generateReviewReply runs for the signed-in user.",
        "tags": [
          "Jobs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Page size (max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of rows to skip",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "job_type",
            "in": "query",
            "description": "Optional job type filter, e.g. ai_generation",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "summary": "Get one AI job",
        "description": "Returns payload and result for a completed job owned by the current user.",
        "tags": [
          "Jobs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Job UUID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/tools/ai-review-answer-generator": {
      "post": {
        "operationId": "generatePublicReviewReply",
        "summary": "Free public review-reply generator",
        "description": "Unauthenticated demo used by /tools/ai-review-answer-generator. Limited to 15 requests per IP per week. For production volume, use generateReviewReply with a BoltReply.io account. Do not send secrets here.",
        "tags": [
          "Public tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "description": "Review to answer without a saved profile",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicReplyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated reply and remaining quota",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicReplyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Weekly IP quota exhausted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/tools/prompt-generator": {
      "post": {
        "operationId": "generatePublicPrompt",
        "summary": "Free public Pro Mode prompt generator",
        "description": "Builds sample system prompts from a short business brief. Rate-limited (5/IP/week). Authenticated equivalent: generateCustomPrompt.",
        "tags": [
          "Public tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "description": "Business brief",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicPromptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated prompts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Weekly IP quota exhausted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/tools/capture-email": {
      "post": {
        "operationId": "captureToolEmail",
        "summary": "Store an email from a free tool",
        "description": "Lead capture after a public tool run. Requires a valid email and tool_name. Not a mailing-list API for third parties.",
        "tags": [
          "Public tools"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "description": "Email plus tool identifier",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaptureEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "operationId": "submitContactForm",
        "summary": "Email GrowLocal / BoltReply.io support",
        "description": "Sends a message to admin@boltreply.io. Rate-limited to one POST per IP per minute. Use this when the user needs a human, not a generated review reply.",
        "tags": [
          "Contact"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "description": "Contact form fields",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "429": {
            "description": "Too many messages from this IP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "searchDocs",
        "summary": "Search BoltReply.io documentation",
        "description": "Full-text search over /docs (Fumadocs). Query string is required by the search client.",
        "tags": [
          "Discovery"
        ],
        "security": [],
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Search string",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search hits",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/stripe/prices": {
      "get": {
        "operationId": "listStripePrices",
        "summary": "List current BoltReply.io plan prices",
        "description": "Live Stripe unit amounts for Starter, Enthusiast, and Pro. Prefer this over cached marketing copy when quoting price.",
        "tags": [
          "Billing"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Price map keyed by Stripe price id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/stripe/create-checkout-session": {
      "post": {
        "operationId": "createCheckoutSession",
        "summary": "Create a Stripe Checkout session",
        "description": "Starts paid-plan checkout for the signed-in user. Requires a valid priceId from listStripePrices. Do not invent price IDs.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Plan to subscribe",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckoutRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/stripe/customer-portal": {
      "post": {
        "operationId": "createCustomerPortalSession",
        "summary": "Open the Stripe billing portal",
        "description": "Returns a portal URL so the user can update payment method or cancel. Requires an existing Stripe customer.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Portal URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/webhook": {
      "post": {
        "operationId": "receiveStripeWebhook",
        "summary": "Stripe webhook receiver",
        "description": "Internal Stripe event handler. Agents must not call this. Requires stripe-signature. Documented so function-calling models do not invent a fake webhook URL.",
        "tags": [
          "Billing"
        ],
        "security": [],
        "parameters": [
          {
            "name": "stripe-signature",
            "in": "header",
            "required": true,
            "description": "Stripe signature of the raw POST body",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Raw Stripe event JSON",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "405": {
            "description": "HTTP method not allowed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supabase access token from a BoltReply.io login (Authorization: Bearer <token>). The Chrome extension obtains this after the user signs in. There is no public API key."
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "required": [
          "success",
          "error",
          "code",
          "hint",
          "docs_url"
        ],
        "additionalProperties": true,
        "description": "Structured error. `error` stays a string for the Chrome extension; `code` and `hint` are for agents.",
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Always false on errors"
          },
          "error": {
            "type": "string",
            "description": "Human-readable message"
          },
          "code": {
            "type": "string",
            "description": "Stable machine code",
            "enum": [
              "UNAUTHORIZED",
              "USER_NOT_FOUND",
              "VALIDATION_ERROR",
              "NOT_FOUND",
              "METHOD_NOT_ALLOWED",
              "PAYMENT_REQUIRED",
              "RATE_LIMITED",
              "CONFLICT",
              "CONFIGURATION_ERROR",
              "INTERNAL_ERROR",
              "WEBHOOK_INVALID"
            ]
          },
          "hint": {
            "type": "string",
            "description": "How to recover"
          },
          "docs_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ApiIndex": {
        "type": "object",
        "required": [
          "name",
          "openapi",
          "docs"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "authentication": {
            "type": "string",
            "format": "uri"
          },
          "when_to_use": {
            "type": "string"
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          }
        }
      },
      "GenerateReplyRequest": {
        "type": "object",
        "required": [
          "review_text"
        ],
        "properties": {
          "review_text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "review_rating": {
            "type": "number",
            "minimum": 1,
            "maximum": 5
          },
          "reviewer_name": {
            "type": "string",
            "maxLength": 200
          },
          "mode": {
            "type": "string",
            "enum": [
              "simple",
              "pro"
            ]
          },
          "custom_prompt": {
            "type": "string",
            "maxLength": 5000
          },
          "debug": {
            "type": "boolean"
          }
        }
      },
      "GenerateReplyResponse": {
        "type": "object",
        "required": [
          "success",
          "generated_response"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "generated_response": {
            "type": "string"
          },
          "confidence_score": {
            "type": "number"
          },
          "tokens_used": {
            "type": "number"
          },
          "prompt_tokens": {
            "type": "number"
          },
          "completion_tokens": {
            "type": "number"
          },
          "processing_time_ms": {
            "type": "number"
          },
          "model_used": {
            "type": "string"
          },
          "credits_used": {
            "type": "number"
          },
          "credits_remaining": {
            "type": "number"
          }
        }
      },
      "GeneratePromptRequest": {
        "type": "object",
        "properties": {
          "rating": {
            "type": "number",
            "minimum": 1,
            "maximum": 5,
            "description": "1–2 bad, 3 neutral, 4–5 positive"
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 2
          }
        }
      },
      "GeneratePromptResponse": {
        "type": "object",
        "required": [
          "success",
          "content"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "content": {
            "type": "string"
          }
        }
      },
      "ImprovePromptRequest": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 3000
          },
          "prompt_type": {
            "type": "string",
            "enum": [
              "bad",
              "neutral",
              "positive"
            ]
          },
          "rating": {
            "type": "number",
            "minimum": 1,
            "maximum": 5
          }
        }
      },
      "ImproveFieldRequest": {
        "type": "object",
        "required": [
          "field_name",
          "text"
        ],
        "properties": {
          "field_name": {
            "type": "string",
            "minLength": 1
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          }
        }
      },
      "ImproveTextResponse": {
        "type": "object",
        "required": [
          "success",
          "improved_text"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "improved_text": {
            "type": "string"
          }
        }
      },
      "UpdateUserRequest": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string",
            "maxLength": 100
          },
          "last_name": {
            "type": "string",
            "maxLength": 100
          },
          "phone": {
            "type": "string",
            "maxLength": 30
          },
          "company": {
            "type": "string",
            "maxLength": 200
          },
          "position": {
            "type": "string",
            "maxLength": 100
          },
          "answering_mode_selected": {
            "type": "string",
            "enum": [
              "simple",
              "pro"
            ]
          }
        }
      },
      "UserResponse": {
        "type": "object",
        "required": [
          "success",
          "user"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "user": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "AnsweringModeResponse": {
        "type": "object",
        "required": [
          "success",
          "answering_mode"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "answering_mode": {
            "type": "string",
            "enum": [
              "simple",
              "pro"
            ]
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "BusinessProfileRequest": {
        "type": "object",
        "required": [
          "business_name",
          "business_main_category",
          "main_products_services",
          "country",
          "state_province"
        ],
        "properties": {
          "business_name": {
            "type": "string"
          },
          "business_main_category": {
            "type": "string"
          },
          "business_secondary_category": {
            "type": "string"
          },
          "business_tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "main_products_services": {
            "type": "string"
          },
          "brief_description": {
            "type": "string"
          },
          "business_address": {
            "type": "string"
          },
          "business_website": {
            "type": "string"
          },
          "contact_email": {
            "type": "string"
          },
          "contact_name": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "state_province": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "response_tone": {
            "type": "string"
          },
          "response_length": {
            "type": "string",
            "enum": [
              "Brief",
              "Standard",
              "Detailed",
              "Adaptive"
            ]
          },
          "greetings": {
            "type": "string"
          },
          "signatures": {
            "type": "string"
          },
          "positive_review_cta": {
            "type": "string"
          },
          "negative_review_escalation": {
            "type": "string"
          },
          "brand_voice_notes": {
            "type": "string"
          },
          "other_considerations": {
            "type": "string"
          }
        }
      },
      "BusinessProfileResponse": {
        "type": "object",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "business_profile": {
            "type": "object",
            "additionalProperties": true,
            "nullable": true
          }
        }
      },
      "PromptWriteRequest": {
        "type": "object",
        "required": [
          "content"
        ],
        "properties": {
          "content": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "rating": {
            "type": "number",
            "minimum": 0,
            "maximum": 5
          }
        }
      },
      "PromptResponse": {
        "type": "object",
        "required": [
          "success",
          "prompt"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "prompt": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "PromptListResponse": {
        "type": "object",
        "required": [
          "success",
          "prompts"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "prompts": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "JobListResponse": {
        "type": "object",
        "required": [
          "success",
          "jobs",
          "pagination"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "jobs": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "pagination": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "JobResponse": {
        "type": "object",
        "required": [
          "success",
          "job"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "job": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "PublicReplyRequest": {
        "type": "object",
        "required": [
          "review_text",
          "review_rating"
        ],
        "properties": {
          "review_text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "review_rating": {
            "type": "number",
            "minimum": 1,
            "maximum": 5
          },
          "business_type": {
            "type": "string"
          }
        }
      },
      "PublicReplyResponse": {
        "type": "object",
        "required": [
          "success",
          "generated_response"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "generated_response": {
            "type": "string"
          },
          "tokens_used": {
            "type": "number"
          },
          "rate_limit": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "PublicPromptRequest": {
        "type": "object",
        "required": [
          "business_name",
          "business_type",
          "main_products_services"
        ],
        "properties": {
          "business_name": {
            "type": "string"
          },
          "business_type": {
            "type": "string"
          },
          "main_products_services": {
            "type": "string",
            "maxLength": 1000
          },
          "response_tone": {
            "type": "string"
          },
          "brand_voice_notes": {
            "type": "string",
            "maxLength": 500
          },
          "language": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "cta_preference": {
            "type": "string",
            "enum": [
              "invite_back",
              "contact_support",
              "no_cta",
              "custom"
            ]
          },
          "personalization_level": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ]
          },
          "length_preference": {
            "type": "string",
            "enum": [
              "brief",
              "standard",
              "detailed"
            ]
          }
        }
      },
      "CaptureEmailRequest": {
        "type": "object",
        "required": [
          "email",
          "tool_name"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "tool_name": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "ContactRequest": {
        "type": "object",
        "required": [
          "name",
          "email",
          "subject",
          "message"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "subject": {
            "type": "string",
            "minLength": 3,
            "maxLength": 200
          },
          "message": {
            "type": "string",
            "minLength": 10,
            "maxLength": 5000
          },
          "honeypot": {
            "type": "string",
            "maxLength": 0,
            "description": "Leave empty; bots that fill it are discarded"
          }
        }
      },
      "PricesResponse": {
        "type": "object",
        "required": [
          "success",
          "prices"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "prices": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "CheckoutRequest": {
        "type": "object",
        "required": [
          "priceId"
        ],
        "properties": {
          "priceId": {
            "type": "string"
          },
          "successUrl": {
            "type": "string",
            "format": "uri"
          },
          "cancelUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CheckoutResponse": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "PortalResponse": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "WebhookAck": {
        "type": "object",
        "required": [
          "received"
        ],
        "properties": {
          "received": {
            "type": "boolean"
          }
        }
      }
    }
  }
}