{
  "openapi": "3.0.1",
  "info": {
    "title": "TownVue Public API",
    "description": "Read-only public API for AI agents and integrators. Returns businesses, events, experiences, trading-post listings, towns, and categories as JSON. Rate limit: 60 requests per minute per IP. No authentication. CORS: any origin, GET/HEAD/OPTIONS only. Contact support@townvue.com for higher rate limits.",
    "contact": {
      "name": "TownVue support",
      "url": "https://www.townvue.com/About",
      "email": "support@townvue.com"
    },
    "license": {
      "name": "Terms of use",
      "url": "https://www.townvue.com/Legal/Terms"
    },
    "version": "v1"
  },
  "paths": {
    "/public-api/v1/Businesses": {
      "get": {
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessSummaryPaginatedResult"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Businesses/{slugOrId}": {
      "get": {
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "slugOrId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Categories": {
      "get": {
        "tags": [
          "Categories"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CategoryDto"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Events": {
      "get": {
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "includePast",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventSummaryPaginatedResult"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Events/{slugOrId}": {
      "get": {
        "tags": [
          "Events"
        ],
        "parameters": [
          {
            "name": "slugOrId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Experiences": {
      "get": {
        "tags": [
          "Experiences"
        ],
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExperienceSummaryPaginatedResult"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Experiences/{slugOrId}": {
      "get": {
        "tags": [
          "Experiences"
        ],
        "parameters": [
          {
            "name": "slugOrId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExperienceDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Towns": {
      "get": {
        "tags": [
          "Towns"
        ],
        "parameters": [
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TownSummaryPaginatedResult"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/Towns/{citySlug}": {
      "get": {
        "tags": [
          "Towns"
        ],
        "parameters": [
          {
            "name": "citySlug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TownDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/trading-post": {
      "get": {
        "tags": [
          "TradingPost"
        ],
        "parameters": [
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradingPostSummaryPaginatedResult"
                }
              }
            }
          }
        }
      }
    },
    "/public-api/v1/trading-post/{slugOrId}": {
      "get": {
        "tags": [
          "TradingPost"
        ],
        "parameters": [
          {
            "name": "slugOrId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradingPostDetail"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "BusinessDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "zipCode": {
            "type": "string",
            "nullable": true
          },
          "geo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/GeoDto"
              }
            ],
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "menuUrl": {
            "type": "string",
            "nullable": true
          },
          "serviceEntireUS": {
            "type": "boolean"
          },
          "serviceAreas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlaceDto"
            }
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageDto"
            }
          },
          "priceRange": {
            "type": "string",
            "nullable": true
          },
          "createdDate": {
            "type": "string",
            "format": "date-time"
          },
          "lastModified": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BusinessSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "primaryImageUrl": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "BusinessSummaryPaginatedResult": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessSummary"
            }
          }
        },
        "additionalProperties": false
      },
      "CategoryDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "EventDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "eventDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "startTime": {
            "type": "string",
            "nullable": true
          },
          "endTime": {
            "type": "string",
            "nullable": true
          },
          "isAllDay": {
            "type": "boolean"
          },
          "isVirtualEvent": {
            "type": "boolean"
          },
          "virtualEventUrl": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "geo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/GeoDto"
              }
            ],
            "nullable": true
          },
          "isFree": {
            "type": "boolean"
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "priceDescription": {
            "type": "string",
            "nullable": true
          },
          "organizerName": {
            "type": "string",
            "nullable": true
          },
          "organizerEmail": {
            "type": "string",
            "nullable": true
          },
          "organizerPhone": {
            "type": "string",
            "nullable": true
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageDto"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "EventSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "primaryImageUrl": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "eventDate": {
            "type": "string",
            "format": "date-time"
          },
          "isFree": {
            "type": "boolean"
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EventSummaryPaginatedResult": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventSummary"
            }
          }
        },
        "additionalProperties": false
      },
      "ExperienceDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "zipCode": {
            "type": "string",
            "nullable": true
          },
          "geo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/GeoDto"
              }
            ],
            "nullable": true
          },
          "isFree": {
            "type": "boolean"
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "priceDescription": {
            "type": "string",
            "nullable": true
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageDto"
            }
          },
          "createdDate": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExperienceSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "primaryImageUrl": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "isFree": {
            "type": "boolean"
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExperienceSummaryPaginatedResult": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExperienceSummary"
            }
          }
        },
        "additionalProperties": false
      },
      "GeoDto": {
        "type": "object",
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "ImageDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "altText": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PlaceDto": {
        "type": "object",
        "properties": {
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "TownDetail": {
        "type": "object",
        "properties": {
          "citySlug": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "businessCount": {
            "type": "integer",
            "format": "int32"
          },
          "eventCount": {
            "type": "integer",
            "format": "int32"
          },
          "experienceCount": {
            "type": "integer",
            "format": "int32"
          },
          "tradingPostCount": {
            "type": "integer",
            "format": "int32"
          },
          "servingBusinessCount": {
            "type": "integer",
            "format": "int32"
          },
          "introText": {
            "type": "string",
            "nullable": true
          },
          "lastUpdated": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TownSummary": {
        "type": "object",
        "properties": {
          "citySlug": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "businessCount": {
            "type": "integer",
            "format": "int32"
          },
          "eventCount": {
            "type": "integer",
            "format": "int32"
          },
          "experienceCount": {
            "type": "integer",
            "format": "int32"
          },
          "tradingPostCount": {
            "type": "integer",
            "format": "int32"
          },
          "servingBusinessCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "TownSummaryPaginatedResult": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TownSummary"
            }
          }
        },
        "additionalProperties": false
      },
      "TradingPostDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "zipCode": {
            "type": "string",
            "nullable": true
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "condition": {
            "type": "string",
            "nullable": true
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageDto"
            }
          },
          "createdDate": {
            "type": "string",
            "format": "date-time"
          },
          "updatedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TradingPostSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "primaryImageUrl": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "allOf": [
              {
                "$ref": "#/components/schemas/PlaceDto"
              }
            ],
            "nullable": true
          },
          "price": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TradingPostSummaryPaginatedResult": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TradingPostSummary"
            }
          }
        },
        "additionalProperties": false
      }
    }
  }
}