{
  "openapi": "3.0.1",
  "info": {
    "title": "WannaSport Open API",
    "description": "Live availability of sports courts and activities in Denmark (and Sweden), for third parties and AI agents. Anonymous, all parameters in the query string. Bookings happen on wannasport.com through the bookingUrl of each result.",
    "version": "v1"
  },
  "paths": {
    "/api/open/v1/availability/search": {
      "get": {
        "tags": [
          "OpenAvailability"
        ],
        "summary": "Live, bookable court and activity slots at WannaSport facilities.",
        "description": "Search by city (`area`, e.g. \"odense\"), sport (`category`, e.g. \"padel\"),\r\nfacility, date, exact start time (\"18:00\"), exact duration in minutes, distance and\r\nprice. Leave out `area` and `facility` to search the whole country.\r\n`sort` is startTime, price, duration or distance; an area search sorts by\r\ndistance by default. 50 results per page (`page`, `totalPages`).\r\n            \r\nEvery result has a `bookingUrl`: a deep link to that exact slot (start time and\r\nduration) on wannasport.com, where the user sees the live price and books.\r\n`distanceKm` is measured from `origin`, the centre of the searched area.",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "description": "Country to search in, ISO 3166 alpha-3: \"dnk\" (default) or \"swe\". Area slugs\r\nonly resolve within their own country.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "description": "Language of the bookingUrl pages: \"en\" (default), \"da\" or \"sv\". Does not change\r\nthe data, only the language of the page the user lands on.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "area",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "facility",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "product",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "startTime",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "durationMinutes",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "maxDistanceKm",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "minPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "maxPrice",
            "in": "query",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          },
          "400": {
            "description": "Bad Request"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Api.WannaSport.Rest.Public.Availability.Search.Response": {
        "required": [
          "isLast",
          "page",
          "pageSize",
          "results",
          "total",
          "totalPages"
        ],
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response.Result"
            }
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          },
          "totalPages": {
            "type": "integer",
            "format": "int32"
          },
          "isLast": {
            "type": "boolean"
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "origin": {
            "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response.OriginInfo"
          }
        },
        "additionalProperties": false
      },
      "Api.WannaSport.Rest.Public.Availability.Search.Response.FacilityInfo": {
        "required": [
          "id",
          "name",
          "slug"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "minLength": 1,
            "type": "string"
          },
          "slug": {
            "minLength": 1,
            "type": "string"
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "Api.WannaSport.Rest.Public.Availability.Search.Response.OriginInfo": {
        "required": [
          "latitude",
          "longitude",
          "name",
          "slug"
        ],
        "type": "object",
        "properties": {
          "name": {
            "minLength": 1,
            "type": "string"
          },
          "slug": {
            "minLength": 1,
            "type": "string"
          },
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "Api.WannaSport.Rest.Public.Availability.Search.Response.PriceInfo": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "Api.WannaSport.Rest.Public.Availability.Search.Response.ResourceInfo": {
        "required": [
          "id",
          "name",
          "slug"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "minLength": 1,
            "type": "string"
          },
          "slug": {
            "minLength": 1,
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "Api.WannaSport.Rest.Public.Availability.Search.Response.Result": {
        "required": [
          "available",
          "bookableOnline",
          "bookingUrl",
          "durationMinutes",
          "endTime",
          "facility",
          "price",
          "resource",
          "sport",
          "startTime"
        ],
        "type": "object",
        "properties": {
          "facility": {
            "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response.FacilityInfo"
          },
          "resource": {
            "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response.ResourceInfo"
          },
          "sport": {
            "minLength": 1,
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "format": "date-time"
          },
          "endTime": {
            "type": "string",
            "format": "date-time"
          },
          "durationMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "price": {
            "$ref": "#/components/schemas/Api.WannaSport.Rest.Public.Availability.Search.Response.PriceInfo"
          },
          "available": {
            "type": "boolean"
          },
          "bookableOnline": {
            "type": "boolean"
          },
          "bookingUrl": {
            "minLength": 1,
            "type": "string"
          },
          "distanceKm": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Please enter a valid token",
        "scheme": "Bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ]
}