{
  "openapi": "3.1.0",
  "info": {
    "title": "256M Watch Insurance Quote API",
    "version": "1.1.0",
    "description": "Returns indicative luxury watch insurance premium estimates. This is NOT a binding offer — estimates only. 256M is a Swiss-based mutual insurance protocol for luxury watches.",
    "contact": {
      "name": "256M",
      "email": "hello@256m.io",
      "url": "https://256m.io"
    }
  },
  "servers": [
    {
      "url": "https://vomuzjchszgcoxaomdfi.supabase.co/functions/v1",
      "description": "Production"
    }
  ],
  "paths": {
    "/quote": {
      "get": {
        "operationId": "getQuote",
        "summary": "Get an indicative insurance quote for a luxury watch",
        "description": "Pass all 13 required parameters to receive a premium estimate. Call with no parameters or ?schema to get the full parameter schema. Tips: brandTier can be inferred from watch brand, recognizability from model name. Use sensible defaults for fields the user hasn't specified.",
        "parameters": [
          {
            "name": "watchValue",
            "in": "query",
            "required": true,
            "description": "Watch value in USD",
            "schema": { "type": "integer", "minimum": 500, "maximum": 35000 }
          },
          {
            "name": "brandTier",
            "in": "query",
            "required": true,
            "description": "Ultra Luxury = Patek/AP/Vacheron, High Luxury = Rolex/Omega, Luxury = TAG/Breitling/IWC, Premium = Longines/Oris",
            "schema": { "type": "string", "enum": ["ultra_luxury", "high_luxury", "luxury", "premium"] }
          },
          {
            "name": "recognizability",
            "in": "query",
            "required": true,
            "description": "How recognisable the watch model is. Iconic = Nautilus/Daytona/Royal Oak",
            "schema": { "type": "string", "enum": ["iconic", "well_known", "moderate", "low"] }
          },
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["uk", "italy", "france", "belgium", "germany", "switzerland"] }
          },
          {
            "name": "urbanDensity",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["major_city", "city", "suburban", "rural"] }
          },
          {
            "name": "postcodeRisk",
            "in": "query",
            "required": true,
            "description": "Crime level in the policyholder's area",
            "schema": { "type": "string", "enum": ["very_high", "high", "moderate", "low", "very_low"] }
          },
          {
            "name": "ageGroup",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["18_25", "26_34", "35_49", "50_plus"] }
          },
          {
            "name": "wearFrequency",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["daily", "weekly", "rotation", "occasional"] }
          },
          {
            "name": "claimsHistory",
            "in": "query",
            "required": true,
            "description": "Prior insurance claims (multiple = 3+)",
            "schema": { "type": "string", "enum": ["none", "one", "two", "multiple"] }
          },
          {
            "name": "storageSecurity",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "enum": ["safe_and_alarm", "safe", "alarm", "standard", "none"] }
          },
          {
            "name": "gpsTracking",
            "in": "query",
            "required": true,
            "description": "GPS or AirTag tracking on the watch",
            "schema": { "type": "string", "enum": ["active", "none"] }
          },
          {
            "name": "purchaseRecency",
            "in": "query",
            "required": true,
            "description": "When the watch was purchased",
            "schema": { "type": "string", "enum": ["first_90", "91_180", "over_180"] }
          },
          {
            "name": "coverageType",
            "in": "query",
            "required": true,
            "description": "Theft Only (0% deductible) or Theft + Loss (20% loss deductible)",
            "schema": { "type": "string", "enum": ["theftOnly", "theftAndLoss"] }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful quote",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/QuoteResponse" },
                "example": {
                  "ok": true,
                  "quote": {
                    "monthlyPremium": "$28.46",
                    "annualPremium": "$341.52",
                    "annualRate": "2.28%",
                    "currency": "USD",
                    "deductible": "0%"
                  },
                  "profile": {
                    "watchValue": "$15,000",
                    "brandTier": "High Luxury",
                    "recognizability": "Well-Known",
                    "country": "United Kingdom",
                    "urbanDensity": "City",
                    "postcodeRisk": "Moderate",
                    "ageGroup": "26-34",
                    "wearFrequency": "Weekly",
                    "claimsHistory": "None",
                    "storageSecurity": "Standard",
                    "gpsTracking": "None",
                    "purchaseRecency": "180+ days",
                    "coverageType": "Theft Only"
                  },
                  "disclaimer": "This is an indicative estimate only and does not constitute an offer of insurance. Final premiums may vary based on full underwriting. 256M is not yet live.",
                  "moreInfo": "https://256m.io/pricing-widget/",
                  "waitlist": "https://256m.io/#signup"
                }
              }
            }
          },
          "400": {
            "description": "Validation error — missing or invalid parameters",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "ok": false,
                  "errors": ["Missing required parameter: watchValue", "Invalid brandTier: \"super\". Expected one of: ultra_luxury, high_luxury, luxury, premium"]
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (30 requests per IP per minute)",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "postQuote",
        "summary": "Get an indicative insurance quote (JSON body)",
        "description": "Same as GET but accepts parameters as a JSON body instead of query parameters.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/QuoteRequest" },
              "example": {
                "watchValue": 15000,
                "brandTier": "high_luxury",
                "recognizability": "well_known",
                "country": "uk",
                "urbanDensity": "city",
                "postcodeRisk": "moderate",
                "ageGroup": "26_34",
                "wearFrequency": "weekly",
                "claimsHistory": "none",
                "storageSecurity": "standard",
                "gpsTracking": "none",
                "purchaseRecency": "over_180",
                "coverageType": "theftOnly"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful quote",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/QuoteResponse" }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "QuoteRequest": {
        "type": "object",
        "required": ["watchValue", "brandTier", "recognizability", "country", "urbanDensity", "postcodeRisk", "ageGroup", "wearFrequency", "claimsHistory", "storageSecurity", "gpsTracking", "purchaseRecency", "coverageType"],
        "properties": {
          "watchValue": { "type": "integer", "minimum": 500, "maximum": 35000, "description": "Watch value in USD" },
          "brandTier": { "type": "string", "enum": ["ultra_luxury", "high_luxury", "luxury", "premium"] },
          "recognizability": { "type": "string", "enum": ["iconic", "well_known", "moderate", "low"] },
          "country": { "type": "string", "enum": ["uk", "italy", "france", "belgium", "germany", "switzerland"] },
          "urbanDensity": { "type": "string", "enum": ["major_city", "city", "suburban", "rural"] },
          "postcodeRisk": { "type": "string", "enum": ["very_high", "high", "moderate", "low", "very_low"] },
          "ageGroup": { "type": "string", "enum": ["18_25", "26_34", "35_49", "50_plus"] },
          "wearFrequency": { "type": "string", "enum": ["daily", "weekly", "rotation", "occasional"] },
          "claimsHistory": { "type": "string", "enum": ["none", "one", "two", "multiple"] },
          "storageSecurity": { "type": "string", "enum": ["safe_and_alarm", "safe", "alarm", "standard", "none"] },
          "gpsTracking": { "type": "string", "enum": ["active", "none"] },
          "purchaseRecency": { "type": "string", "enum": ["first_90", "91_180", "over_180"] },
          "coverageType": { "type": "string", "enum": ["theftOnly", "theftAndLoss"] }
        }
      },
      "QuoteResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "const": true },
          "quote": {
            "type": "object",
            "properties": {
              "monthlyPremium": { "type": "string", "description": "e.g. '$28.46'" },
              "annualPremium": { "type": "string", "description": "e.g. '$341.52'" },
              "annualRate": { "type": "string", "description": "e.g. '2.28%'" },
              "currency": { "type": "string", "const": "USD" },
              "deductible": { "type": "string", "description": "'0%' for Theft Only, '20% on loss claims' for Theft + Loss" }
            }
          },
          "profile": { "type": "object", "description": "Echo of input parameters with human-friendly labels" },
          "disclaimer": { "type": "string" },
          "moreInfo": { "type": "string", "format": "uri" },
          "waitlist": { "type": "string", "format": "uri" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "const": false },
          "errors": { "type": "array", "items": { "type": "string" } },
          "schema": { "type": "object", "description": "Full API schema (included on validation errors)" }
        }
      }
    }
  }
}
