{
  "openapi": "3.0.3",
  "info": {
    "title": "12db Relaisverzeichnis",
    "version": "1.0.0",
    "description": "Suche und Abruf einzelner Relaisinformationen zu Relais in Deutschland, ohne API-Schlüssel. Keine Echtzeitdaten: Der Status beschreibt die zuletzt dokumentierte Lage, nicht den Betrieb in diesem Moment, und eine Frequenz heißt nicht, dass das Relais in Betrieb ist. Grenzen je Herkunft: 120 Abfragen je Minute, 600 je Stunde, 30 CSV-Abrufe je Stunde. HTTP 429 nennt die Wartezeit in `Retry-After`. Die Liste reicht bis Treffer 200, breite Suchen lassen sich mit Filtern oder Umkreis eingrenzen. Eine allgemeine Freigabe der vollständigen Datenbank zur Übernahme und Weiterveröffentlichung ist derzeit nicht vorgesehen, Gesamtausgaben gibt es nicht."
  },
  "servers": [
    {
      "url": "https://www.12db.de/api/v1"
    }
  ],
  "paths": {
    "/relaisverzeichnis": {
      "get": {
        "summary": "Relais suchen und filtern",
        "description": "Band, Betriebsart und Frequenz gelten zusammen für denselben Kanal.",
        "operationId": "liste",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Freie Suche in Rufzeichen, Ort, Betreiber, Locator-Anfang und Frequenz-Anfang",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "rufzeichen",
            "in": "query",
            "required": false,
            "description": "Rufzeichen oder ein Teil davon, Ø gilt als 0",
            "schema": {
              "type": "string",
              "maxLength": 12
            }
          },
          {
            "name": "ort",
            "in": "query",
            "required": false,
            "description": "Teil der Ortsangabe",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "locator",
            "in": "query",
            "required": false,
            "description": "Anfang des Locators",
            "schema": {
              "type": "string",
              "maxLength": 6
            }
          },
          {
            "name": "frequenz",
            "in": "query",
            "required": false,
            "description": "Ausgabe oder Eingabe in MHz",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 300000
            }
          },
          {
            "name": "toleranz_khz",
            "in": "query",
            "required": false,
            "description": "Toleranz zu frequenz in kHz",
            "schema": {
              "type": "number",
              "default": 5,
              "minimum": 0,
              "maximum": 1000
            }
          },
          {
            "name": "band",
            "in": "query",
            "required": false,
            "description": "Ein oder mehrere Bänder, kommagetrennt, zum Beispiel 2m,70cm. Im Bestand kommen 10m, 2m, 70cm, 23cm und 13cm vor. Gültig sind alle Bandnamen nach AFuV Anlage 1, etwa 6m oder 9cm. Das Komma in 1,2cm, 2,5mm und 1,2mm gehört zum Namen.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "betriebsart",
            "in": "query",
            "required": false,
            "description": "Kommagetrennt. Gültig sind FM, DMR, D-Star, C4FM, NXDN, P25, TETRA, M17, ATV und Transponder",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "aktuell_dokumentiert, frequenz_dokumentiert, aeltere_dokumentation, ausser_betrieb, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sicherheit",
            "in": "query",
            "required": false,
            "description": "hoch, mittel, gering, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mit_standort",
            "in": "query",
            "required": false,
            "description": "Nur Relais mit belegtem Standort: 1, true oder ja",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true",
                "ja",
                "0"
              ]
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Breite des eigenen Standorts, nur zusammen mit lon",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "lon",
            "in": "query",
            "required": false,
            "description": "Länge des eigenen Standorts, nur zusammen mit lat",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "radius_km",
            "in": "query",
            "required": false,
            "description": "Umkreis, braucht lat und lon",
            "schema": {
              "type": "number",
              "maximum": 200,
              "minimum": 0
            }
          },
          {
            "name": "seite",
            "in": "query",
            "required": false,
            "description": "Seite. Geblättert wird bis Treffer 200, dahinter antwortet der Server mit 400",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "pro_seite",
            "in": "query",
            "required": false,
            "description": "Treffer je Seite. Größere Werte gelten als 50",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 50,
              "minimum": 1
            }
          },
          {
            "name": "ausschnitt",
            "in": "query",
            "description": "Kartenausschnitt als süd,west,nord,ost. Breite bis 90, Länge bis 540 Grad, damit die Karte über den 180. Längengrad gezogen werden kann",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ruf",
            "in": "query",
            "required": false,
            "description": "Rufzeichen, kommagetrennt, höchstens 25",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortierung",
            "in": "query",
            "description": "Reihenfolge: belege (mit Ort und bestem Beleg zuerst), rufzeichen, ort, frequenz. Vorgabe ist das Rufzeichen. Im Umkreis gilt die Entfernung.",
            "schema": {
              "type": "string",
              "enum": [
                "belege",
                "rufzeichen",
                "ort",
                "frequenz"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Treffer"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/{id}": {
      "get": {
        "summary": "Ein Relais",
        "operationId": "relais",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EinRelais"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "404": {
            "$ref": "#/components/responses/NichtGefunden"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/nearby": {
      "get": {
        "summary": "Relais im Umkreis, nächste zuerst, seitenweise",
        "operationId": "umkreis",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Breite, nur zusammen mit lon",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "lon",
            "in": "query",
            "required": false,
            "description": "Länge, nur zusammen mit lat",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "locator",
            "in": "query",
            "required": false,
            "description": "Mittelpunkt statt lat und lon, vier oder sechs Stellen",
            "schema": {
              "type": "string",
              "maxLength": 6
            }
          },
          {
            "name": "radius_km",
            "in": "query",
            "required": false,
            "description": "Umkreis",
            "schema": {
              "type": "number",
              "default": 50,
              "maximum": 200,
              "minimum": 0
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Freie Suche in Rufzeichen, Ort, Betreiber, Locator-Anfang und Frequenz-Anfang",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "rufzeichen",
            "in": "query",
            "required": false,
            "description": "Rufzeichen oder ein Teil davon, Ø gilt als 0",
            "schema": {
              "type": "string",
              "maxLength": 12
            }
          },
          {
            "name": "ort",
            "in": "query",
            "required": false,
            "description": "Teil der Ortsangabe",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "frequenz",
            "in": "query",
            "required": false,
            "description": "Ausgabe oder Eingabe in MHz",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 300000
            }
          },
          {
            "name": "toleranz_khz",
            "in": "query",
            "required": false,
            "description": "Toleranz zu frequenz in kHz",
            "schema": {
              "type": "number",
              "default": 5,
              "minimum": 0,
              "maximum": 1000
            }
          },
          {
            "name": "band",
            "in": "query",
            "required": false,
            "description": "Ein oder mehrere Bänder, kommagetrennt, zum Beispiel 2m,70cm. Im Bestand kommen 10m, 2m, 70cm, 23cm und 13cm vor. Gültig sind alle Bandnamen nach AFuV Anlage 1, etwa 6m oder 9cm. Das Komma in 1,2cm, 2,5mm und 1,2mm gehört zum Namen.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "betriebsart",
            "in": "query",
            "required": false,
            "description": "Kommagetrennt. Gültig sind FM, DMR, D-Star, C4FM, NXDN, P25, TETRA, M17, ATV und Transponder",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "aktuell_dokumentiert, frequenz_dokumentiert, aeltere_dokumentation, ausser_betrieb, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sicherheit",
            "in": "query",
            "required": false,
            "description": "hoch, mittel, gering, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mit_standort",
            "in": "query",
            "required": false,
            "description": "Nur Relais mit belegtem Standort: 1, true oder ja",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true",
                "ja",
                "0"
              ]
            }
          },
          {
            "name": "ruf",
            "in": "query",
            "required": false,
            "description": "Rufzeichen, kommagetrennt, höchstens 25",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "seite",
            "in": "query",
            "required": false,
            "description": "Seite. Geblättert wird bis Treffer 200, dahinter antwortet der Server mit 400",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "pro_seite",
            "in": "query",
            "required": false,
            "description": "Treffer je Seite. Größere Werte gelten als 50",
            "schema": {
              "type": "integer",
              "default": 25,
              "maximum": 50,
              "minimum": 1
            }
          },
          {
            "name": "ausschnitt",
            "in": "query",
            "description": "Kartenausschnitt als süd,west,nord,ost. Breite bis 90, Länge bis 540 Grad, damit die Karte über den 180. Längengrad gezogen werden kann",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Umkreis"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/karte": {
      "get": {
        "summary": "Punkte in einem Kartenausschnitt",
        "operationId": "karte",
        "description": "Höchstens 100 Einzelpunkte je Anfrage. Bei mehr Treffern liefert `art: sammel` je Rasterzelle den vergröberten Schwerpunkt, die Anzahl und den Rahmen der Zelle, keine einzelnen Relais. `rahmen` umfasst alle Treffer des Filters mit Standort. Filter wie in der Liste.",
        "parameters": [
          {
            "name": "ausschnitt",
            "in": "query",
            "required": true,
            "description": "Kartenausschnitt als süd,west,nord,ost. Breite bis 90, Länge bis 540 Grad, damit die Karte über den 180. Längengrad gezogen werden kann",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Freie Suche in Rufzeichen, Ort, Betreiber, Locator-Anfang und Frequenz-Anfang",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "rufzeichen",
            "in": "query",
            "required": false,
            "description": "Rufzeichen oder ein Teil davon, Ø gilt als 0",
            "schema": {
              "type": "string",
              "maxLength": 12
            }
          },
          {
            "name": "ort",
            "in": "query",
            "required": false,
            "description": "Teil der Ortsangabe",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "locator",
            "in": "query",
            "required": false,
            "description": "Anfang des Locators",
            "schema": {
              "type": "string",
              "maxLength": 6
            }
          },
          {
            "name": "frequenz",
            "in": "query",
            "required": false,
            "description": "Ausgabe oder Eingabe in MHz",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 300000
            }
          },
          {
            "name": "toleranz_khz",
            "in": "query",
            "required": false,
            "description": "Toleranz zu frequenz in kHz",
            "schema": {
              "type": "number",
              "default": 5,
              "minimum": 0,
              "maximum": 1000
            }
          },
          {
            "name": "band",
            "in": "query",
            "required": false,
            "description": "Ein oder mehrere Bänder, kommagetrennt, zum Beispiel 2m,70cm. Im Bestand kommen 10m, 2m, 70cm, 23cm und 13cm vor. Gültig sind alle Bandnamen nach AFuV Anlage 1, etwa 6m oder 9cm. Das Komma in 1,2cm, 2,5mm und 1,2mm gehört zum Namen.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "betriebsart",
            "in": "query",
            "required": false,
            "description": "Kommagetrennt. Gültig sind FM, DMR, D-Star, C4FM, NXDN, P25, TETRA, M17, ATV und Transponder",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "aktuell_dokumentiert, frequenz_dokumentiert, aeltere_dokumentation, ausser_betrieb, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sicherheit",
            "in": "query",
            "required": false,
            "description": "hoch, mittel, gering, kommagetrennt",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mit_standort",
            "in": "query",
            "required": false,
            "description": "Nur Relais mit belegtem Standort: 1, true oder ja",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true",
                "ja",
                "0"
              ]
            }
          },
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Breite des eigenen Standorts, nur zusammen mit lon",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "lon",
            "in": "query",
            "required": false,
            "description": "Länge des eigenen Standorts, nur zusammen mit lat",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "radius_km",
            "in": "query",
            "required": false,
            "description": "Umkreis, braucht lat und lon",
            "schema": {
              "type": "number",
              "maximum": 200,
              "minimum": 0
            }
          },
          {
            "name": "ruf",
            "in": "query",
            "required": false,
            "description": "Rufzeichen, kommagetrennt, höchstens 25",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Karte"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/ort": {
      "get": {
        "summary": "Mittelpunkt zu einem Ortsnamen",
        "operationId": "ort",
        "description": "Für das Feld Nähe der Seite. Sucht in der Ortsliste und im Bestand. Ohne eindeutigen Ort fehlen `lat` und `lon`, `hinweis` erklärt den Grund. Ohne `name` antwortet der Server mit 400.",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ort"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/cockpit": {
      "get": {
        "summary": "Kanäle rund um ein Locator-Feld für das Funkcockpit",
        "operationId": "cockpit",
        "description": "Nutzbare Kanäle von Relais mit Kartenpunkt rund um ein Locator-Feld, die nächsten zuerst. Höchstens 200 Zeilen, `begrenzt` sagt, ob die Antwort deshalb gekürzt ist. Relais ohne belegten Standort und außer Betrieb gemeldete Relais fehlen hier.",
        "parameters": [
          {
            "name": "locator",
            "in": "query",
            "required": true,
            "description": "vier oder sechs Stellen",
            "schema": {
              "type": "string",
              "maxLength": 6
            }
          },
          {
            "name": "radius_km",
            "in": "query",
            "required": true,
            "description": "Abstand vom Rand des Locator-Felds",
            "schema": {
              "type": "number",
              "maximum": 150,
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Cockpit"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    },
    "/relaisverzeichnis/auswahl.csv": {
      "get": {
        "summary": "CSV zu einer Liste von Rufzeichen",
        "operationId": "auswahl_csv",
        "parameters": [
          {
            "name": "ruf",
            "in": "query",
            "required": true,
            "description": "Rufzeichen, kommagetrennt, höchstens 25",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "400": {
            "$ref": "#/components/responses/Eingabefehler"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        },
        "description": "CSV zu höchstens 25 Rufzeichen, etwa der Merkliste. Eigene Grenze: 30 Abrufe je Stunde. Ohne `ruf` antwortet der Server mit 400."
      }
    },
    "/relaisverzeichnis/openapi.json": {
      "get": {
        "summary": "Diese Beschreibung",
        "operationId": "openapi",
        "responses": {
          "200": {
            "description": "Erfolg",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/Unveraendert"
          },
          "429": {
            "$ref": "#/components/responses/ZuViele"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Fehler": {
        "type": "object",
        "required": [
          "fehler"
        ],
        "properties": {
          "fehler": {
            "type": "string"
          },
          "feld": {
            "type": "string"
          }
        }
      },
      "Meta": {
        "type": "object",
        "properties": {
          "herausgeber": {
            "type": "string"
          },
          "api_version": {
            "type": "integer"
          },
          "hinweis": {
            "type": "string",
            "description": "Was die Angaben bedeuten. `lat` und `lon` eines Relais sind die Mitte seines sechsstelligen Locators"
          },
          "nutzung": {
            "type": "string",
            "description": "Nutzungshinweis: Suche und Abruf einzelner Relaisinformationen, keine allgemeine Freigabe der vollständigen Datenbank."
          },
          "datenstand": {
            "type": "string",
            "nullable": true,
            "description": "Letzte Änderung am Bestand, UTC"
          },
          "datenstand_hash": {
            "type": "string",
            "description": "Prüfsumme des öffentlichen Bestands"
          },
          "anzahl_relais": {
            "type": "integer"
          },
          "anzahl_kanaele": {
            "type": "integer"
          }
        },
        "required": [
          "herausgeber",
          "api_version",
          "hinweis",
          "nutzung",
          "datenstand",
          "datenstand_hash",
          "anzahl_relais",
          "anzahl_kanaele"
        ]
      },
      "Kanal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "band": {
            "type": "string"
          },
          "ausgabe_mhz": {
            "type": "number"
          },
          "eingabe_mhz": {
            "type": "number",
            "nullable": true,
            "description": "Leer, wenn nicht belegt"
          },
          "eingabe_herkunft": {
            "type": "string",
            "nullable": true,
            "enum": [
              "quelle",
              "ablage",
              null
            ],
            "description": "quelle: steht so in der Quelle, ablage: aus belegter Ablage berechnet"
          },
          "eingabe_band": {
            "type": "string",
            "nullable": true
          },
          "ablage_mhz": {
            "type": "number",
            "nullable": true,
            "description": "Bei Crossband leer"
          },
          "crossband": {
            "type": "boolean"
          },
          "sonderablage": {
            "type": "boolean"
          },
          "betriebsarten": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "netze": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "multimode": {
            "type": "boolean"
          },
          "ctcss_hz": {
            "type": "number",
            "nullable": true
          },
          "ctcss_ort": {
            "type": "string",
            "nullable": true,
            "enum": [
              "eingabe",
              "ausgabe",
              "beide",
              null
            ]
          },
          "dcs": {
            "type": "string",
            "nullable": true
          },
          "rufton_1750": {
            "type": "boolean"
          },
          "traegergesteuert": {
            "type": "boolean"
          },
          "kein_ctcss": {
            "type": "boolean"
          },
          "farbcode": {
            "type": "integer",
            "nullable": true
          },
          "ausser_betrieb": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "band",
          "ausgabe_mhz",
          "eingabe_mhz",
          "eingabe_herkunft",
          "eingabe_band",
          "ablage_mhz",
          "crossband",
          "sonderablage",
          "betriebsarten",
          "netze",
          "multimode",
          "ctcss_hz",
          "ctcss_ort",
          "dcs",
          "rufton_1750",
          "traegergesteuert",
          "kein_ctcss",
          "farbcode",
          "ausser_betrieb"
        ]
      },
      "Quelle": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "host": {
            "type": "string"
          },
          "felder": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "stand": {
            "type": "string",
            "nullable": true
          },
          "abgerufen": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "url",
          "host",
          "felder",
          "stand",
          "abgerufen"
        ]
      },
      "Relais": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "rufzeichen": {
            "type": "string"
          },
          "ort": {
            "type": "string",
            "nullable": true
          },
          "locator": {
            "type": "string",
            "nullable": true
          },
          "lat": {
            "type": "number",
            "nullable": true,
            "description": "Mitte des sechsstelligen Locators, nicht der genaue Standort. Leer ohne belegten Locator"
          },
          "lon": {
            "type": "number",
            "nullable": true,
            "description": "Mitte des sechsstelligen Locators, nicht der genaue Standort. Leer ohne belegten Locator"
          },
          "betreiber": {
            "type": "string",
            "nullable": true
          },
          "betreiber_art": {
            "type": "string",
            "enum": [
              "verein",
              "ov",
              "person",
              "unbekannt"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "aktuell_dokumentiert",
              "frequenz_dokumentiert",
              "aeltere_dokumentation",
              "ausser_betrieb"
            ]
          },
          "status_text": {
            "type": "string",
            "description": "Langform des Status, etwa \"zuletzt dokumentierter Betrieb\""
          },
          "sicherheit": {
            "type": "string",
            "enum": [
              "hoch",
              "mittel",
              "gering"
            ]
          },
          "stand": {
            "type": "string",
            "nullable": true
          },
          "entfernung_km": {
            "type": "number",
            "description": "Nur bei Abfragen mit `lat` und `lon` oder Umkreis"
          },
          "kanaele": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Kanal"
            }
          },
          "quellen": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Quelle"
            }
          },
          "ort_kurz": {
            "type": "string",
            "nullable": true,
            "description": "Ort für die Anzeige, ohne Zusätze"
          }
        },
        "required": [
          "id",
          "rufzeichen",
          "ort",
          "locator",
          "lat",
          "lon",
          "betreiber",
          "betreiber_art",
          "status",
          "status_text",
          "sicherheit",
          "stand",
          "kanaele",
          "quellen",
          "ort_kurz"
        ]
      },
      "KartenKanal": {
        "type": "object",
        "required": [
          "band",
          "ausgabe_mhz",
          "ablage_mhz",
          "betriebsarten"
        ],
        "properties": {
          "band": {
            "type": "string"
          },
          "ausgabe_mhz": {
            "type": "number"
          },
          "ablage_mhz": {
            "type": "number",
            "nullable": true
          },
          "betriebsarten": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "KartenPunkt": {
        "type": "object",
        "description": "Kurzform eines Relais mit Kartenpunkt",
        "required": [
          "id",
          "rufzeichen",
          "ort",
          "ort_kurz",
          "locator",
          "lat",
          "lon",
          "status",
          "status_text",
          "sicherheit",
          "kanaele"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "rufzeichen": {
            "type": "string"
          },
          "ort": {
            "type": "string",
            "nullable": true
          },
          "ort_kurz": {
            "type": "string",
            "nullable": true,
            "description": "Ort für die Anzeige, ohne Zusätze"
          },
          "locator": {
            "type": "string"
          },
          "lat": {
            "type": "number",
            "description": "Mitte des Locators"
          },
          "lon": {
            "type": "number",
            "description": "Mitte des Locators"
          },
          "status": {
            "type": "string",
            "enum": [
              "aktuell_dokumentiert",
              "frequenz_dokumentiert",
              "aeltere_dokumentation",
              "ausser_betrieb"
            ]
          },
          "status_text": {
            "type": "string"
          },
          "sicherheit": {
            "type": "string",
            "enum": [
              "hoch",
              "mittel",
              "gering"
            ]
          },
          "kanaele": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KartenKanal"
            }
          }
        }
      },
      "Sammelpunkt": {
        "type": "object",
        "description": "Rasterzelle mit mehreren Treffern, ohne einzelne Relais",
        "required": [
          "lat",
          "lon",
          "anzahl",
          "status",
          "rahmen"
        ],
        "properties": {
          "lat": {
            "type": "number",
            "description": "Schwerpunkt der Treffer, auf die halbe Zelle vergröbert"
          },
          "lon": {
            "type": "number",
            "description": "Schwerpunkt der Treffer, auf die halbe Zelle vergröbert"
          },
          "anzahl": {
            "type": "integer",
            "minimum": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "aktuell_dokumentiert",
              "frequenz_dokumentiert",
              "aeltere_dokumentation",
              "ausser_betrieb"
            ],
            "description": "Häufigster Status der Zelle"
          },
          "rahmen": {
            "$ref": "#/components/schemas/Rahmen"
          }
        }
      },
      "Rahmen": {
        "type": "array",
        "description": "süd, west, nord, ost",
        "items": {
          "type": "number"
        },
        "minItems": 4,
        "maxItems": 4
      },
      "Karte": {
        "type": "object",
        "required": [
          "meta",
          "art",
          "treffer",
          "gesamt",
          "rahmen",
          "punkte",
          "sammel"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "art": {
            "type": "string",
            "enum": [
              "punkte",
              "sammel"
            ],
            "description": "punkte: Einzelpunkte in `punkte`. sammel: mehr als 100 Treffer, Sammelpunkte in `sammel`"
          },
          "treffer": {
            "type": "integer",
            "description": "Treffer im Ausschnitt"
          },
          "gesamt": {
            "type": "integer",
            "description": "Treffer des Filters mit Standort, auch außerhalb des Ausschnitts"
          },
          "rahmen": {
            "type": "array",
            "description": "Rahmen um alle Treffer des Filters: süd, west, nord, ost. Leer ohne Treffer",
            "items": {
              "type": "number"
            },
            "minItems": 4,
            "maxItems": 4,
            "nullable": true
          },
          "punkte": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/KartenPunkt"
            }
          },
          "sammel": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sammelpunkt"
            }
          }
        }
      },
      "CockpitZeile": {
        "type": "object",
        "description": "Ein nutzbarer Kanal",
        "required": [
          "ruf",
          "band",
          "mhz",
          "ein_mhz",
          "ablage_mhz",
          "crossband",
          "sonderablage",
          "betriebsarten",
          "netze",
          "ton",
          "ort",
          "locator",
          "lat",
          "lon",
          "status_text",
          "stand"
        ],
        "properties": {
          "ruf": {
            "type": "string",
            "description": "Rufzeichen"
          },
          "band": {
            "type": "string"
          },
          "mhz": {
            "type": "number",
            "description": "Ausgabe"
          },
          "ein_mhz": {
            "type": "number",
            "nullable": true,
            "description": "Eingabe, leer ohne Beleg"
          },
          "ablage_mhz": {
            "type": "number",
            "nullable": true
          },
          "crossband": {
            "type": "boolean"
          },
          "sonderablage": {
            "type": "boolean"
          },
          "betriebsarten": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "netze": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ton": {
            "type": "string",
            "description": "Einstellung in Worten, leer ohne Beleg"
          },
          "ort": {
            "type": "string",
            "nullable": true
          },
          "locator": {
            "type": "string"
          },
          "lat": {
            "type": "number",
            "description": "Mitte des Locators"
          },
          "lon": {
            "type": "number",
            "description": "Mitte des Locators"
          },
          "status_text": {
            "type": "string"
          },
          "stand": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Cockpit": {
        "type": "object",
        "required": [
          "meta",
          "radius_km",
          "begrenzt",
          "relais"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "radius_km": {
            "type": "number"
          },
          "begrenzt": {
            "type": "boolean",
            "description": "Wahr, wenn im Umkreis mehr als 200 Zeilen liegen. Die Antwort enthält dann nur die 200 nächsten"
          },
          "relais": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/CockpitZeile"
            }
          }
        }
      },
      "Ort": {
        "type": "object",
        "description": "`lat`, `lon` und `name` bei art ort und bestand, `namen` bei mehrdeutig, `hinweis` immer dann, wenn es keinen Mittelpunkt gibt",
        "required": [
          "art",
          "hinweis"
        ],
        "properties": {
          "art": {
            "type": "string",
            "enum": [
              "ort",
              "bestand",
              "mehrdeutig",
              "ohne_punkt",
              "unbekannt"
            ],
            "description": "ort: aus der Ortsliste. bestand: aus einem Relais im Verzeichnis. mehrdeutig: mehrere Orte passen. ohne_punkt: Relais an diesem Ort, aber ohne belegten Standort. unbekannt: kein Treffer"
          },
          "lat": {
            "type": "number",
            "description": "Mittelpunkt des Orts"
          },
          "lon": {
            "type": "number",
            "description": "Mittelpunkt des Orts"
          },
          "name": {
            "type": "string"
          },
          "namen": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 4
          },
          "hinweis": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Treffer": {
        "type": "object",
        "required": [
          "meta",
          "treffer",
          "mit_standort",
          "seite",
          "pro_seite",
          "seiten",
          "relais"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "treffer": {
            "type": "integer",
            "description": "Alle Treffer, auch hinter Treffer 200"
          },
          "mit_standort": {
            "type": "integer",
            "description": "Treffer mit Kartenpunkt"
          },
          "seite": {
            "type": "integer"
          },
          "pro_seite": {
            "type": "integer"
          },
          "seiten": {
            "type": "integer",
            "description": "Lesbare Seiten bis Treffer 200"
          },
          "relais": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Relais"
            }
          }
        }
      },
      "Umkreis": {
        "type": "object",
        "required": [
          "meta",
          "radius_km",
          "ohne_standort",
          "treffer",
          "mit_standort",
          "seite",
          "pro_seite",
          "seiten",
          "relais"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "radius_km": {
            "type": "number"
          },
          "ohne_standort": {
            "type": "integer",
            "description": "Relais zum Filter, die mangels Standort nicht geprüft wurden"
          },
          "treffer": {
            "type": "integer",
            "description": "Alle Treffer, auch hinter Treffer 200"
          },
          "mit_standort": {
            "type": "integer",
            "description": "Treffer mit Kartenpunkt"
          },
          "seite": {
            "type": "integer"
          },
          "pro_seite": {
            "type": "integer"
          },
          "seiten": {
            "type": "integer",
            "description": "Lesbare Seiten bis Treffer 200"
          },
          "relais": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Relais"
            }
          }
        }
      },
      "EinRelais": {
        "type": "object",
        "required": [
          "meta",
          "relais"
        ],
        "properties": {
          "meta": {
            "$ref": "#/components/schemas/Meta"
          },
          "relais": {
            "$ref": "#/components/schemas/Relais"
          }
        }
      }
    },
    "responses": {
      "Unveraendert": {
        "description": "Unverändert seit `If-None-Match`, ohne Inhalt",
        "headers": {
          "ETag": {
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "Eingabefehler": {
        "description": "Ungültige Eingabe, `feld` nennt den Parameter",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Fehler"
            }
          }
        }
      },
      "NichtGefunden": {
        "description": "Nicht gefunden",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Fehler"
            }
          }
        }
      },
      "ZuViele": {
        "description": "Grenze erreicht",
        "headers": {
          "Retry-After": {
            "description": "Sekunden bis zum nächsten Zeitfenster",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Fehler"
            }
          }
        }
      }
    }
  }
}
