{
 "openapi": "3.1.0",
 "info": {
  "title": "CityBotMagic API",
  "version": "0.2.0",
  "description": "Local businesses, services and prices — structured for AI agents."
 },
 "servers": [
  {
   "url": "https://citybotmagic.com"
  }
 ],
 "paths": {
  "/api/v1/cities.json": {
   "get": {
    "summary": "Cities covered",
    "responses": {
     "200": {
      "description": "City list"
     }
    }
   }
  },
  "/api/v1/us/{state}/{city}.json": {
   "get": {
    "summary": "Businesses in a city (paginated summaries)",
    "parameters": [
     {
      "name": "state",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "nv"
      }
     },
     {
      "name": "city",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "reno"
      }
     },
     {
      "name": "page",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1
      }
     },
     {
      "name": "per_page",
      "in": "query",
      "schema": {
       "type": "integer",
       "maximum": 500
      }
     },
     {
      "name": "group",
      "in": "query",
      "schema": {
       "type": "string",
       "example": "food_and_drink"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "City info, categories, one page of business summaries and a `next` link"
     }
    }
   }
  },
  "/api/v1/us/{state}/{city}/{business}.json": {
   "get": {
    "summary": "One business",
    "parameters": [
     {
      "name": "state",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "city",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "business",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Business record",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Business"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/search.json": {
   "get": {
    "summary": "Search businesses in a city by name, category, service or product",
    "parameters": [
     {
      "name": "state",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "nv"
      }
     },
     {
      "name": "city",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "reno"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "oil change"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "maximum": 100
      }
     },
     {
      "name": "group",
      "in": "query",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "has_prices",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "1"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Matching business summaries"
     }
    }
   }
  },
  "/api/v1/prices.json": {
   "get": {
    "summary": "Published prices for an item or service in a city",
    "parameters": [
     {
      "name": "state",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "nv"
      }
     },
     {
      "name": "city",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "reno"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "example": "oil change"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "maximum": 100
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Price rows with source URL and date"
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "Business": {
    "type": "object",
    "required": [
     "id",
     "name",
     "category",
     "lat",
     "lon",
     "sources"
    ],
    "properties": {
     "id": {
      "type": "string",
      "description": "Overture GERS id (stable)"
     },
     "name": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "category": {
      "type": "string"
     },
     "categoryLabel": {
      "type": "string"
     },
     "group": {
      "type": "string"
     },
     "chain": {
      "type": "string"
     },
     "address": {
      "type": "string"
     },
     "city": {
      "type": "string"
     },
     "state": {
      "type": "string"
     },
     "postcode": {
      "type": "string"
     },
     "lat": {
      "type": "number"
     },
     "lon": {
      "type": "number"
     },
     "phone": {
      "type": "string",
      "description": "E.164"
     },
     "website": {
      "type": "string"
     },
     "email": {
      "type": "string"
     },
     "description": {
      "type": "string"
     },
     "hours": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "schema.org openingHours, e.g. \"Mo-Fr 08:00-17:00\""
     },
     "hoursText": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Hours as written on the website"
     },
     "services": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "prices": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "item": {
         "type": "string"
        },
        "price": {
         "type": "number"
        },
        "maxPrice": {
         "type": "number"
        },
        "currency": {
         "type": "string"
        },
        "unit": {
         "type": "string"
        },
        "source": {
         "type": "string"
        },
        "seen": {
         "type": "string",
         "format": "date"
        },
        "method": {
         "type": "string",
         "enum": [
          "schema",
          "llm",
          "text"
         ],
         "description": "schema = the business's structured data; llm = read by Claude and verified against the quoted page text; text = pattern-matched"
        },
        "quote": {
         "type": "string",
         "description": "Page text the price was read from"
        }
       }
      }
     },
     "bookingUrl": {
      "type": "string"
     },
     "sources": {
      "type": "array",
      "items": {
       "type": "object"
      }
     }
    }
   }
  }
 }
}