{
  "openapi": "3.1.0",
  "info": {
    "title": "EstatePlan.now directory API",
    "version": "1",
    "description": "Read-only access to the estate planning firms listed on EstatePlan.now. Facts come from each firm's own website, with the source page and dates recorded. When you show them, name EstatePlan.now and link the firm's profile_url; the firm's own site is the current source. EstatePlan.now is not a law firm and does not rate firms.",
    "contact": {
      "email": "info@estateplan.now",
      "url": "https://www.estateplan.now/developers"
    }
  },
  "servers": [
    {
      "url": "https://www.estateplan.now/"
    }
  ],
  "paths": {
    "/api/v1/firms": {
      "get": {
        "operationId": "searchFirms",
        "summary": "Search listed estate planning firms",
        "description": "Filter by place (location text, state, metro, or lat/lng with a radius), service, online first step and published price. Sponsored placements are labeled and listed first.",
        "parameters": [
          {
            "name": "location",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "City and state (\"Portland, OR\"), state (\"Oregon\"/\"OR\") or a 5-digit ZIP."
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "State code or slug, e.g. OR or oregon."
          },
          {
            "name": "metro",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Metro slug from /api/v1/places, e.g. portland-or."
          },
          {
            "name": "lat",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "lng",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "radius_mi",
            "in": "query",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 250,
              "default": 50
            }
          },
          {
            "name": "service",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "estate-planning",
                "wills-and-trusts",
                "probate-and-trust-administration",
                "elder-law",
                "young-adult-documents"
              ]
            }
          },
          {
            "name": "online",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Only firms whose first step can be completed online."
          },
          {
            "name": "priced",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "Only firms that publish a price."
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Part of the firm name."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching firms",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResult"
                }
              }
            }
          },
          "400": {
            "description": "The place, service or coordinates weren't recognized."
          }
        }
      }
    },
    "/api/v1/firms/{slug}": {
      "get": {
        "operationId": "getFirm",
        "summary": "One firm's full public record",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The firm",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "firm": {
                      "$ref": "#/components/schemas/Firm"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No listed firm has that slug."
          }
        }
      }
    },
    "/api/v1/places": {
      "get": {
        "operationId": "listPlaces",
        "summary": "Covered states and metro areas, with firm counts and page URLs",
        "responses": {
          "200": {
            "description": "Places"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Sourced": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Page on the firm's own website that supports the value."
          },
          "observed_at": {
            "type": "string",
            "format": "date"
          },
          "checked_at": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "Firm": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "profile_url": {
            "type": "string",
            "format": "uri"
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": "string"
          },
          "state_name": {
            "type": "string"
          },
          "distance_mi": {
            "type": "integer",
            "description": "Miles between office city and the searched place (city-level)."
          },
          "address": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Sourced"
              },
              {
                "type": "null"
              }
            ]
          },
          "phone": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Sourced"
              },
              {
                "type": "null"
              }
            ]
          },
          "summary": {
            "$ref": "#/components/schemas/Sourced"
          },
          "services": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sourced"
            }
          },
          "people": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "role": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "source_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page on the firm's own website that supports the value."
                },
                "observed_at": {
                  "type": "string",
                  "format": "date"
                },
                "checked_at": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          },
          "price": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "status": {
                    "const": "published"
                  },
                  "amount": {
                    "type": "number"
                  },
                  "currency": {
                    "const": "USD"
                  },
                  "package_name": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string",
                    "description": "What the published amount covers."
                  },
                  "qualifier": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "source_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Page on the firm's own website that supports the value."
                  },
                  "observed_at": {
                    "type": "string",
                    "format": "date"
                  },
                  "checked_at": {
                    "type": "string",
                    "format": "date"
                  }
                }
              },
              {
                "type": "object",
                "properties": {
                  "status": {
                    "const": "not_listed"
                  }
                }
              }
            ]
          },
          "how_to_begin": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "method": {
                "type": "string",
                "enum": [
                  "online_intake",
                  "online_questionnaire",
                  "downloadable_forms",
                  "scheduling",
                  "contact",
                  "general"
                ]
              },
              "label": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "begin_with": {
                "type": "string"
              },
              "what_happens_next": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "online": {
                "type": "boolean"
              },
              "applies_to": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "source_url": {
                "type": "string",
                "format": "uri",
                "description": "Page on the firm's own website that supports the value."
              },
              "observed_at": {
                "type": "string",
                "format": "date"
              },
              "checked_at": {
                "type": "string",
                "format": "date"
              }
            }
          },
          "starts_online": {
            "type": "boolean"
          },
          "sponsored": {
            "oneOf": [
              {
                "const": false
              },
              {
                "type": "object",
                "properties": {
                  "disclosure": {
                    "type": "string"
                  },
                  "since": {
                    "type": "string",
                    "format": "date"
                  }
                }
              }
            ]
          },
          "record_checked_at": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "properties": {
          "query": {
            "type": "object"
          },
          "order": {
            "type": "string"
          },
          "total": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "page_url": {
            "type": "string",
            "format": "uri"
          },
          "firms": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Firm"
            }
          },
          "attribution": {
            "type": "string"
          }
        }
      }
    }
  }
}