{
  "openapi": "3.1.0",
  "info": {
    "title": "AYCF Radar API",
    "description": "Free, open, no-auth API for the Wizz Air All You Can Fly (AYCF) pass. Returns routes bookable on the pass right now, real scheduled flight times, layover-aware connections, and paid Ryanair onward legs. Cities are plain names (e.g. \"Budapest\", \"Tel Aviv\"). All data is scoped to the current AYCF booking window (~3-4 days). Unofficial; not affiliated with Wizz Air or Ryanair. Times are the published schedule; AYCF seats are only confirmed at booking; connection layovers are estimated.",
    "version": "1.0.0",
    "contact": {
      "email": "hello@aycfradar.com"
    }
  },
  "servers": [
    {
      "url": "https://aycfradar.com"
    }
  ],
  "paths": {
    "/api/graph": {
      "get": {
        "operationId": "getRouteGraph",
        "summary": "Full AYCF route network",
        "description": "Every city currently on the pass with coordinates, country, and its direct AYCF destinations. Best single call to understand what is flyable right now.",
        "responses": {
          "200": {
            "description": "Route graph",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "window": {
                      "type": "object",
                      "properties": {
                        "start": {
                          "type": "string"
                        },
                        "end": {
                          "type": "string"
                        }
                      }
                    },
                    "nodes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "city": {
                            "type": "string"
                          },
                          "iata": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          },
                          "lat": {
                            "type": "number"
                          },
                          "lon": {
                            "type": "number"
                          },
                          "dests": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "operationId": "searchDirectRoutes",
        "summary": "Direct AYCF routes",
        "description": "Direct routes bookable on the pass. Provide from and/or to; omit to to list everywhere you can fly from a city.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Origin city name, e.g. Budapest"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Destination city name, e.g. London"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching direct routes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/flights": {
      "get": {
        "operationId": "getFlightTimes",
        "summary": "Real scheduled departures for a route",
        "description": "Actual Wizz departure dates and times for a route in the current window.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Origin city name"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Destination city name"
          }
        ],
        "responses": {
          "200": {
            "description": "Flights",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "available": {
                      "type": "boolean"
                    },
                    "flights": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string"
                          },
                          "time": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/connections": {
      "get": {
        "operationId": "getConnections",
        "summary": "1- or 2-stop connections",
        "description": "Layover-aware itineraries when there is no direct AYCF route, sorted by total trip time.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stops",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                1,
                2
              ],
              "default": 1
            },
            "description": "Max stops (1 or 2)"
          }
        ],
        "responses": {
          "200": {
            "description": "Itineraries",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "connections": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "via": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "totalMin": {
                            "type": "integer"
                          },
                          "layovers": {
                            "type": "array",
                            "items": {
                              "type": "integer"
                            }
                          },
                          "legs": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "from": {
                                  "type": "string"
                                },
                                "to": {
                                  "type": "string"
                                },
                                "date": {
                                  "type": "string"
                                },
                                "dep": {
                                  "type": "string"
                                },
                                "arr": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/onward": {
      "get": {
        "operationId": "getOnwardOptions",
        "summary": "AYCF hub + paid Ryanair onward",
        "description": "Reach a destination Wizz doesn't serve: fly AYCF free to a hub, then a paid Ryanair leg onward (real times + fares).",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "AYCF origin city"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Final destination (anywhere Ryanair flies)"
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30
            },
            "description": "Onward horizon in days"
          }
        ],
        "responses": {
          "200": {
            "description": "Onward options",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "itineraries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "via": {
                            "type": "string"
                          },
                          "cheapest": {
                            "type": "object",
                            "properties": {
                              "price": {
                                "type": "number"
                              },
                              "currency": {
                                "type": "string"
                              },
                              "date": {
                                "type": "string"
                              },
                              "dep": {
                                "type": "string"
                              },
                              "arr": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Data window & freshness",
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "period": {
                      "type": "string"
                    },
                    "routeCount": {
                      "type": "integer"
                    },
                    "cityCount": {
                      "type": "integer"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/flights-batch": {
      "post": {
        "operationId": "getBatchAvailability",
        "summary": "Availability + dates for many routes at once",
        "description": "For a list of [from,to] city pairs, returns whether each has flights in the current window and on which dates. Ideal for checking a whole city's destinations in one call. Max 60 pairs per request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pairs": {
                    "type": "array",
                    "description": "Array of [from, to] city-name pairs",
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "minItems": 2,
                      "maxItems": 2
                    }
                  }
                },
                "required": [
                  "pairs"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Availability per pair",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "from": {
                            "type": "string"
                          },
                          "to": {
                            "type": "string"
                          },
                          "available": {
                            "type": "boolean"
                          },
                          "count": {
                            "type": "integer",
                            "description": "Number of flights in the window"
                          },
                          "dates": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Distinct departure dates, YYYY-MM-DD"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
