{
  "openapi": "3.1.0",
  "info": {
    "title": "Digital Pages API",
    "version": "1.0.0",
    "description": "Open read API for the Digital Pages directory of Australian local service businesses, plus moderated review submission. No authentication for reads. Attestations are verified facts with provenance and checked-at dates."
  },
  "servers": [
    {
      "url": "https://digitalpages.com.au"
    }
  ],
  "paths": {
    "/api/v1/businesses": {
      "get": {
        "operationId": "listBusinesses",
        "summary": "List/search businesses",
        "parameters": [
          {
            "name": "vertical",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "home-builders",
                "construction",
                "renovations",
                "trade-services",
                "office-fitout",
                "joinery",
                "pool-builders",
                "landscapers",
                "solar-installers",
                "signage",
                "architects",
                "engineering",
                "dentists",
                "allied-health",
                "cosmetic-clinics",
                "beauty-clinics",
                "vets",
                "ndis-providers",
                "aged-care",
                "fitness",
                "financial-advisers",
                "smsf-specialists",
                "finance-brokers",
                "accountants",
                "family-lawyers",
                "personal-injury-lawyers",
                "immigration-lawyers",
                "real-estate",
                "automotive",
                "marine",
                "manufacturing",
                "venues",
                "wedding-services",
                "accommodation",
                "distilleries",
                "wineries",
                "education"
              ]
            }
          },
          {
            "name": "city",
            "in": "query",
            "description": "city slug, e.g. perth",
            "schema": {
              "type": "string",
              "enum": [
                "sydney",
                "melbourne",
                "brisbane",
                "perth",
                "adelaide",
                "canberra",
                "hobart",
                "newcastle",
                "gold-coast",
                "sunshine-coast",
                "geelong",
                "wollongong",
                "central-coast",
                "hunter-region",
                "parramatta",
                "bendigo",
                "ballarat",
                "shepparton",
                "launceston",
                "toowoomba",
                "rockhampton",
                "mackay",
                "cairns",
                "townsville",
                "wagga-wagga",
                "orange",
                "coffs-harbour",
                "albury",
                "tamworth",
                "dubbo",
                "bunbury"
              ]
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "NSW",
                "VIC",
                "QLD",
                "WA",
                "SA",
                "TAS",
                "ACT",
                "NT"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "name/city substring",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 200,
              "default": 60
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Businesses with embedded attestations"
          }
        }
      }
    },
    "/api/v1/businesses/{slug}": {
      "get": {
        "operationId": "getBusiness",
        "summary": "One business with attestations and published reviews",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Business detail"
          },
          "404": {
            "description": "Not found"
          }
        }
      }
    },
    "/api/v1/verticals": {
      "get": {
        "operationId": "listVerticals",
        "summary": "Categories with counts",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/cities": {
      "get": {
        "operationId": "listCities",
        "summary": "Cities with counts",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/reviews": {
      "post": {
        "operationId": "submitReview",
        "summary": "Submit a review (moderated; nothing publishes automatically)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "business_slug",
                  "rating",
                  "body"
                ],
                "properties": {
                  "business_slug": {
                    "type": "string"
                  },
                  "rating": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5
                  },
                  "title": {
                    "type": "string"
                  },
                  "body": {
                    "type": "string",
                    "minLength": 30,
                    "maxLength": 4000
                  },
                  "author_name": {
                    "type": "string",
                    "description": "for human submitters"
                  },
                  "agent": {
                    "type": "object",
                    "description": "REQUIRED for agent submitters: declare yourself and who you act for",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "operator": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted into moderation queue"
          },
          "400": {
            "description": "Validation error"
          }
        }
      }
    }
  }
}