{
  "openapi": "3.1.0",
  "info": {
    "title": "Mapricot API",
    "version": "1.0.0",
    "description": "Places and geocoding, routing, and IP geolocation. Each completed request is billed; see https://mapricot.com/pricing. Every response carries X-Request-Id, which is also the billed operation ID."
  },
  "servers": [{"url": "https://api.mapricot.com"}],
  "security": [{"apiKey": []}],
  "paths": {
    "/v1/search": {
      "get": {
        "operationId": "search",
        "tags": ["Places"],
        "summary": "Find addresses and places matching free text.",
        "parameters": [
          {"$ref": "#/components/parameters/q"},
          {"$ref": "#/components/parameters/focus"},
          {"$ref": "#/components/parameters/country"},
          {"$ref": "#/components/parameters/limit"},
          {"$ref": "#/components/parameters/lang"}
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/autocomplete": {
      "get": {
        "operationId": "autocomplete",
        "tags": ["Places"],
        "summary": "Suggest addresses and places for partial text.",
        "parameters": [
          {"$ref": "#/components/parameters/q"},
          {"$ref": "#/components/parameters/focus"},
          {"$ref": "#/components/parameters/country"},
          {"$ref": "#/components/parameters/limit"},
          {"$ref": "#/components/parameters/lang"}
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/reverse": {
      "get": {
        "operationId": "reverseGeocode",
        "tags": ["Places"],
        "summary": "Find the addresses nearest a coordinate.",
        "parameters": [
          {"$ref": "#/components/parameters/lat"},
          {"$ref": "#/components/parameters/lon"},
          {"$ref": "#/components/parameters/limit"},
          {"$ref": "#/components/parameters/lang"}
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/nearby": {
      "get": {
        "operationId": "nearbySearch",
        "tags": ["Places"],
        "summary": "List places around a coordinate, optionally by category.",
        "parameters": [
          {"$ref": "#/components/parameters/lat"},
          {"$ref": "#/components/parameters/lon"},
          {
            "name": "category",
            "in": "query",
            "description": "Up to ten place categories, comma separated; a place matches any of them. The values are listed at https://mapricot.com/docs/places/#categories.",
            "schema": {"type": "string", "pattern": "^[a-z0-9_:]{1,40}(,[a-z0-9_:]{1,40}){0,9}$"},
            "example": "food:coffee_shop"
          },
          {
            "name": "radius",
            "in": "query",
            "description": "Search radius in meters, at most 50000.",
            "schema": {"type": "integer", "minimum": 1, "maximum": 50000}
          },
          {"$ref": "#/components/parameters/limit"},
          {"$ref": "#/components/parameters/lang"}
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/places/{id}": {
      "get": {
        "operationId": "getPlace",
        "tags": ["Places"],
        "summary": "Fetch one place or address by its Mapricot ID.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {"type": "string", "pattern": "^[A-Za-z0-9_-]{1,200}$"}
          },
          {"$ref": "#/components/parameters/lang"}
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/route": {
      "post": {
        "operationId": "computeRoute",
        "tags": ["Routing"],
        "summary": "Compute a route through 2 to 20 waypoints.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["waypoints"],
                "properties": {
                  "waypoints": {
                    "type": "array",
                    "minItems": 2,
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": ["lat", "lon"],
                      "properties": {
                        "lat": {"type": "number", "minimum": -90, "maximum": 90},
                        "lon": {"type": "number", "minimum": -180, "maximum": 180}
                      }
                    }
                  },
                  "mode": {"type": "string", "enum": ["drive", "walk", "bicycle"], "default": "drive"}
                }
              }
            }
          }
        },
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/ip/{ip}": {
      "get": {
        "operationId": "lookupIp",
        "tags": ["IP Geolocation"],
        "summary": "Approximate location of a public IP address.",
        "parameters": [
          {
            "name": "ip",
            "in": "path",
            "required": true,
            "description": "A public IPv4 or IPv6 address.",
            "schema": {"type": "string", "maxLength": 45},
            "example": "8.8.8.8"
          }
        ],
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/account": {
      "get": {
        "operationId": "getAccount",
        "tags": ["Account"],
        "summary": "The API key's account: its ID, name, status, and creation time. Not billed, so it checks a key for free.",
        "responses": {
          "200": {"$ref": "#/components/responses/Result"},
          "4XX": {"$ref": "#/components/responses/Error"},
          "5XX": {"$ref": "#/components/responses/Error"}
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {"type": "http", "scheme": "bearer", "description": "An API key from the dashboard."}
    },
    "parameters": {
      "q": {
        "name": "q",
        "in": "query",
        "required": true,
        "description": "Free text.",
        "schema": {"type": "string", "minLength": 1, "maxLength": 500},
        "example": "coffee near pioneer square"
      },
      "focus": {
        "name": "focus",
        "in": "query",
        "description": "Bias results toward this point, as lat,lon.",
        "schema": {"type": "string"},
        "example": "45.5152,-122.6784"
      },
      "country": {
        "name": "country",
        "in": "query",
        "description": "Up to ten ISO 3166-1 alpha-2 countries, comma separated.",
        "schema": {"type": "string", "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2}){0,9}$"},
        "example": "US,CA"
      },
      "limit": {
        "name": "limit",
        "in": "query",
        "description": "Maximum results.",
        "schema": {"type": "integer", "minimum": 1, "maximum": 20, "default": 10}
      },
      "lang": {
        "name": "lang",
        "in": "query",
        "description": "ISO 639-1 language for names and labels. Defaults to en.",
        "schema": {"type": "string", "pattern": "^[a-z]{2}$"},
        "example": "fr"
      },
      "lat": {
        "name": "lat",
        "in": "query",
        "required": true,
        "schema": {"type": "number", "minimum": -90, "maximum": 90},
        "example": 45.5152
      },
      "lon": {
        "name": "lon",
        "in": "query",
        "required": true,
        "schema": {"type": "number", "minimum": -180, "maximum": 180},
        "example": -122.6784
      }
    },
    "responses": {
      "Result": {
        "description": "The service's JSON result, unchanged.",
        "content": {"application/json": {"schema": {"type": "object"}}}
      },
      "Error": {
        "description": "An error, with a code from the API reference.",
        "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error", "request_id"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {"code": {"type": "string"}, "message": {"type": "string"}}
          },
          "request_id": {"type": "string", "format": "uuid"}
        }
      }
    }
  }
}
