{
  "openapi": "3.1.0",
  "info": {
    "title": "CityPreferred public API",
    "version": "1",
    "description": "CityPreferred connects a person in the United States with one local service company (cleaning, concrete, paving, garage doors, painting, plumbing, electrical, HVAC, roofing, landscaping), for a home or a business. The person describes the job; CityPreferred checks it by hand and one company that serves their area contacts them. Free for the person; funded by the companies. No rankings, no price lists.",
    "contact": {
      "email": "hello@citypreferred.com"
    }
  },
  "servers": [
    {
      "url": "https://citypreferred.com"
    }
  ],
  "paths": {
    "/api/v1": {
      "get": {
        "operationId": "index",
        "summary": "What this API is and where its endpoints are",
        "responses": {
          "200": {
            "description": "Index",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/services": {
      "get": {
        "operationId": "listServices",
        "summary": "The services CityPreferred covers, with the questions each asks and a link to its page",
        "responses": {
          "200": {
            "description": "Services",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/markets": {
      "get": {
        "operationId": "listMarkets",
        "summary": "City and city-plus-service pages currently published, with their publication state",
        "responses": {
          "200": {
            "description": "Markets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents": {
      "get": {
        "operationId": "listDocuments",
        "summary": "Every public page, with a markdown URL",
        "responses": {
          "200": {
            "description": "Documents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/documents/{path}": {
      "get": {
        "operationId": "getDocument",
        "summary": "One public page as markdown (guides, tools, local pages, policies)",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Site path without the leading slash, e.g. services/cleaning"
          }
        ],
        "responses": {
          "200": {
            "description": "Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Not a public page"
          }
        }
      }
    },
    "/api/v1/counts": {
      "get": {
        "operationId": "providerCounts",
        "summary": "How many companies CityPreferred counted for a trade: nationally, in a state, or in a city. Numbers only.",
        "parameters": [
          {
            "name": "trade",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Service slug (cleaning) or dataset slug (roofing). Omit to list trades."
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$"
            },
            "description": "Two-letter state code"
          },
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "City name; needs state"
          }
        ],
        "responses": {
          "200": {
            "description": "Counts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Unknown trade or state"
          }
        }
      }
    },
    "/api/v1/request-link": {
      "get": {
        "operationId": "requestLink",
        "summary": "A link that opens the request form with the service and ZIP filled in. The person sends it; programs cannot.",
        "parameters": [
          {
            "name": "service",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Service slug from /api/v1/services"
          },
          {
            "name": "zip",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^\\d{5}$"
            },
            "description": "5-digit US ZIP code of the property"
          }
        ],
        "responses": {
          "200": {
            "description": "Link",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "service": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "zip": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}