{
  "openapi": "3.1.0",
  "info": {
    "title": "CharlestonRanked Public API",
    "version": "1.0.0",
    "description": "Read-only JSON API for CharlestonRanked — Charleston, SC's community-curated guide. Use this to query ranked places, neighborhoods, and a comprehensive events calendar aggregated nightly. Free to use under CC BY 4.0 with attribution.",
    "contact": {
      "name": "CharlestonRanked",
      "url": "https://www.charlestonranked.com"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://www.charlestonranked.com/api/v1",
      "description": "Production v1"
    }
  ],
  "paths": {
    "/events": {
      "get": {
        "summary": "List upcoming events",
        "description": "Returns approved upcoming events sorted by start time ascending. Supports filtering by category, neighborhood, venue (entity slug), and date range.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Page size (1–200, default 50)"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Items to skip (default 0)"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "music | food | festival | market | family | nightlife | art | sports | community"
          },
          {
            "name": "neighborhood",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Neighborhood slug, e.g. downtown, mount-pleasant, folly-beach"
          },
          {
            "name": "venue",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Entity slug to filter by venue, e.g. charleston-music-hall"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 — events starting at/after (default: now)"
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 — events starting before"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            }
          }
        }
      }
    },
    "/entities": {
      "get": {
        "summary": "List ranked places",
        "description": "Returns ranked Charleston places (restaurants, bars, beaches, coffee shops, etc.) sorted by rating descending by default.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Page size (1–200, default 50)"
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Items to skip"
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Category slug — restaurants | coffee | bars | beaches | golf | …"
          },
          {
            "name": "neighborhood",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Neighborhood slug"
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Fuzzy text match against name/description/address"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "rank (default, by avg rating desc) | new (created desc)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityList"
                }
              }
            }
          }
        }
      }
    },
    "/areas": {
      "get": {
        "summary": "List Charleston neighborhoods",
        "description": "Returns the curated list of Charleston-area neighborhoods we cover, with centroids and links to filtered events/entities.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AreaList"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Meta": {
        "type": "object",
        "properties": {
          "total": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Total matching rows"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "next": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL for the next page or null"
          }
        },
        "required": [
          "limit",
          "offset"
        ]
      },
      "Links": {
        "type": "object",
        "properties": {
          "self": {
            "type": "string"
          },
          "docs": {
            "type": "string"
          },
          "openapi": {
            "type": "string"
          },
          "license": {
            "type": "string"
          }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "starts_at": {
            "type": "string",
            "format": "date-time"
          },
          "ends_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "all_day": {
            "type": "boolean"
          },
          "category": {
            "type": "string",
            "enum": [
              "music",
              "food",
              "festival",
              "market",
              "family",
              "nightlife",
              "art",
              "sports",
              "community"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "venue": {
            "type": "object",
            "properties": {
              "entity_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "neighborhood": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "latitude": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "longitude": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "ticket_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "price_tier": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "free",
              "$",
              "$$",
              "$$$",
              null
            ]
          },
          "organizer": {
            "type": [
              "string",
              "null"
            ]
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "source_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "description": "Canonical event detail URL"
              }
            }
          }
        }
      },
      "Entity": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "business",
              "place",
              "activity",
              "area"
            ]
          },
          "category": {
            "type": "string"
          },
          "secondary_categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "neighborhood": {
            "type": [
              "string",
              "null"
            ]
          },
          "latitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "longitude": {
            "type": [
              "number",
              "null"
            ]
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "website_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "avg_rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "rating_count": {
            "type": [
              "integer",
              "null"
            ]
          },
          "score": {
            "type": "number"
          },
          "google_rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "yelp_rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "price_level": {
            "type": [
              "integer",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string"
              }
            }
          }
        }
      },
      "Area": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "blurb": {
            "type": "string"
          },
          "centroid": {
            "type": "object",
            "properties": {
              "latitude": {
                "type": "number"
              },
              "longitude": {
                "type": "number"
              }
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string"
              },
              "events": {
                "type": "string"
              },
              "entities": {
                "type": "string"
              }
            }
          }
        }
      },
      "EventList": {
        "type": "object",
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "links": {
            "$ref": "#/components/schemas/Links"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          }
        },
        "required": [
          "meta",
          "data"
        ]
      },
      "EntityList": {
        "type": "object",
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "links": {
            "$ref": "#/components/schemas/Links"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Entity"
            }
          }
        },
        "required": [
          "meta",
          "data"
        ]
      },
      "AreaList": {
        "type": "object",
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "links": {
            "$ref": "#/components/schemas/Links"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Area"
            }
          }
        },
        "required": [
          "meta",
          "data"
        ]
      }
    }
  }
}