{
 "openapi": "3.1.0",
 "info": {
  "title": "IPv64.net API",
  "version": "2.0.0",
  "description": "RESTful JSON-API für DynDNS, DNS, Healthchecks, DNS-Failover, CDN, Cloud Router und DNS64 von IPv64.net. Anmeldung mit einem API-Key aus dem Menü Account > API. Die ausführliche Anleitung steht unter https://ipv64.net/api/v2/docs.",
  "contact": {
   "name": "IPv64.net",
   "url": "https://ipv64.net"
  }
 },
 "servers": [
  {
   "url": "https://ipv64.net/api/v2",
   "description": "Produktion"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  },
  {
   "apiKeyHeader": []
  }
 ],
 "tags": [
  {
   "name": "Meta",
   "description": "Öffentliche Endpunkte ohne Anmeldung."
  },
  {
   "name": "Account",
   "description": "Account, Nutzung, Logs und Account-Freigaben."
  },
  {
   "name": "API-Keys",
   "description": "Dieselben Keys wie im Menü Account > API."
  },
  {
   "name": "Domains",
   "description": "DynDNS-Domains und eigene Domains. Überall, wo {domain} steht, geht die ID oder der vollständige Name."
  },
  {
   "name": "DynDNS",
   "description": "IP-Updates über die API. Für Router und einfache Geräte bleibt update.php der richtige Weg."
  },
  {
   "name": "DNS-Records",
   "description": "Records einer Domain. {record} ist die ID oder der Record-Token."
  },
  {
   "name": "Healthchecks",
   "description": "Push-Checks (dein System meldet sich) und aktive Checks (ICMP, TCP, HTTP, Keyword). {token} ist der Healthcheck-Token."
  },
  {
   "name": "Benachrichtigungen",
   "description": "Integrationen für Healthchecks und DNS-Failover. Die ID 0 steht immer für die E-Mail-Adresse des Accounts."
  },
  {
   "name": "DNS-Failover",
   "description": "Policies schalten Records automatisch auf ein Ersatzziel, wenn Healthchecks ausfallen. {id} ist die Policy-ID."
  },
  {
   "name": "Statusseiten",
   "description": "Öffentliche Statusseiten unter https://ipv64.net/status/<slug>."
  },
  {
   "name": "Offline-Pages",
   "description": "Eigene Wartungsseiten als Ziel für den DNS-Failover. {id} ist die Offline-Page-ID."
  },
  {
   "name": "CDN",
   "description": "Reverse Proxy und Portmapper. {token} ist die CDN-ID. Viele Änderungen setzt der CDN-Dienst im Hintergrund um, die Antwort ist dann 202 und pending zeigt den Fortschritt."
  },
  {
   "name": "Cloud Router",
   "description": "WireGuard-Router mit Gateways, Routing, Firewall und öffentlichen IPv6-Adressen. Fast alle Änderungen setzt der VPN-Dienst im Hintergrund um (202)."
  },
  {
   "name": "Gateways",
   "description": "WireGuard-Gateways eines Cloud Routers. {token} ist die Gateway-ID. Während ein Gateway eingerichtet wird, antworten Änderungen mit 409 gateway_busy und retry_after."
  },
  {
   "name": "Peers",
   "description": "WireGuard-Peers. {token} ist die Peer-ID."
  },
  {
   "name": "DNS64",
   "description": "Persönliche DNS-Resolver mit DNS64, DoH, DoT, DoQ und Blocklisten. {token} ist die Client-ID."
  }
 ],
 "paths": {
  "/": {
   "get": {
    "tags": [
     "Meta"
    ],
    "summary": "API-Info",
    "operationId": "get",
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "name": {
             "type": "string",
             "description": "Name",
             "example": "IPv64.net API"
            },
            "version": {
             "type": "string",
             "description": "Version",
             "example": "2.0.0"
            },
            "documentation": {
             "type": "string",
             "description": "Doku",
             "example": "https://ipv64.net/api/v2/docs"
            },
            "time": {
             "type": "string",
             "description": "Serverzeit",
             "format": "date-time",
             "example": "2026-10-10T12:00:00+02:00"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     }
    },
    "security": []
   }
  },
  "/health": {
   "get": {
    "tags": [
     "Meta"
    ],
    "summary": "Verfügbarkeit der API",
    "operationId": "get_health",
    "description": "Prüft auch die Datenbankverbindung. Geeignet für Monitoring.",
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "status": {
             "type": "string",
             "description": "Status",
             "example": "ok"
            },
            "version": {
             "type": "string",
             "description": "Version",
             "example": "2.0.0"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     }
    },
    "security": []
   }
  },
  "/ip": {
   "get": {
    "tags": [
     "Meta"
    ],
    "summary": "Eigene öffentliche IP",
    "operationId": "get_ip",
    "description": "Liefert die Adresse, mit der du die API erreichst.",
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "ip": {
             "type": "string",
             "description": "IP-Adresse",
             "example": "203.0.113.10"
            },
            "family": {
             "type": "string",
             "description": "Familie",
             "enum": [
              "ipv4",
              "ipv6"
             ],
             "example": "ipv4"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     }
    },
    "security": []
   }
  },
  "/openapi.json": {
   "get": {
    "tags": [
     "Meta"
    ],
    "summary": "Diese Beschreibung als OpenAPI 3.1",
    "operationId": "get_openapi.json",
    "description": "Zum Import in Postman, Insomnia, Bruno oder für Code-Generatoren.",
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "description": "OpenAPI-Dokument (ohne data-Hülle)"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     }
    },
    "security": []
   }
  },
  "/me": {
   "get": {
    "tags": [
     "Account"
    ],
    "summary": "Account und Nutzung",
    "operationId": "get_me",
    "description": "Zeigt Paket, Verbrauch und Limits sowie die verwendete Anmeldung.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Me"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me/logs": {
   "get": {
    "tags": [
     "Account"
    ],
    "summary": "Account-Log",
    "operationId": "get_me_logs",
    "description": "Neueste Einträge zuerst. Zum Weiterblättern meta.next_before als before übergeben. Es werden nur Einträge innerhalb der Aufbewahrungszeit des Pakets geliefert.",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Anzahl (1 bis 500)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 500,
       "default": 50
      }
     },
     {
      "name": "before",
      "in": "query",
      "required": false,
      "description": "Nur Einträge mit kleinerer ID (Cursor)",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "since",
      "in": "query",
      "required": false,
      "description": "Nur Einträge ab diesem Zeitpunkt (ISO 8601)",
      "schema": {
       "type": "string",
       "format": "date-time"
      },
      "example": "2026-10-01T00:00:00+02:00"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/LogEntry"
           }
          },
          "meta": {
           "type": "object",
           "properties": {
            "limit": {
             "type": "integer",
             "description": "Limit",
             "example": 50
            },
            "next_before": {
             "type": [
              "integer",
              "null"
             ],
             "description": "Cursor für die nächste Seite, null = Ende",
             "example": 83448900
            },
            "retention_days": {
             "type": "integer",
             "description": "Aufbewahrung",
             "example": 90
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/me/account-links": {
   "get": {
    "tags": [
     "Account"
    ],
    "summary": "Account-Freigaben",
    "operationId": "get_me_account_links",
    "description": "shared_with: wer deinen Account verwalten darf. managed: welche Accounts du verwalten darfst. Mit dem Header X-IPv64-Act-As handelst du für einen verwalteten Account.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "shared_with": {
             "type": "array",
             "items": {
              "$ref": "#/components/schemas/AccountLink"
             }
            },
            "managed": {
             "type": "array",
             "items": {
              "$ref": "#/components/schemas/AccountLink"
             }
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/api-keys": {
   "get": {
    "tags": [
     "API-Keys"
    ],
    "summary": "Alle API-Keys",
    "operationId": "get_api_keys",
    "description": "Die Keys selbst werden nie wieder angezeigt, nur Anfang und Ende.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/ApiKey"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "API-Keys"
    ],
    "summary": "API-Key anlegen",
    "operationId": "post_api_keys",
    "description": "Der vollständige Key steht nur in dieser Antwort.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Backup-Server"
         },
         "expires_in": {
          "type": "integer",
          "description": "Gültigkeit in Sekunden, 0 = unbegrenzt",
          "minimum": 0,
          "maximum": 315360000,
          "example": 2592000
         }
        }
       },
       "example": {
        "name": "Backup-Server",
        "expires_in": 2592000
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/ApiKeyCreated"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/api-keys/{id}": {
   "delete": {
    "tags": [
     "API-Keys"
    ],
    "summary": "API-Key löschen",
    "operationId": "delete_api_keys_id",
    "description": "Der Key, mit dem du gerade angemeldet bist, kann sich nicht selbst löschen.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains": {
   "get": {
    "tags": [
     "Domains"
    ],
    "summary": "Alle Domains",
    "operationId": "get_domains",
    "parameters": [
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "description": "Nur DynDNS- oder nur eigene Domains",
      "schema": {
       "type": "string",
       "enum": [
        "dyndns",
        "own"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Domain"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Domains"
    ],
    "summary": "Domain anlegen",
    "operationId": "post_domains",
    "description": "DynDNS-Domain: name als <wunschname>.<zone>, Zonen: ipv64.net, ipv64.de, any64.de, api64.de, dns64.de, dyndns64.de, dynipv6.de, eth64.de, home64.de, iot64.de, lan64.de, nas64.de, root64.de, route64.de, srv64.de, tcp64.de, udp64.de, vpn64.de, wan64.de. Eigene Domain: own auf true setzen und danach die Nameserver ns1.ipv64.net und ns2.ipv64.net beim Registrar eintragen. Die Limits deines Pakets gelten.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Domainname",
          "example": "meinname.ipv64.de"
         },
         "own": {
          "type": "boolean",
          "description": "Eigene Domain statt DynDNS",
          "example": false
         }
        },
        "required": [
         "name"
        ]
       },
       "example": {
        "name": "meinname.ipv64.de"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/DomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/{domain}": {
   "get": {
    "tags": [
     "Domains"
    ],
    "summary": "Domain mit Records",
    "operationId": "get_domains_domain",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/DomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Domains"
    ],
    "summary": "Domain-Einstellungen ändern",
    "operationId": "patch_domains_domain",
    "description": "Nur mitgeschickte Felder werden geändert.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "wildcard": {
          "type": "boolean",
          "description": "Wildcard *.name an oder aus",
          "example": true
         },
         "ignore": {
          "type": "string",
          "description": "Adressfamilie bei DynDNS-Updates ignorieren",
          "enum": [
           "none",
           "ipv4",
           "ipv6"
          ],
          "example": "none"
         },
         "ipv6_prefix": {
          "type": "string",
          "description": "Fester IPv6-Präfix wie 2001:db8:1234:5600::/56, leer = aus",
          "example": "2001:db8:1234:5600::/56"
         }
        }
       },
       "example": {
        "wildcard": true,
        "ignore": "none"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/DomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Domains"
    ],
    "summary": "Domain löschen",
    "operationId": "delete_domains_domain",
    "description": "Löscht die Domain mit allen Records. Nicht möglich, solange ein DNS-Failover aktiv ist.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/{domain}/rotate-token": {
   "post": {
    "tags": [
     "Domains"
    ],
    "summary": "Neuen Domain-Update-Token erzeugen",
    "operationId": "post_domains_domain_rotate_token",
    "description": "Der alte Token für update.php ist sofort ungültig.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Domain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/{domain}/reset": {
   "post": {
    "tags": [
     "Domains"
    ],
    "summary": "Domain zurücksetzen",
    "operationId": "post_domains_domain_reset",
    "description": "Löscht alle aktiven Records und setzt die Zone neu auf.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/DomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/{domain}/dyndns": {
   "post": {
    "tags": [
     "DynDNS"
    ],
    "summary": "IP aktualisieren",
    "operationId": "post_domains_domain_dyndns",
    "description": "Setzt A- und AAAA-Records einer Domain oder eines Präfixes. Ohne ipv4 und ipv6 wird die Absenderadresse verwendet. Nur öffentliche Adressen sind erlaubt. Fehlende Records werden angelegt. Das Update zählt in der Statistik, ist über die API aber nicht durch das Tageslimit begrenzt.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "ipv4": {
          "type": "string",
          "description": "IPv4-Adresse",
          "example": "203.0.113.10"
         },
         "ipv6": {
          "type": "string",
          "description": "IPv6-Adresse",
          "example": "2001:db8::10"
         },
         "prefix": {
          "type": "string",
          "description": "Präfix, leer = Domain selbst",
          "example": "nas"
         }
        }
       },
       "example": {
        "ipv4": "203.0.113.10",
        "ipv6": "2001:db8::10"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/DynDnsResult"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/domains/{domain}/records": {
   "get": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Records einer Domain",
    "operationId": "get_domains_domain_records",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "name": "type",
      "in": "query",
      "required": false,
      "description": "Nur dieser Typ",
      "schema": {
       "type": "string",
       "enum": [
        "A",
        "AAAA",
        "CNAME",
        "MX",
        "TXT",
        "NS",
        "SRV",
        "TLSA",
        "CAA"
       ]
      }
     },
     {
      "name": "prefix",
      "in": "query",
      "required": false,
      "description": "Nur dieser Präfix",
      "schema": {
       "type": "string"
      },
      "example": "_acme-challenge"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Record"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Record anlegen",
    "operationId": "post_domains_domain_records",
    "description": "TTL ist fest 60 Sekunden. Formate je Typ wie in der Weboberfläche, zum Beispiel MX als \"10 mail.example.com\".",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "Typ",
          "enum": [
           "A",
           "AAAA",
           "CNAME",
           "MX",
           "TXT",
           "NS",
           "SRV",
           "TLSA",
           "CAA"
          ],
          "example": "TXT"
         },
         "prefix": {
          "type": "string",
          "description": "Präfix, leer oder @ = Domain selbst",
          "example": "_acme-challenge"
         },
         "content": {
          "type": "string",
          "description": "Inhalt",
          "example": "abc123"
         }
        },
        "required": [
         "type",
         "content"
        ]
       },
       "example": {
        "type": "TXT",
        "prefix": "_acme-challenge",
        "content": "gfj9Xq...Rg85nM"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Record"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Record nach Inhalt löschen",
    "operationId": "delete_domains_domain_records",
    "description": "Praktisch für ACME-Clients: löscht den Record mit genau diesem Typ, Präfix und Inhalt.",
    "parameters": [
     {
      "name": "domain",
      "in": "path",
      "required": true,
      "description": "Domain-ID oder vollständiger Name, z. B. beispiel.ipv64.de",
      "schema": {
       "type": "string"
      },
      "example": "beispiel.ipv64.de"
     },
     {
      "name": "type",
      "in": "query",
      "required": true,
      "description": "Typ",
      "schema": {
       "type": "string",
       "enum": [
        "A",
        "AAAA",
        "CNAME",
        "MX",
        "TXT",
        "NS",
        "SRV",
        "TLSA",
        "CAA"
       ]
      },
      "example": "TXT"
     },
     {
      "name": "content",
      "in": "query",
      "required": true,
      "description": "Inhalt",
      "schema": {
       "type": "string"
      },
      "example": "gfj9Xq...Rg85nM"
     },
     {
      "name": "prefix",
      "in": "query",
      "required": false,
      "description": "Präfix",
      "schema": {
       "type": "string"
      },
      "example": "_acme-challenge"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/records/{record}": {
   "get": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Einzelner Record",
    "operationId": "get_records_record",
    "parameters": [
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Record"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Record ändern",
    "operationId": "patch_records_record",
    "description": "Ändert sich nur die IP eines A- oder AAAA-Records, bleiben ID und Token erhalten. Bei anderen Änderungen wird der Record ersetzt und bekommt eine neue ID und einen neuen Token. Records, die vom CDN oder DNS-Failover verwaltet werden, sind gesperrt.",
    "parameters": [
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "Typ",
          "enum": [
           "A",
           "AAAA",
           "CNAME",
           "MX",
           "TXT",
           "NS",
           "SRV",
           "TLSA",
           "CAA"
          ],
          "example": "A"
         },
         "prefix": {
          "type": "string",
          "description": "Präfix",
          "example": "nas"
         },
         "content": {
          "type": "string",
          "description": "Inhalt",
          "example": "203.0.113.20"
         }
        }
       },
       "example": {
        "content": "203.0.113.20"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Record"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "DNS-Records"
    ],
    "summary": "Record löschen",
    "operationId": "delete_records_record",
    "parameters": [
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks": {
   "get": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Alle Healthchecks",
    "operationId": "get_healthchecks",
    "parameters": [
     {
      "name": "type",
      "in": "query",
      "required": false,
      "description": "Nur diese Art",
      "schema": {
       "type": "string",
       "enum": [
        "push",
        "icmp",
        "tcp",
        "http",
        "keyword"
       ]
      }
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Nur dieser Status",
      "schema": {
       "type": "string",
       "enum": [
        "new",
        "up",
        "paused",
        "warning",
        "down",
        "stabilizing"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Healthcheck"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Healthcheck anlegen",
    "operationId": "post_healthchecks",
    "description": "Push-Check: Danach push.url aus der Antwort regelmäßig aufrufen. Aktive Checks: target bzw. url ist Pflicht.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Backup NAS"
         },
         "type": {
          "type": "string",
          "description": "Art. Erlaubt sind auch die Namen der Weboberfläche: health, ping, web.",
          "enum": [
           "push",
           "icmp",
           "tcp",
           "http",
           "keyword"
          ],
          "example": "push"
         },
         "integrations": {
          "type": "array",
          "items": {
           "type": "integer",
           "example": 0
          },
          "description": "Integrationen für Benachrichtigungen, 0 = Account-E-Mail"
         },
         "notify_on_down": {
          "type": "boolean",
          "description": "Bei DOWN benachrichtigen",
          "example": true
         },
         "notify_on_up": {
          "type": "boolean",
          "description": "Bei UP benachrichtigen",
          "example": true
         },
         "period_seconds": {
          "type": "integer",
          "description": "push: erwarteter Abstand der Pings. Ganze Minuten, Stunden oder Tage.",
          "minimum": 60,
          "example": 3600
         },
         "grace_seconds": {
          "type": "integer",
          "description": "push: Kulanzzeit nach Ablauf der Periode. Ganze Minuten, Stunden oder Tage.",
          "minimum": 60,
          "example": 600
         },
         "target": {
          "type": "string",
          "description": "icmp und tcp: Hostname oder IP",
          "example": "nas.beispiel.ipv64.de"
         },
         "prefer_ipv4": {
          "type": "boolean",
          "description": "icmp und tcp: IPv4 bevorzugen",
          "example": false
         },
         "port": {
          "type": "integer",
          "description": "tcp: Port",
          "minimum": 1,
          "maximum": 65535,
          "example": 443
         },
         "url": {
          "type": "string",
          "description": "http und keyword: URL",
          "example": "https://example.com/health"
         },
         "verify_tls": {
          "type": "boolean",
          "description": "http und keyword: Zertifikat prüfen",
          "example": true
         },
         "keyword": {
          "type": "string",
          "description": "keyword: Text, der auf der Seite stehen muss",
          "example": "OK"
         },
         "interval_seconds": {
          "type": "integer",
          "description": "Aktive Checks: Prüfintervall. Free-Paket mindestens 120 Sekunden.",
          "minimum": 1,
          "maximum": 86400,
          "example": 300
         },
         "retry_interval_seconds": {
          "type": "integer",
          "description": "Aktive Checks: Intervall nach einem Fehler, mindestens 10 Sekunden",
          "minimum": 1,
          "maximum": 86400,
          "example": 60
         },
         "failures_before_alarm": {
          "type": "integer",
          "description": "Aktive Checks: Fehlschläge bis zum Alarm",
          "minimum": 1,
          "maximum": 60,
          "example": 3
         }
        },
        "required": [
         "name"
        ]
       },
       "example": {
        "name": "Webseite",
        "type": "http",
        "url": "https://example.com/",
        "interval_seconds": 300,
        "integrations": [
         0
        ]
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/HealthcheckDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}": {
   "get": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Healthcheck mit den letzten Events",
    "operationId": "get_healthchecks_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/HealthcheckDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Healthcheck ändern",
    "operationId": "patch_healthchecks_token",
    "description": "Nur mitgeschickte Felder werden geändert. Ein Wechsel von type setzt die Prüf-Einstellungen zurück.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Backup NAS"
         },
         "type": {
          "type": "string",
          "description": "Art. Erlaubt sind auch die Namen der Weboberfläche: health, ping, web.",
          "enum": [
           "push",
           "icmp",
           "tcp",
           "http",
           "keyword"
          ],
          "example": "push"
         },
         "integrations": {
          "type": "array",
          "items": {
           "type": "integer",
           "example": 0
          },
          "description": "Integrationen für Benachrichtigungen, 0 = Account-E-Mail"
         },
         "notify_on_down": {
          "type": "boolean",
          "description": "Bei DOWN benachrichtigen",
          "example": true
         },
         "notify_on_up": {
          "type": "boolean",
          "description": "Bei UP benachrichtigen",
          "example": true
         },
         "period_seconds": {
          "type": "integer",
          "description": "push: erwarteter Abstand der Pings. Ganze Minuten, Stunden oder Tage.",
          "minimum": 60,
          "example": 3600
         },
         "grace_seconds": {
          "type": "integer",
          "description": "push: Kulanzzeit nach Ablauf der Periode. Ganze Minuten, Stunden oder Tage.",
          "minimum": 60,
          "example": 600
         },
         "target": {
          "type": "string",
          "description": "icmp und tcp: Hostname oder IP",
          "example": "nas.beispiel.ipv64.de"
         },
         "prefer_ipv4": {
          "type": "boolean",
          "description": "icmp und tcp: IPv4 bevorzugen",
          "example": false
         },
         "port": {
          "type": "integer",
          "description": "tcp: Port",
          "minimum": 1,
          "maximum": 65535,
          "example": 443
         },
         "url": {
          "type": "string",
          "description": "http und keyword: URL",
          "example": "https://example.com/health"
         },
         "verify_tls": {
          "type": "boolean",
          "description": "http und keyword: Zertifikat prüfen",
          "example": true
         },
         "keyword": {
          "type": "string",
          "description": "keyword: Text, der auf der Seite stehen muss",
          "example": "OK"
         },
         "interval_seconds": {
          "type": "integer",
          "description": "Aktive Checks: Prüfintervall. Free-Paket mindestens 120 Sekunden.",
          "minimum": 1,
          "maximum": 86400,
          "example": 300
         },
         "retry_interval_seconds": {
          "type": "integer",
          "description": "Aktive Checks: Intervall nach einem Fehler, mindestens 10 Sekunden",
          "minimum": 1,
          "maximum": 86400,
          "example": 60
         },
         "failures_before_alarm": {
          "type": "integer",
          "description": "Aktive Checks: Fehlschläge bis zum Alarm",
          "minimum": 1,
          "maximum": 60,
          "example": 3
         }
        }
       },
       "example": {
        "interval_seconds": 60,
        "failures_before_alarm": 2
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/HealthcheckDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Healthcheck löschen",
    "operationId": "delete_healthchecks_token",
    "description": "Nicht möglich, solange der Check einen aktiven DNS-Failover steuert.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/pause": {
   "post": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Pausieren",
    "operationId": "post_healthchecks_token_pause",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Healthcheck"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/resume": {
   "post": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Fortsetzen",
    "operationId": "post_healthchecks_token_resume",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Healthcheck"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/rotate-token": {
   "post": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Neuen Token erzeugen",
    "operationId": "post_healthchecks_token_rotate_token",
    "description": "Die Push-URL ändert sich dadurch. Events, Incidents und Failover-Monitore werden mitgenommen.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Healthcheck"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/events": {
   "get": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Events",
    "operationId": "get_healthchecks_token_events",
    "description": "Ohne Cursor die neuesten zuerst. Mit after werden ältere zuerst geliefert, ideal zum fortlaufenden Abholen neuer Events.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Anzahl (1 bis 1000)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 1000,
       "default": 100
      }
     },
     {
      "name": "before",
      "in": "query",
      "required": false,
      "description": "Nur Events mit kleinerer ID",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "after",
      "in": "query",
      "required": false,
      "description": "Nur Events mit größerer ID, aufsteigend sortiert",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "since",
      "in": "query",
      "required": false,
      "description": "Nur Events ab diesem Zeitpunkt (ISO 8601)",
      "schema": {
       "type": "string",
       "format": "date-time"
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/HealthcheckEvent"
           }
          },
          "meta": {
           "type": "object",
           "properties": {
            "limit": {
             "type": "integer",
             "description": "Limit",
             "example": 100
            },
            "has_more": {
             "type": "boolean",
             "description": "Weitere Events vorhanden",
             "example": false
            },
            "next_before": {
             "type": [
              "integer",
              "null"
             ],
             "description": "Cursor ohne after"
            },
            "next_after": {
             "type": [
              "integer",
              "null"
             ],
             "description": "Cursor mit after"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/incidents": {
   "get": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Incidents",
    "operationId": "get_healthchecks_token_incidents",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "Anzahl (1 bis 500)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 500,
       "default": 50
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Incident"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/stats": {
   "get": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Verfügbarkeit und Latenz",
    "operationId": "get_healthchecks_token_stats",
    "description": "Berechnet aus den gespeicherten Events, mit Zeitreihe.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "range",
      "in": "query",
      "required": false,
      "description": "Zeitraum",
      "schema": {
       "type": "string",
       "enum": [
        "1h",
        "24h",
        "7d",
        "30d"
       ],
       "default": "24h"
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/HealthcheckStats"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/healthchecks/{token}/test-notification": {
   "post": {
    "tags": [
     "Healthchecks"
    ],
    "summary": "Testnachricht senden",
    "operationId": "post_healthchecks_token_test_notification",
    "description": "An alle Integrationen des Checks. Höchstens eine pro 30 Sekunden.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "sent": {
             "type": "boolean",
             "description": "Gesendet",
             "example": true
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/integrations": {
   "get": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Alle Integrationen",
    "operationId": "get_integrations",
    "parameters": [
     {
      "name": "include_secrets",
      "in": "query",
      "required": false,
      "description": "Tokens und URLs vollständig anzeigen",
      "schema": {
       "type": "string",
       "enum": [
        "true",
        "false"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Integration"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Integration anlegen",
    "operationId": "post_integrations",
    "description": "Je nach type sind andere Felder nötig:\n\n- telegram: chat_id, api_token\n- gotify: server_url, app_token, priority (0 bis 10)\n- ntfy: server_url (inklusive Topic), priority_down und priority_up (1 bis 5)\n- pushover: user_token, app_token, device, priority (-2 bis 1)\n- discord: webhook_url, ping_user, ping_group\n- webhook: url_down und/oder url_up\n- email: email. Es wird ein Bestätigungslink verschickt.\n- sms: number (deutsche Mobilnummer), country_code 0049. Es wird ein Bestätigungslink per SMS verschickt.\n- app: device_token der IPv64-App\n\nURLs müssen mit http oder https beginnen und auf öffentliche Adressen zeigen. E-Mail- und SMS-Bestätigungen sind auf wenige pro Stunde begrenzt.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "type": {
          "type": "string",
          "description": "Art",
          "enum": [
           "telegram",
           "gotify",
           "ntfy",
           "pushover",
           "discord",
           "webhook",
           "email",
           "sms",
           "app"
          ],
          "example": "telegram"
         },
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Mein Telegram"
         },
         "default": {
          "type": "boolean",
          "description": "Bei neuen Healthchecks vorauswählen",
          "example": false
         },
         "chat_id": {
          "type": "string",
          "description": "telegram",
          "example": "123456789"
         },
         "api_token": {
          "type": "string",
          "description": "telegram: Bot-Token",
          "example": "123456:ABC-DEF"
         },
         "server_url": {
          "type": "string",
          "description": "gotify, ntfy",
          "example": "https://ntfy.sh/mein-topic"
         },
         "app_token": {
          "type": "string",
          "description": "gotify, pushover"
         },
         "user_token": {
          "type": "string",
          "description": "pushover"
         },
         "device": {
          "type": "string",
          "description": "pushover"
         },
         "priority": {
          "type": "integer",
          "description": "gotify (0 bis 10), pushover (-2 bis 1)"
         },
         "priority_down": {
          "type": "integer",
          "description": "ntfy (1 bis 5)",
          "example": 4
         },
         "priority_up": {
          "type": "integer",
          "description": "ntfy (1 bis 5)",
          "example": 3
         },
         "webhook_url": {
          "type": "string",
          "description": "discord"
         },
         "ping_user": {
          "type": "string",
          "description": "discord: User-ID"
         },
         "ping_group": {
          "type": "string",
          "description": "discord: Rollen-ID"
         },
         "url_down": {
          "type": "string",
          "description": "webhook: wird bei DOWN aufgerufen"
         },
         "url_up": {
          "type": "string",
          "description": "webhook: wird bei UP aufgerufen"
         },
         "email": {
          "type": "string",
          "description": "email",
          "example": "alarm@example.com"
         },
         "number": {
          "type": "string",
          "description": "sms",
          "example": "01701234567"
         },
         "country_code": {
          "type": "string",
          "description": "sms",
          "example": "0049"
         },
         "device_token": {
          "type": "string",
          "description": "app"
         }
        },
        "required": [
         "type",
         "name"
        ]
       },
       "example": {
        "type": "telegram",
        "name": "Mein Telegram",
        "chat_id": "123456789",
        "api_token": "123456:ABC-DEF"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Integration"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/integrations/{id}": {
   "get": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Einzelne Integration",
    "operationId": "get_integrations_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "name": "include_secrets",
      "in": "query",
      "required": false,
      "description": "Tokens und URLs vollständig anzeigen",
      "schema": {
       "type": "string",
       "enum": [
        "true",
        "false"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Integration"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/E400"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Name oder Vorauswahl ändern",
    "operationId": "patch_integrations_id",
    "description": "Für andere Änderungen die Integration neu anlegen.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Telegram Gruppe"
         },
         "default": {
          "type": "boolean",
          "description": "Vorauswahl",
          "example": true
         }
        }
       },
       "example": {
        "default": true
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Integration"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Integration löschen",
    "operationId": "delete_integrations_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/integrations/{id}/test": {
   "post": {
    "tags": [
     "Benachrichtigungen"
    ],
    "summary": "Testnachricht senden",
    "operationId": "post_integrations_id_test",
    "description": "Mit der ID 0 geht die Nachricht an die Account-E-Mail. Höchstens eine pro 30 Sekunden und Integration.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "sent": {
             "type": "boolean",
             "description": "Gesendet",
             "example": true
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies": {
   "get": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Alle Policies",
    "operationId": "get_failover_policies",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/FailoverPolicy"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Policy anlegen",
    "operationId": "post_failover_policies",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Webserver"
         },
         "mode": {
          "type": "string",
          "description": "Umschaltverhalten",
          "enum": [
           "auto_failover",
           "auto_failover_and_fallback",
           "manual"
          ],
          "example": "auto_failover"
         },
         "fallback_requires_all": {
          "type": "boolean",
          "description": "Rückschaltung erst, wenn alle Monitore UP sind",
          "example": false
         },
         "linking": {
          "type": "string",
          "description": "Verknüpfung der Monitore",
          "enum": [
           "and",
           "or"
          ],
          "example": "or"
         },
         "notifications_enabled": {
          "type": "boolean",
          "description": "Benachrichtigungen",
          "example": true
         },
         "integrations": {
          "type": "array",
          "items": {
           "type": "integer",
           "example": 0
          },
          "description": "Integrationen, 0 = Account-E-Mail"
         }
        }
       },
       "example": {
        "name": "Webserver",
        "mode": "auto_failover_and_fallback"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}": {
   "get": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Einzelne Policy",
    "operationId": "get_failover_policies_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Policy ändern",
    "operationId": "patch_failover_policies_id",
    "description": "linking kann während eines aktiven Failovers nicht geändert werden.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Webserver"
         },
         "mode": {
          "type": "string",
          "description": "Umschaltverhalten",
          "enum": [
           "auto_failover",
           "auto_failover_and_fallback",
           "manual"
          ],
          "example": "auto_failover"
         },
         "fallback_requires_all": {
          "type": "boolean",
          "description": "Rückschaltung erst, wenn alle Monitore UP sind",
          "example": false
         },
         "linking": {
          "type": "string",
          "description": "Verknüpfung der Monitore",
          "enum": [
           "and",
           "or"
          ],
          "example": "or"
         },
         "notifications_enabled": {
          "type": "boolean",
          "description": "Benachrichtigungen",
          "example": true
         },
         "integrations": {
          "type": "array",
          "items": {
           "type": "integer",
           "example": 0
          },
          "description": "Integrationen, 0 = Account-E-Mail"
         }
        }
       },
       "example": {
        "notifications_enabled": false
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Policy löschen",
    "operationId": "delete_failover_policies_id",
    "description": "Nicht möglich, solange der Failover aktiv ist.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/pause": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Pausieren",
    "operationId": "post_failover_policies_id_pause",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/resume": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Fortsetzen",
    "operationId": "post_failover_policies_id_resume",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/failover": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Manuell umschalten",
    "operationId": "post_failover_policies_id_failover",
    "description": "Nur im Status active.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/failover/policies/{id}/fallback": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Manuell zurückschalten",
    "operationId": "post_failover_policies_id_fallback",
    "description": "Nur im Status failed_over.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/failover/policies/{id}/monitors": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Monitor hinzufügen",
    "operationId": "post_failover_policies_id_monitors",
    "description": "Ein Healthcheck, der den Failover auslöst.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "healthcheck": {
          "type": "string",
          "description": "Healthcheck-Token",
          "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
         },
         "negate": {
          "type": "boolean",
          "description": "Umgekehrt werten",
          "example": false
         }
        },
        "required": [
         "healthcheck"
        ]
       },
       "example": {
        "healthcheck": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/monitors/{token}": {
   "delete": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Monitor entfernen",
    "operationId": "delete_failover_policies_id_monitors_token",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/rules": {
   "post": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Regel hinzufügen",
    "operationId": "post_failover_policies_id_rules",
    "description": "Schützt einen A- oder AAAA-Record. Als Ziel genau eines angeben: target_ip, target_record oder offline_page. Bei offline_page zeigt der Record im Failover auf die IPv64-Offline-Seite.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "record": {
          "type": "string",
          "description": "Record-ID oder -Token des geschützten Records",
          "example": "4711"
         },
         "target_ip": {
          "type": "string",
          "description": "Ersatz-IP derselben Familie",
          "example": "198.51.100.5"
         },
         "target_record": {
          "type": "string",
          "description": "Anderer eigener Record, dessen IP übernommen wird",
          "example": "4712"
         },
         "offline_page": {
          "type": "string",
          "description": "default oder Offline-Page-ID",
          "example": "default"
         }
        },
        "required": [
         "record"
        ]
       },
       "example": {
        "record": "4711",
        "target_ip": "198.51.100.5"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FailoverPolicy"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/failover/policies/{id}/rules/{record}": {
   "delete": {
    "tags": [
     "DNS-Failover"
    ],
    "summary": "Regel entfernen",
    "operationId": "delete_failover_policies_id_rules_record",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/status-pages": {
   "get": {
    "tags": [
     "Statusseiten"
    ],
    "summary": "Alle Statusseiten",
    "operationId": "get_status_pages",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/StatusPage"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Statusseiten"
    ],
    "summary": "Statusseite anlegen",
    "operationId": "post_status_pages",
    "description": "Ohne slug wird eine zufällige Adresse vergeben.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Titel",
          "example": "Mein Status"
         },
         "description": {
          "type": "string",
          "description": "Beschreibung"
         },
         "slug": {
          "type": "string",
          "description": "Adresse, 3 bis 128 Zeichen a-z, A-Z, 0-9",
          "example": "meinstatus"
         },
         "password": {
          "type": "string",
          "description": "Passwort, leer = öffentlich"
         },
         "design": {
          "type": "integer",
          "description": "Design",
          "minimum": 1,
          "maximum": 4,
          "example": 1
         },
         "autorefresh": {
          "type": "boolean",
          "description": "Automatisch neu laden",
          "example": true
         },
         "healthchecks": {
          "type": "array",
          "items": {
           "type": "string",
           "description": "Healthcheck-Token",
           "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
          },
          "description": "Angezeigte Healthchecks"
         }
        }
       },
       "example": {
        "name": "Mein Status",
        "healthchecks": [
         "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
        ]
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/StatusPage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/status-pages/{id}": {
   "get": {
    "tags": [
     "Statusseiten"
    ],
    "summary": "Einzelne Statusseite",
    "operationId": "get_status_pages_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/StatusPage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Statusseiten"
    ],
    "summary": "Statusseite ändern",
    "operationId": "patch_status_pages_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Titel",
          "example": "Mein Status"
         },
         "description": {
          "type": "string",
          "description": "Beschreibung"
         },
         "slug": {
          "type": "string",
          "description": "Adresse, 3 bis 128 Zeichen a-z, A-Z, 0-9",
          "example": "meinstatus"
         },
         "password": {
          "type": "string",
          "description": "Passwort, leer = öffentlich"
         },
         "design": {
          "type": "integer",
          "description": "Design",
          "minimum": 1,
          "maximum": 4,
          "example": 1
         },
         "autorefresh": {
          "type": "boolean",
          "description": "Automatisch neu laden",
          "example": true
         },
         "healthchecks": {
          "type": "array",
          "items": {
           "type": "string",
           "description": "Healthcheck-Token",
           "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
          },
          "description": "Angezeigte Healthchecks"
         }
        }
       },
       "example": {
        "slug": "meinstatus",
        "design": 2
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/StatusPage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Statusseiten"
    ],
    "summary": "Statusseite löschen",
    "operationId": "delete_status_pages_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/offline-pages": {
   "get": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Alle Offline-Pages",
    "operationId": "get_offline_pages",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/OfflinePage"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Offline-Page anlegen",
    "operationId": "post_offline_pages",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Überschrift",
          "example": "Wartungsarbeiten"
         },
         "domain": {
          "type": "string",
          "description": "Domain, für die die Seite gilt",
          "example": "www.example.com"
         },
         "email": {
          "type": "string",
          "description": "Kontakt-E-Mail"
         },
         "phone": {
          "type": "string",
          "description": "Telefon, Ziffern und optional führendes +"
         },
         "alternative_url": {
          "type": "string",
          "description": "Ausweichadresse"
         },
         "text": {
          "type": "string",
          "description": "Text. Zeilenumbrüche bleiben erhalten, HTML wird maskiert."
         }
        }
       },
       "example": {
        "name": "Wartungsarbeiten",
        "domain": "www.example.com",
        "text": "Wir sind gleich wieder da."
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/OfflinePage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/offline-pages/{id}": {
   "get": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Einzelne Offline-Page",
    "operationId": "get_offline_pages_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/OfflinePage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Offline-Page ändern",
    "operationId": "patch_offline_pages_id",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Überschrift",
          "example": "Wartungsarbeiten"
         },
         "domain": {
          "type": "string",
          "description": "Domain, für die die Seite gilt",
          "example": "www.example.com"
         },
         "email": {
          "type": "string",
          "description": "Kontakt-E-Mail"
         },
         "phone": {
          "type": "string",
          "description": "Telefon, Ziffern und optional führendes +"
         },
         "alternative_url": {
          "type": "string",
          "description": "Ausweichadresse"
         },
         "text": {
          "type": "string",
          "description": "Text. Zeilenumbrüche bleiben erhalten, HTML wird maskiert."
         }
        }
       },
       "example": {
        "text": "Wartung bis 14 Uhr."
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/OfflinePage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Offline-Page löschen",
    "operationId": "delete_offline_pages_id",
    "description": "Nicht möglich, solange eine Failover-Regel sie nutzt.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/offline-pages/{id}/icon": {
   "post": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Logo hochladen",
    "operationId": "post_offline_pages_id_icon",
    "description": "Als multipart/form-data im Feld icon. JPEG, PNG oder WebP, höchstens 1 MB und 1024 x 1024 Pixel.",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "icon": {
          "type": "string",
          "description": "Bilddatei",
          "format": "binary"
         }
        },
        "required": [
         "icon"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/OfflinePage"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "413": {
      "$ref": "#/components/responses/E413"
     },
     "415": {
      "$ref": "#/components/responses/E415"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Offline-Pages"
    ],
    "summary": "Logo löschen",
    "operationId": "delete_offline_pages_id_icon",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn": {
   "get": {
    "tags": [
     "CDN"
    ],
    "summary": "Alle CDN-Domains",
    "operationId": "get_cdn",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/CdnDomain"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Domain ins CDN aufnehmen",
    "operationId": "post_cdn",
    "description": "Danach wird automatisch ein CDN-Server zugewiesen.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domain": {
          "type": "string",
          "description": "Domain-ID oder Name",
          "example": "beispiel.ipv64.de"
         }
        },
        "required": [
         "domain"
        ]
       },
       "example": {
        "domain": "beispiel.ipv64.de"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}": {
   "get": {
    "tags": [
     "CDN"
    ],
    "summary": "CDN-Domain mit Mappings",
    "operationId": "get_cdn_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "CDN"
    ],
    "summary": "Proxy-Einstellungen ändern",
    "operationId": "patch_cdn_token",
    "description": "Nur mitgeschickte Felder werden geändert. HTTPS im Frontend stösst automatisch ein Let's-Encrypt-Zertifikat an.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "frontend": {
          "type": "string",
          "description": "Frontend",
          "enum": [
           "http",
           "https_redirect",
           "http_and_https"
          ],
          "example": "https_redirect"
         },
         "backend_scheme": {
          "type": "string",
          "description": "Protokoll zu deinem Server",
          "enum": [
           "http",
           "https"
          ],
          "example": "http"
         },
         "backend_port": {
          "type": "integer",
          "description": "Port deines Servers",
          "minimum": 1,
          "maximum": 65535,
          "example": 8080
         },
         "websocket": {
          "type": "boolean",
          "description": "WebSocket, nur bei aktivem Proxy",
          "example": false
         },
         "caching": {
          "type": "object",
          "properties": {
           "enabled": {
            "type": "boolean",
            "description": "Cache"
           },
           "time_minutes": {
            "type": "integer",
            "description": "1 bis 600"
           },
           "size_mb": {
            "type": "integer",
            "description": "1 bis Paketlimit"
           }
          }
         },
         "access_list": {
          "type": "object",
          "properties": {
           "enabled": {
            "type": "boolean",
            "description": "Zugriffsliste"
           },
           "mode": {
            "type": "string",
            "description": "allowlist oder denylist",
            "enum": [
             "allowlist",
             "denylist"
            ]
           }
          }
         }
        }
       },
       "example": {
        "frontend": "https_redirect",
        "backend_port": 8080,
        "caching": {
         "enabled": true,
         "time_minutes": 60,
         "size_mb": 100
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomainDetail"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "CDN"
    ],
    "summary": "Domain aus dem CDN entfernen",
    "operationId": "delete_cdn_token",
    "description": "Vorher das CDN für alle Records abschalten.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/proxy/enable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Reverse Proxy einschalten",
    "operationId": "post_cdn_token_proxy_enable",
    "description": "Mindestens ein Record muss über das CDN laufen.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/proxy/disable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Reverse Proxy ausschalten",
    "operationId": "post_cdn_token_proxy_disable",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/portmapper/enable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Portmapper einschalten",
    "operationId": "post_cdn_token_portmapper_enable",
    "description": "Mindestens ein Record muss über das CDN laufen.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/portmapper/disable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Portmapper ausschalten",
    "operationId": "post_cdn_token_portmapper_disable",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/redeploy": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Konfiguration neu ausrollen",
    "operationId": "post_cdn_token_redeploy",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/reset-traffic": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Traffic-Zähler der Domain zurücksetzen",
    "operationId": "post_cdn_token_reset_traffic",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}/move": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Auf einen anderen CDN-Server umziehen",
    "operationId": "post_cdn_token_move",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/renew-certificate": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Zertifikat neu ausstellen",
    "operationId": "post_cdn_token_renew_certificate",
    "description": "Nur bei aktivem Proxy mit HTTPS-Frontend.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnDomain"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/records": {
   "get": {
    "tags": [
     "CDN"
    ],
    "summary": "A- und AAAA-Records der Domain mit CDN-Zustand",
    "operationId": "get_cdn_token_records",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Record"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}/records/{record}/enable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Record über das CDN leiten",
    "operationId": "post_cdn_token_records_record_enable",
    "description": "full: der Name zeigt komplett auf das CDN. other_family_only: der Record bleibt direkt erreichbar und das CDN liefert nur die andere Adressfamilie, zum Beispiel IPv4 für einen reinen IPv6-Anschluss. other_family_only geht nur, wenn der Record der einzige auf seinem Präfix ist.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "mode": {
          "type": "string",
          "description": "Modus",
          "enum": [
           "full",
           "other_family_only"
          ],
          "example": "full"
         }
        }
       },
       "example": {
        "mode": "other_family_only"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Record"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/records/{record}/disable": {
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Record wieder direkt ausliefern",
    "operationId": "post_cdn_token_records_record_disable",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "record",
      "in": "path",
      "required": true,
      "description": "Record-ID oder Record-Token",
      "schema": {
       "type": "string"
      },
      "example": "4711"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Record"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cdn/{token}/mappings": {
   "get": {
    "tags": [
     "CDN"
    ],
    "summary": "Port-Mappings",
    "operationId": "get_cdn_token_mappings",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/CdnMapping"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Port-Mapping anlegen",
    "operationId": "post_cdn_token_mappings",
    "description": "Leitet einen öffentlichen Port des CDN-Servers auf einen Port bei dir weiter. Ohne listen_port wird ein freier Port zwischen 50000 und 62000 vergeben. Für A und AAAA desselben Namens mit gleichem Ziel-Port wird derselbe Port verwendet.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "record": {
          "type": "string",
          "description": "Record-ID oder -Token, der über das CDN läuft",
          "example": "4711"
         },
         "target_port": {
          "type": "integer",
          "description": "Port bei dir",
          "minimum": 1,
          "maximum": 65535,
          "example": 25565
         },
         "transport": {
          "type": "string",
          "description": "Protokoll",
          "enum": [
           "tcp",
           "udp"
          ],
          "example": "tcp"
         },
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Minecraft"
         },
         "listen_port": {
          "type": "integer",
          "description": "Wunsch-Port",
          "minimum": 50000,
          "maximum": 62000
         }
        },
        "required": [
         "record",
         "target_port"
        ]
       },
       "example": {
        "record": "4711",
        "target_port": 25565,
        "transport": "tcp",
        "name": "Minecraft"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CdnMapping"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}/mappings/{mapping}": {
   "delete": {
    "tags": [
     "CDN"
    ],
    "summary": "Port-Mapping löschen",
    "operationId": "delete_cdn_token_mappings_mapping",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "mapping",
      "in": "path",
      "required": true,
      "description": "Mapping-ID",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}/access-list": {
   "get": {
    "tags": [
     "CDN"
    ],
    "summary": "Zugriffsliste",
    "operationId": "get_cdn_token_access_list",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/AccessListEntry"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "CDN"
    ],
    "summary": "Eintrag hinzufügen",
    "operationId": "post_cdn_token_access_list",
    "description": "Ob die Liste erlaubt oder sperrt, steht in proxy.access_list.mode.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "address": {
          "type": "string",
          "description": "IP oder Netz in CIDR",
          "example": "198.51.100.0/24"
         }
        },
        "required": [
         "address"
        ]
       },
       "example": {
        "address": "198.51.100.0/24"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/AccessListEntry"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cdn/{token}/access-list/{id}": {
   "delete": {
    "tags": [
     "CDN"
    ],
    "summary": "Eintrag entfernen",
    "operationId": "delete_cdn_token_access_list_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cloud-routers": {
   "get": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Alle Cloud Router",
    "operationId": "get_cloud_routers",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/CloudRouter"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Cloud Router anlegen",
    "operationId": "post_cloud_routers",
    "description": "Legt Router und erstes Gateway an.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Home Lab"
         }
        }
       },
       "example": {
        "name": "Home Lab"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CloudRouter"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}": {
   "get": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Cloud Router mit Gateways, Peers und IPs",
    "operationId": "get_cloud_routers_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CloudRouter"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Router umbenennen",
    "operationId": "patch_cloud_routers_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Home Lab"
         }
        }
       },
       "example": {
        "name": "Buero"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/CloudRouter"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/cloud-routers/{token}/gateways": {
   "post": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Weiteres Gateway anlegen",
    "operationId": "post_cloud_routers_token_gateways",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Gateway 2"
         }
        }
       },
       "example": {
        "name": "Gateway 2"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/routes": {
   "get": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Routen",
    "operationId": "get_cloud_routers_token_routes",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Route"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Route anlegen",
    "operationId": "post_cloud_routers_token_routes",
    "description": "Statische Route in ein Netz hinter einem Peer.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "destination": {
          "type": "string",
          "description": "Zielnetz in CIDR",
          "example": "192.168.50.0/24"
         },
         "gateway": {
          "type": "string",
          "description": "Next Hop, gleiche Familie",
          "example": "10.7.0.2"
         },
         "peer": {
          "type": "string",
          "description": "Peer-ID",
          "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
         },
         "distance": {
          "type": "integer",
          "description": "Distanz",
          "minimum": 1,
          "maximum": 255,
          "example": 1
         }
        },
        "required": [
         "destination",
         "gateway",
         "peer"
        ]
       },
       "example": {
        "destination": "192.168.50.0/24",
        "gateway": "10.7.0.2",
        "peer": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Route"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/routes/{id}": {
   "patch": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Route ein- oder ausschalten",
    "operationId": "patch_cloud_routers_token_routes_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "disabled": {
          "type": "boolean",
          "description": "Deaktiviert",
          "example": true
         }
        }
       },
       "example": {
        "disabled": true
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Route"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   },
   "delete": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Route löschen",
    "operationId": "delete_cloud_routers_token_routes_id",
    "description": "Systemrouten können nicht gelöscht werden.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "id": {
             "type": "integer",
             "description": "ID",
             "example": 21
            },
            "state": {
             "type": "string",
             "description": "Zustand",
             "example": "deleting"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/firewall": {
   "get": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Firewall-Regeln",
    "operationId": "get_cloud_routers_token_firewall",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/FirewallRule"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Firewall-Regel anlegen",
    "operationId": "post_cloud_routers_token_firewall",
    "description": "source und destination müssen zur selben Familie gehören. Mindestens eines davon ist Pflicht.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "chain": {
          "type": "string",
          "description": "Kette",
          "enum": [
           "forward",
           "input",
           "output"
          ],
          "example": "forward"
         },
         "action": {
          "type": "string",
          "description": "Aktion",
          "enum": [
           "accept",
           "drop"
          ],
          "example": "drop"
         },
         "source": {
          "type": "string",
          "description": "Quelle als IP oder CIDR",
          "example": "10.7.0.0/24"
         },
         "destination": {
          "type": "string",
          "description": "Ziel als IP oder CIDR",
          "example": "192.168.50.10"
         }
        },
        "required": [
         "chain",
         "action"
        ]
       },
       "example": {
        "chain": "forward",
        "action": "drop",
        "source": "10.7.0.5",
        "destination": "192.168.50.0/24"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FirewallRule"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/firewall/{id}": {
   "patch": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Regel ein- oder ausschalten",
    "operationId": "patch_cloud_routers_token_firewall_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "disabled": {
          "type": "boolean",
          "description": "Deaktiviert",
          "example": true
         }
        }
       },
       "example": {
        "disabled": true
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/FirewallRule"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   },
   "delete": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Regel löschen",
    "operationId": "delete_cloud_routers_token_firewall_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "id": {
             "type": "integer",
             "description": "ID",
             "example": 4
            },
            "state": {
             "type": "string",
             "description": "Zustand",
             "example": "deleting"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/public-ips": {
   "get": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Öffentliche IPs",
    "operationId": "get_cloud_routers_token_public_ips",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/PublicIp"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "Öffentliche IPv6 anlegen",
    "operationId": "post_cloud_routers_token_public_ips",
    "description": "Höchstens eine IPv6 je Router. Die Adresse wird zufällig aus dem Netz des VPN-Servers vergeben.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/PublicIp"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/cloud-routers/{token}/public-ips/{id}": {
   "patch": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "IP ein- oder ausschalten",
    "operationId": "patch_cloud_routers_token_public_ips_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "disabled": {
          "type": "boolean",
          "description": "Deaktiviert",
          "example": true
         }
        }
       },
       "example": {
        "disabled": true
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/PublicIp"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   },
   "delete": {
    "tags": [
     "Cloud Router"
    ],
    "summary": "IP löschen",
    "operationId": "delete_cloud_routers_token_public_ips_id",
    "description": "Port-Forwards auf diese IP werden neu eingerichtet.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "id": {
             "type": "integer",
             "description": "ID",
             "example": 5
            },
            "state": {
             "type": "string",
             "description": "Zustand",
             "example": "deleting"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}": {
   "get": {
    "tags": [
     "Gateways"
    ],
    "summary": "Gateway mit Peers",
    "operationId": "get_gateways_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Gateways"
    ],
    "summary": "Gateway ändern",
    "operationId": "patch_gateways_token",
    "description": "Adressen in CIDR-Schreibweise. Leerer String entfernt die Adresse.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Gateway Frankfurt"
         },
         "ipv4": {
          "type": "string",
          "description": "Gateway-Adresse IPv4",
          "example": "10.7.0.1/24"
         },
         "ipv6": {
          "type": "string",
          "description": "Gateway-Adresse IPv6",
          "example": "fd64::1/64"
         },
         "disabled": {
          "type": "boolean",
          "description": "Gateway deaktivieren",
          "example": false
         }
        }
       },
       "example": {
        "ipv4": "10.7.0.1/24"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Gateways"
    ],
    "summary": "Gateway mit allen Peers löschen",
    "operationId": "delete_gateways_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}/rotate-keys": {
   "post": {
    "tags": [
     "Gateways"
    ],
    "summary": "Neues Schlüsselpaar für das Gateway",
    "operationId": "post_gateways_token_rotate_keys",
    "description": "Danach müssen alle Peers die neue Konfiguration erhalten.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}/reset-traffic": {
   "post": {
    "tags": [
     "Gateways"
    ],
    "summary": "Traffic-Zähler zurücksetzen",
    "operationId": "post_gateways_token_reset_traffic",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/gateways/{token}/ospf": {
   "put": {
    "tags": [
     "Gateways"
    ],
    "summary": "OSPF einschalten oder einstellen",
    "operationId": "put_gateways_token_ospf",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "area_id": {
          "type": "string",
          "description": "Area",
          "example": "0.0.0.0"
         },
         "version": {
          "type": "integer",
          "description": "OSPF-Version",
          "minimum": 2,
          "maximum": 3,
          "example": 2
         },
         "cost": {
          "type": "integer",
          "description": "Kosten",
          "minimum": 1,
          "maximum": 256,
          "example": 10
         }
        }
       },
       "example": {
        "area_id": "0.0.0.0",
        "version": 2,
        "cost": 10
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   },
   "delete": {
    "tags": [
     "Gateways"
    ],
    "summary": "OSPF ausschalten",
    "operationId": "delete_gateways_token_ospf",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Gateway"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}/port-forwards": {
   "get": {
    "tags": [
     "Gateways"
    ],
    "summary": "Port-Forwards",
    "operationId": "get_gateways_token_port_forwards",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/PortForward"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Gateways"
    ],
    "summary": "Port-Forward anlegen",
    "operationId": "post_gateways_token_port_forwards",
    "description": "Den öffentlichen Port vergibt der Server, er steht danach in public_port.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "destination": {
          "type": "string",
          "description": "Ziel-IP im Tunnel",
          "example": "10.7.0.2"
         },
         "target_port": {
          "type": "integer",
          "description": "Ziel-Port",
          "minimum": 1,
          "maximum": 65499,
          "example": 443
         },
         "protocol": {
          "type": "string",
          "description": "Protokoll",
          "enum": [
           "tcp",
           "udp"
          ],
          "example": "tcp"
         },
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Webserver"
         },
         "public_ip": {
          "type": "string",
          "description": "server oder router (öffentliche IP des Routers, vorher anlegen)",
          "enum": [
           "server",
           "router"
          ],
          "example": "server"
         }
        },
        "required": [
         "destination",
         "target_port",
         "protocol"
        ]
       },
       "example": {
        "destination": "10.7.0.2",
        "target_port": 443,
        "protocol": "tcp",
        "name": "Webserver"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/PortForward"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}/port-forwards/{id}": {
   "patch": {
    "tags": [
     "Gateways"
    ],
    "summary": "Port-Forward ein- oder ausschalten",
    "operationId": "patch_gateways_token_port_forwards_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "disabled": {
          "type": "boolean",
          "description": "Deaktiviert",
          "example": true
         }
        }
       },
       "example": {
        "disabled": true
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/PortForward"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   },
   "delete": {
    "tags": [
     "Gateways"
    ],
    "summary": "Port-Forward löschen",
    "operationId": "delete_gateways_token_port_forwards_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "id": {
             "type": "integer",
             "description": "ID",
             "example": 9
            },
            "state": {
             "type": "string",
             "description": "Zustand",
             "example": "deleting"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/gateways/{token}/peers": {
   "get": {
    "tags": [
     "Gateways"
    ],
    "summary": "Peers des Gateways",
    "operationId": "get_gateways_token_peers",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Peer"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "Gateways"
    ],
    "summary": "Peer anlegen",
    "operationId": "post_gateways_token_peers",
    "description": "Schlüssel und Adressen werden automatisch vergeben.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Laptop"
         }
        }
       },
       "example": {
        "name": "Laptop"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/peers/{token}": {
   "get": {
    "tags": [
     "Peers"
    ],
    "summary": "Peer mit AllowedIPs",
    "operationId": "get_peers_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "Peers"
    ],
    "summary": "Peer ändern",
    "operationId": "patch_peers_token",
    "description": "name und dns_server wirken sofort (200). Alle anderen Felder werden am Gateway umgesetzt (202).",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Laptop"
         },
         "dns_server": {
          "type": "string",
          "description": "DNS-Server für die Client-Config, leer = keiner",
          "example": "1.1.1.1"
         },
         "keepalive": {
          "type": "string",
          "description": "Keepalive hh:mm:ss",
          "example": "00:00:25"
         },
         "endpoint": {
          "type": "string",
          "description": "Fester Endpunkt (IP oder Hostname)",
          "example": "site-b.example.com"
         },
         "endpoint_port": {
          "type": "integer",
          "description": "Port des Endpunkts",
          "minimum": 0,
          "maximum": 65535,
          "example": 51820
         },
         "ipv4": {
          "type": "string",
          "description": "Tunnel-IPv4 in CIDR",
          "example": "10.7.0.5/32"
         },
         "ipv6": {
          "type": "string",
          "description": "Tunnel-IPv6 in CIDR",
          "example": "fd64::5/128"
         },
         "disabled": {
          "type": "boolean",
          "description": "Deaktiviert",
          "example": false
         },
         "site_to_site": {
          "type": "boolean",
          "description": "Site-to-Site",
          "example": false
         }
        }
       },
       "example": {
        "keepalive": "00:00:25",
        "dns_server": "1.1.1.1"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "202": {
      "description": "Angenommen, wird am Gateway umgesetzt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "Peers"
    ],
    "summary": "Peer löschen",
    "operationId": "delete_peers_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/peers/{token}/config": {
   "get": {
    "tags": [
     "Peers"
    ],
    "summary": "WireGuard-Konfiguration",
    "operationId": "get_peers_token_config",
    "description": "Mit dem Header Accept: text/plain kommt die .conf-Datei direkt als Download. Sie enthält den privaten Schlüssel des Peers.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Konfiguration",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "peer": {
             "type": "string",
             "description": "Peer-ID",
             "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
            },
            "config": {
             "type": "string",
             "description": "Inhalt der .conf-Datei"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       },
       "text/plain": {
        "schema": {
         "type": "string",
         "description": "WireGuard-Konfiguration"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/peers/{token}/rotate-keys": {
   "post": {
    "tags": [
     "Peers"
    ],
    "summary": "Neues Schlüsselpaar",
    "operationId": "post_peers_token_rotate_keys",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/peers/{token}/rotate-preshared-key": {
   "post": {
    "tags": [
     "Peers"
    ],
    "summary": "Neuer Preshared Key",
    "operationId": "post_peers_token_rotate_preshared_key",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/peers/{token}/keys": {
   "put": {
    "tags": [
     "Peers"
    ],
    "summary": "Eigene Schlüssel setzen",
    "operationId": "put_peers_token_keys",
    "description": "Ohne private_key wird nur der öffentliche Schlüssel hinterlegt. Die Config enthält dann keinen privaten Schlüssel.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "public_key": {
          "type": "string",
          "description": "Öffentlicher Schlüssel (Base64)",
          "example": "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="
         },
         "private_key": {
          "type": "string",
          "description": "Privater Schlüssel, muss passen"
         },
         "preshared_key": {
          "type": "string",
          "description": "Preshared Key (Base64)"
         }
        },
        "required": [
         "public_key"
        ]
       },
       "example": {
        "public_key": "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/peers/{token}/allowed-ips": {
   "post": {
    "tags": [
     "Peers"
    ],
    "summary": "AllowedIP hinzufügen",
    "operationId": "post_peers_token_allowed_ips",
    "description": "Zusätzliches Netz in der Client-Config, zum Beispiel ein Netz hinter einem anderen Peer.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "network": {
          "type": "string",
          "description": "IP oder Netz in CIDR",
          "example": "192.168.50.0/24"
         }
        },
        "required": [
         "network"
        ]
       },
       "example": {
        "network": "192.168.50.0/24"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Angelegt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Peer"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/peers/{token}/allowed-ips/{id}": {
   "delete": {
    "tags": [
     "Peers"
    ],
    "summary": "AllowedIP entfernen",
    "operationId": "delete_peers_token_allowed_ips_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/dns64/clients": {
   "get": {
    "tags": [
     "DNS64"
    ],
    "summary": "Alle DNS64-Clients",
    "operationId": "get_dns64_clients",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Dns64Client"
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "post": {
    "tags": [
     "DNS64"
    ],
    "summary": "Client anlegen",
    "operationId": "post_dns64_clients",
    "description": "Resolver-Adressen und client_id stehen bereit, sobald state ready ist.",
    "parameters": [
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Familie"
         }
        }
       },
       "example": {
        "name": "Familie"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/dns64/clients/{token}": {
   "get": {
    "tags": [
     "DNS64"
    ],
    "summary": "Client mit Regeln, Quellen und DNS-Stamps",
    "operationId": "get_dns64_clients_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "patch": {
    "tags": [
     "DNS64"
    ],
    "summary": "Client ändern",
    "operationId": "patch_dns64_clients_token",
    "description": "Die Blocklisten adult und threats gibt es nicht im Free-Paket.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name",
          "example": "Familie"
         },
         "blocking_enabled": {
          "type": "boolean",
          "description": "Filter aktiv",
          "example": true
         },
         "blocklists": {
          "type": "array",
          "items": {
           "type": "string",
           "enum": [
            "ads",
            "adult",
            "threats"
           ],
           "example": "ads"
          },
          "description": "Aktive Blocklisten"
         }
        }
       },
       "example": {
        "blocklists": [
         "ads",
         "threats"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Erfolgreich",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "202": {
      "description": "Angenommen, Filter werden neu ausgerollt",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   },
   "delete": {
    "tags": [
     "DNS64"
    ],
    "summary": "Client löschen",
    "operationId": "delete_dns64_clients_token",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "type": "object",
           "properties": {
            "id": {
             "type": "string",
             "description": "Client-ID",
             "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
            },
            "state": {
             "type": "string",
             "description": "Zustand",
             "example": "deleting"
            }
           }
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/dns64/clients/{token}/rules": {
   "post": {
    "tags": [
     "DNS64"
    ],
    "summary": "Domain erlauben oder sperren",
    "operationId": "post_dns64_clients_token_rules",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "domain": {
          "type": "string",
          "description": "Domain",
          "example": "example.com"
         },
         "action": {
          "type": "string",
          "description": "Aktion",
          "enum": [
           "allow",
           "block"
          ],
          "example": "block"
         }
        },
        "required": [
         "domain"
        ]
       },
       "example": {
        "domain": "example.com",
        "action": "block"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/dns64/clients/{token}/rules/{id}": {
   "delete": {
    "tags": [
     "DNS64"
    ],
    "summary": "Regel entfernen",
    "operationId": "delete_dns64_clients_token_rules_id",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  },
  "/dns64/clients/{token}/sources": {
   "post": {
    "tags": [
     "DNS64"
    ],
    "summary": "Quell-Adresse hinzufügen",
    "operationId": "post_dns64_clients_token_sources",
    "description": "Damit die gemeinsamen Resolver-IPs Anfragen deinem Client zuordnen. Entweder eine feste ip oder ein eigener A/AAAA-Record, dessen DynDNS-Adresse verfolgt wird. Je Art höchstens 5.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "ip": {
          "type": "string",
          "description": "Feste IP",
          "example": "203.0.113.10"
         },
         "record": {
          "type": "string",
          "description": "Record-ID oder -Token",
          "example": "4711"
         }
        }
       },
       "example": {
        "record": "4711"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Angenommen. Die Änderung wird in den nächsten Sekunden vom Hintergrunddienst umgesetzt.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "data": {
           "$ref": "#/components/schemas/Dns64Client"
          }
         },
         "required": [
          "data"
         ]
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "403": {
      "$ref": "#/components/responses/E403"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "409": {
      "$ref": "#/components/responses/E409"
     },
     "422": {
      "$ref": "#/components/responses/E422"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    },
    "x-async": true
   }
  },
  "/dns64/clients/{token}/sources/{id}": {
   "delete": {
    "tags": [
     "DNS64"
    ],
    "summary": "Quell-Adresse entfernen",
    "operationId": "delete_dns64_clients_token_sources_id",
    "description": "{id} ist die numerische ID bei festen IPs oder der Record-Token bei Records.",
    "parameters": [
     {
      "name": "token",
      "in": "path",
      "required": true,
      "description": "Token bzw. ID der Ressource (32 Zeichen)",
      "schema": {
       "type": "string"
      },
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "description": "ID der Ressource",
      "schema": {
       "type": "string"
      },
      "example": "12"
     },
     {
      "$ref": "#/components/parameters/ActAs"
     }
    ],
    "responses": {
     "204": {
      "description": "Erfolgreich, ohne Inhalt"
     },
     "401": {
      "$ref": "#/components/responses/E401"
     },
     "404": {
      "$ref": "#/components/responses/E404"
     },
     "429": {
      "$ref": "#/components/responses/E429"
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "description": "Authorization: Bearer <API-Key>"
   },
   "apiKeyHeader": {
    "type": "apiKey",
    "in": "header",
    "name": "X-API-Key",
    "description": "Alternativ der Header X-API-Key"
   }
  },
  "parameters": {
   "ActAs": {
    "name": "X-IPv64-Act-As",
    "in": "header",
    "required": false,
    "schema": {
     "type": "string"
    },
    "description": "Optional: Account-ID oder E-Mail eines Accounts, der dir per Account-Freigabe die Verwaltung erlaubt hat. Die Anfrage läuft dann in diesem Account."
   }
  },
  "responses": {
   "E400": {
    "description": "Ungültige Anfrage oder Parameter",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#invalid_parameter",
       "title": "Bad Request",
       "status": 400,
       "detail": "Query parameter 'limit' must be a positive integer.",
       "code": "invalid_parameter"
      }
     }
    }
   },
   "E401": {
    "description": "Kein oder ungültiger API-Key",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#invalid_token",
       "title": "Unauthorized",
       "status": 401,
       "detail": "The API key is invalid, expired or the account is not active.",
       "code": "invalid_token"
      }
     }
    }
   },
   "E403": {
    "description": "Limit des Pakets erreicht oder keine Berechtigung",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#limit_reached",
       "title": "Forbidden",
       "status": 403,
       "detail": "Your plan allows no further domains of this kind.",
       "code": "limit_reached"
      }
     }
    }
   },
   "E404": {
    "description": "Nicht gefunden",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#not_found",
       "title": "Not Found",
       "status": 404,
       "detail": "Unknown endpoint /beispiel.",
       "code": "not_found"
      }
     }
    }
   },
   "E409": {
    "description": "Konflikt mit dem aktuellen Zustand",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#failover_active",
       "title": "Conflict",
       "status": 409,
       "detail": "A DNS failover is active on this domain. Fall back first.",
       "code": "failover_active"
      }
     }
    }
   },
   "E413": {
    "description": "Body größer als 1 MB",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#payload_too_large",
       "title": "Payload Too Large",
       "status": 413,
       "detail": "Request body exceeds 1 MB.",
       "code": "payload_too_large"
      }
     }
    }
   },
   "E415": {
    "description": "Falscher Content-Type",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#unsupported_media_type",
       "title": "Unsupported Media Type",
       "status": 415,
       "detail": "Use Content-Type application/json.",
       "code": "unsupported_media_type"
      }
     }
    }
   },
   "E422": {
    "description": "Eingaben ungültig",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#missing_field",
       "title": "Unprocessable Content",
       "status": 422,
       "detail": "Field 'name' is required.",
       "code": "missing_field"
      }
     }
    }
   },
   "E429": {
    "description": "Zu viele Anfragen",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "example": {
       "type": "https://ipv64.net/api/v2/errors#rate_limited",
       "title": "Too Many Requests",
       "status": 429,
       "detail": "Too many requests (account). Retry in 3 seconds.",
       "code": "rate_limited"
      }
     }
    }
   }
  },
  "schemas": {
   "Problem": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "description": "Link auf die Fehlerbeschreibung",
      "example": "https://ipv64.net/api/v2/errors#domain_not_found"
     },
     "title": {
      "type": "string",
      "description": "HTTP-Statustext",
      "example": "Not Found"
     },
     "status": {
      "type": "integer",
      "description": "HTTP-Status",
      "example": 404
     },
     "detail": {
      "type": "string",
      "description": "Verständliche Fehlermeldung",
      "example": "Domain 'beispiel.ipv64.de' not found."
     },
     "code": {
      "type": "string",
      "description": "Maschinenlesbarer Fehlercode",
      "example": "domain_not_found"
     },
     "field": {
      "type": "string",
      "description": "Betroffenes Eingabefeld, falls vorhanden",
      "example": "name"
     },
     "retry_after": {
      "type": "integer",
      "description": "Sekunden bis zum nächsten Versuch (bei 429 und manchen 409)",
      "example": 10
     }
    },
    "required": [
     "type",
     "title",
     "status",
     "detail",
     "code"
    ],
    "description": "Fehler nach RFC 9457 (application/problem+json)"
   },
   "Me": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Account-ID",
      "example": 522
     },
     "email": {
      "type": "string",
      "description": "E-Mail-Adresse",
      "example": "max@example.com"
     },
     "username": {
      "type": [
       "string",
       "null"
      ],
      "description": "Benutzername"
     },
     "registered_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Registriert seit",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_login_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Login auf der Webseite",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "plan": {
      "type": "object",
      "properties": {
       "id": {
        "type": "integer",
        "description": "Paket-ID",
        "example": 2
       },
       "name": {
        "type": "string",
        "description": "Paketname",
        "example": "VIP"
       },
       "valid_until": {
        "type": [
         "string",
         "null"
        ],
        "description": "Laufzeitende, null beim Free-Paket",
        "format": "date-time",
        "example": "2026-10-10T12:00:00+02:00"
       }
      }
     },
     "usage": {
      "type": "object",
      "properties": {
       "dyndns_domains": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DynDNS-Domains"
       },
       "own_domains": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "Eigene Domains"
       },
       "dyndns_updates_24h": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DynDNS-Updates der letzten 24 Stunden"
       },
       "healthchecks": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "Healthchecks"
       },
       "healthcheck_pings_24h": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "Healthcheck-Pings der letzten 24 Stunden"
       },
       "sms_24h": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "SMS der letzten 24 Stunden"
       },
       "failover_policies": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DNS-Failover-Policies"
       },
       "failover_monitors": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DNS-Failover-Monitore"
       },
       "failover_rules": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DNS-Failover-Regeln"
       },
       "cdn_domains": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "CDN-Domains"
       },
       "cdn_traffic_gb": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "CDN-Traffic im aktuellen Monat in GB"
       },
       "vpn_traffic_gb": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 1.5
         },
         "limit": {
          "type": "integer",
          "description": "Limit in GB",
          "example": 100
         },
         "limited": {
          "type": "boolean",
          "description": "Traffic-Limit erreicht",
          "example": false
         }
        },
        "description": "Cloud-Router-Traffic in GB"
       },
       "dns64_clients": {
        "type": "object",
        "properties": {
         "used": {
          "type": "number",
          "description": "Verbraucht",
          "example": 2
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "description": "Limit des Pakets, null = unbegrenzt",
          "example": 10
         }
        },
        "description": "DNS64-Clients"
       }
      }
     },
     "log_retention_days": {
      "type": "integer",
      "description": "So viele Tage werden Logs aufbewahrt",
      "example": 90
     },
     "auth": {
      "type": "object",
      "properties": {
       "type": {
        "type": "string",
        "description": "Art des Schlüssels",
        "enum": [
         "api_key",
         "account_key"
        ],
        "example": "api_key"
       },
       "key_id": {
        "type": [
         "integer",
         "null"
        ],
        "description": "ID des API-Keys",
        "example": 75043
       },
       "key_name": {
        "type": "string",
        "description": "Name des API-Keys",
        "example": "Mein Server"
       },
       "acting_for": {
        "type": "integer",
        "description": "Bei X-IPv64-Act-As: Account, für den gehandelt wird",
        "example": 1234
       },
       "acting_by": {
        "type": "integer",
        "description": "Bei X-IPv64-Act-As: eigener Account",
        "example": 522
       }
      },
      "description": "Verwendete Anmeldung"
     }
    }
   },
   "LogEntry": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Log-ID, auch Cursor für before",
      "example": 83448927
     },
     "domain_id": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Betroffene Domain"
     },
     "title": {
      "type": "string",
      "description": "Kategorie",
      "example": "API Key"
     },
     "message": {
      "type": "string",
      "description": "Text",
      "example": "New API Key 'test' created."
     },
     "time": {
      "type": "string",
      "description": "Zeitpunkt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "AccountLink": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID der Freigabe",
      "example": 1
     },
     "direction": {
      "type": "string",
      "description": "shared_with = du hast freigegeben, managed = du verwaltest",
      "enum": [
       "shared_with",
       "managed"
      ],
      "example": "shared_with"
     },
     "email": {
      "type": "string",
      "description": "E-Mail des anderen Accounts",
      "example": "admin@example.com"
     },
     "status": {
      "type": "string",
      "description": "Status",
      "enum": [
       "active",
       "pending"
      ],
      "example": "active"
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_used_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Zuletzt benutzt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "account_id": {
      "type": "integer",
      "description": "Nur bei managed: ID für X-IPv64-Act-As",
      "example": 1234
     }
    }
   },
   "ApiKey": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 303
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Mein Server"
     },
     "token_hint": {
      "type": "string",
      "description": "Anfang und Ende des Keys",
      "example": "1ZK4…Rx5e"
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "expires_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Ablauf, null = nie",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "expired": {
      "type": "boolean",
      "description": "Abgelaufen",
      "example": false
     },
     "uses": {
      "type": "integer",
      "description": "Anzahl Aufrufe",
      "example": 42
     }
    }
   },
   "ApiKeyCreated": {
    "allOf": [
     {
      "$ref": "#/components/schemas/ApiKey"
     },
     {
      "type": "object",
      "properties": {
       "token": {
        "type": "string",
        "description": "Der vollständige Key. Wird nur dieses eine Mal angezeigt.",
        "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
       }
      }
     }
    ]
   },
   "Record": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Record-ID",
      "example": 4711
     },
     "domain_id": {
      "type": "integer",
      "description": "Domain-ID",
      "example": 17597
     },
     "domain": {
      "type": "string",
      "description": "Domain",
      "example": "beispiel.ipv64.de"
     },
     "prefix": {
      "type": "string",
      "description": "Präfix, leer = Domain selbst",
      "example": "nas"
     },
     "fqdn": {
      "type": "string",
      "description": "Vollständiger Name",
      "example": "nas.beispiel.ipv64.de"
     },
     "type": {
      "type": "string",
      "description": "Record-Typ",
      "enum": [
       "A",
       "AAAA",
       "CNAME",
       "MX",
       "TXT",
       "NS",
       "SRV",
       "TLSA",
       "CAA"
      ],
      "example": "A"
     },
     "content": {
      "type": "string",
      "description": "Inhalt",
      "example": "203.0.113.10"
     },
     "ttl": {
      "type": "integer",
      "description": "TTL in Sekunden",
      "example": 60
     },
     "state": {
      "type": "string",
      "description": "active, inactive, cdn_record (vom CDN verwaltet), cdn_proxied / cdn_partial (läuft über das CDN), failover_record (temporärer Ersatz), failover_replaced (durch Failover ersetzt)",
      "enum": [
       "active",
       "inactive",
       "cdn_record",
       "cdn_proxied",
       "cdn_partial",
       "failover_record",
       "failover_replaced"
      ],
      "example": "active"
     },
     "pending_dns": {
      "type": "boolean",
      "description": "Änderung wird noch an die Nameserver übertragen",
      "example": false
     },
     "token": {
      "type": "string",
      "description": "Record-Token. Bleibt bei IP-Änderungen gleich und kann statt der ID verwendet werden.",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "updated_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzte Änderung",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "Domain": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Domain-ID",
      "example": 17597
     },
     "name": {
      "type": "string",
      "description": "Vollständiger Name",
      "example": "beispiel.ipv64.de"
     },
     "kind": {
      "type": "string",
      "description": "dyndns oder own (eigene Domain)",
      "enum": [
       "dyndns",
       "own"
      ],
      "example": "dyndns"
     },
     "zone": {
      "type": "string",
      "description": "Zone",
      "example": "ipv64.de"
     },
     "wildcard": {
      "type": "boolean",
      "description": "Wildcard-Records *.name aktiv",
      "example": true
     },
     "ignore": {
      "type": "string",
      "description": "Diese Adressfamilie wird bei DynDNS-Updates ignoriert",
      "enum": [
       "none",
       "ipv4",
       "ipv6"
      ],
      "example": "none"
     },
     "ipv6_prefix": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fester IPv6-Präfix für Interface-IDs"
     },
     "active": {
      "type": "boolean",
      "description": "Domain aktiv",
      "example": true
     },
     "update_token": {
      "type": "string",
      "description": "Domain-Update-Token für update.php",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "update_count": {
      "type": "integer",
      "description": "Anzahl DynDNS-Updates",
      "example": 1200
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "updated_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letztes Update",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "DomainDetail": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Domain-ID",
      "example": 17597
     },
     "name": {
      "type": "string",
      "description": "Vollständiger Name",
      "example": "beispiel.ipv64.de"
     },
     "kind": {
      "type": "string",
      "description": "dyndns oder own (eigene Domain)",
      "enum": [
       "dyndns",
       "own"
      ],
      "example": "dyndns"
     },
     "zone": {
      "type": "string",
      "description": "Zone",
      "example": "ipv64.de"
     },
     "wildcard": {
      "type": "boolean",
      "description": "Wildcard-Records *.name aktiv",
      "example": true
     },
     "ignore": {
      "type": "string",
      "description": "Diese Adressfamilie wird bei DynDNS-Updates ignoriert",
      "enum": [
       "none",
       "ipv4",
       "ipv6"
      ],
      "example": "none"
     },
     "ipv6_prefix": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fester IPv6-Präfix für Interface-IDs"
     },
     "active": {
      "type": "boolean",
      "description": "Domain aktiv",
      "example": true
     },
     "update_token": {
      "type": "string",
      "description": "Domain-Update-Token für update.php",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "update_count": {
      "type": "integer",
      "description": "Anzahl DynDNS-Updates",
      "example": 1200
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "updated_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letztes Update",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "records": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Record"
      },
      "description": "Alle Records der Domain"
     }
    }
   },
   "DynDnsResult": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "description": "Domain",
      "example": "beispiel.ipv64.de"
     },
     "prefix": {
      "type": "string",
      "description": "Präfix",
      "example": ""
     },
     "changed": {
      "type": "boolean",
      "description": "Mindestens ein Record geändert",
      "example": true
     },
     "results": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "ip": {
         "type": "string",
         "description": "IP",
         "example": "203.0.113.10"
        },
        "type": {
         "type": "string",
         "description": "A oder AAAA",
         "example": "A"
        },
        "result": {
         "type": "string",
         "description": "Ergebnis je IP",
         "enum": [
          "created",
          "updated",
          "unchanged",
          "ignored",
          "invalid_ip",
          "cname_conflict",
          "cdn_managed"
         ],
         "example": "updated"
        }
       }
      }
     }
    }
   },
   "HealthcheckEvent": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "Event-ID, auch Cursor",
      "example": 1057264859
     },
     "time": {
      "type": "string",
      "description": "Zeitpunkt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "status": {
      "type": "string",
      "description": "Status",
      "enum": [
       "new",
       "up",
       "paused",
       "warning",
       "down",
       "stabilizing"
      ],
      "example": "up"
     },
     "message": {
      "type": "string",
      "description": "Text",
      "example": "Healthcheck is UP"
     },
     "latency_ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Antwortzeit",
      "example": 23.4
     },
     "payload": {
      "type": [
       "object",
       "null"
      ],
      "description": "Zusatzdaten des Pings"
     }
    }
   },
   "Healthcheck": {
    "type": "object",
    "properties": {
     "token": {
      "type": "string",
      "description": "Healthcheck-Token, identifiziert den Check",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Backup NAS"
     },
     "type": {
      "type": "string",
      "description": "Art des Checks",
      "enum": [
       "push",
       "icmp",
       "tcp",
       "http",
       "keyword"
      ],
      "example": "push"
     },
     "status": {
      "type": "string",
      "description": "Status",
      "enum": [
       "new",
       "up",
       "paused",
       "warning",
       "down",
       "stabilizing"
      ],
      "example": "up"
     },
     "notify": {
      "type": "object",
      "properties": {
       "on_down": {
        "type": "boolean",
        "description": "Bei DOWN benachrichtigen",
        "example": true
       },
       "on_up": {
        "type": "boolean",
        "description": "Bei UP benachrichtigen",
        "example": true
       },
       "integrations": {
        "type": "array",
        "items": {
         "type": "integer",
         "example": 0
        },
        "description": "IDs der Integrationen, 0 = Account-E-Mail"
       }
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_seen_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Ping oder letzte Prüfung",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_alarm_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Alarm",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "pings_total": {
      "type": "integer",
      "description": "Anzahl Pings",
      "example": 1500
     },
     "failed_in_row": {
      "type": "integer",
      "description": "Fehlschläge in Folge",
      "example": 0
     },
     "push": {
      "type": "object",
      "properties": {
       "url": {
        "type": "string",
        "description": "Diese URL pingt dein System an",
        "example": "https://ipv64.net/health.php?token=Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
       },
       "period_seconds": {
        "type": "integer",
        "description": "Erwarteter Abstand der Pings",
        "example": 3600
       },
       "grace_seconds": {
        "type": "integer",
        "description": "Kulanzzeit",
        "example": 600
       },
       "expected_by": {
        "type": [
         "string",
         "null"
        ],
        "description": "Spätester Zeitpunkt für den nächsten Ping",
        "format": "date-time",
        "example": "2026-10-10T12:00:00+02:00"
       }
      },
      "description": "Nur bei type push"
     },
     "check": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "target": {
        "type": "string",
        "description": "Ziel bei icmp und tcp",
        "example": "nas.beispiel.ipv64.de"
       },
       "prefer_ipv4": {
        "type": "boolean",
        "description": "IPv4 bevorzugen",
        "example": false
       },
       "port": {
        "type": "integer",
        "description": "Port bei tcp",
        "example": 443
       },
       "url": {
        "type": "string",
        "description": "URL bei http und keyword",
        "example": "https://example.com/"
       },
       "verify_tls": {
        "type": "boolean",
        "description": "Zertifikat prüfen",
        "example": true
       },
       "keyword": {
        "type": "string",
        "description": "Suchbegriff bei keyword",
        "example": "OK"
       },
       "interval_seconds": {
        "type": "integer",
        "description": "Prüfintervall",
        "example": 300
       },
       "retry_interval_seconds": {
        "type": "integer",
        "description": "Intervall nach einem Fehler",
        "example": 60
       },
       "failures_before_alarm": {
        "type": "integer",
        "description": "Fehlschläge bis zum Alarm",
        "example": 3
       },
       "next_check_at": {
        "type": [
         "string",
         "null"
        ],
        "description": "Nächste Prüfung",
        "format": "date-time",
        "example": "2026-10-10T12:00:00+02:00"
       }
      },
      "description": "Nur bei aktiven Checks (icmp, tcp, http, keyword). null, solange noch nichts eingestellt ist."
     }
    }
   },
   "HealthcheckDetail": {
    "type": "object",
    "properties": {
     "token": {
      "type": "string",
      "description": "Healthcheck-Token, identifiziert den Check",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Backup NAS"
     },
     "type": {
      "type": "string",
      "description": "Art des Checks",
      "enum": [
       "push",
       "icmp",
       "tcp",
       "http",
       "keyword"
      ],
      "example": "push"
     },
     "status": {
      "type": "string",
      "description": "Status",
      "enum": [
       "new",
       "up",
       "paused",
       "warning",
       "down",
       "stabilizing"
      ],
      "example": "up"
     },
     "notify": {
      "type": "object",
      "properties": {
       "on_down": {
        "type": "boolean",
        "description": "Bei DOWN benachrichtigen",
        "example": true
       },
       "on_up": {
        "type": "boolean",
        "description": "Bei UP benachrichtigen",
        "example": true
       },
       "integrations": {
        "type": "array",
        "items": {
         "type": "integer",
         "example": 0
        },
        "description": "IDs der Integrationen, 0 = Account-E-Mail"
       }
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_seen_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Ping oder letzte Prüfung",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_alarm_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Alarm",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "pings_total": {
      "type": "integer",
      "description": "Anzahl Pings",
      "example": 1500
     },
     "failed_in_row": {
      "type": "integer",
      "description": "Fehlschläge in Folge",
      "example": 0
     },
     "push": {
      "type": "object",
      "properties": {
       "url": {
        "type": "string",
        "description": "Diese URL pingt dein System an",
        "example": "https://ipv64.net/health.php?token=Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
       },
       "period_seconds": {
        "type": "integer",
        "description": "Erwarteter Abstand der Pings",
        "example": 3600
       },
       "grace_seconds": {
        "type": "integer",
        "description": "Kulanzzeit",
        "example": 600
       },
       "expected_by": {
        "type": [
         "string",
         "null"
        ],
        "description": "Spätester Zeitpunkt für den nächsten Ping",
        "format": "date-time",
        "example": "2026-10-10T12:00:00+02:00"
       }
      },
      "description": "Nur bei type push"
     },
     "check": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "target": {
        "type": "string",
        "description": "Ziel bei icmp und tcp",
        "example": "nas.beispiel.ipv64.de"
       },
       "prefer_ipv4": {
        "type": "boolean",
        "description": "IPv4 bevorzugen",
        "example": false
       },
       "port": {
        "type": "integer",
        "description": "Port bei tcp",
        "example": 443
       },
       "url": {
        "type": "string",
        "description": "URL bei http und keyword",
        "example": "https://example.com/"
       },
       "verify_tls": {
        "type": "boolean",
        "description": "Zertifikat prüfen",
        "example": true
       },
       "keyword": {
        "type": "string",
        "description": "Suchbegriff bei keyword",
        "example": "OK"
       },
       "interval_seconds": {
        "type": "integer",
        "description": "Prüfintervall",
        "example": 300
       },
       "retry_interval_seconds": {
        "type": "integer",
        "description": "Intervall nach einem Fehler",
        "example": 60
       },
       "failures_before_alarm": {
        "type": "integer",
        "description": "Fehlschläge bis zum Alarm",
        "example": 3
       },
       "next_check_at": {
        "type": [
         "string",
         "null"
        ],
        "description": "Nächste Prüfung",
        "format": "date-time",
        "example": "2026-10-10T12:00:00+02:00"
       }
      },
      "description": "Nur bei aktiven Checks (icmp, tcp, http, keyword). null, solange noch nichts eingestellt ist."
     },
     "recent": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/HealthcheckEvent"
      },
      "description": "Die letzten 20 Events"
     }
    }
   },
   "Incident": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 991
     },
     "status": {
      "type": "string",
      "description": "Status",
      "enum": [
       "open",
       "closed"
      ],
      "example": "closed"
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Beginn",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "closed_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Ende",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "events": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "time": {
         "type": [
          "string",
          "null"
         ],
         "description": "Zeitpunkt",
         "format": "date-time",
         "example": "2026-10-10T12:00:00+02:00"
        },
        "kind": {
         "type": "string",
         "description": "Art",
         "example": "down"
        },
        "message": {
         "type": "string",
         "description": "Text",
         "example": "Healthcheck is DOWN"
        }
       }
      }
     }
    }
   },
   "HealthcheckStats": {
    "type": "object",
    "properties": {
     "range": {
      "type": "string",
      "description": "Zeitraum",
      "example": "24h"
     },
     "from": {
      "type": [
       "string",
       "null"
      ],
      "description": "Beginn",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "to": {
      "type": [
       "string",
       "null"
      ],
      "description": "Ende",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "measurements": {
      "type": "integer",
      "description": "Anzahl Messungen",
      "example": 288
     },
     "availability_percent": {
      "type": [
       "number",
       "null"
      ],
      "description": "Verfügbarkeit",
      "example": 99.65
     },
     "latency_ms": {
      "type": "object",
      "properties": {
       "avg": {
        "type": [
         "number",
         "null"
        ],
        "description": "Durchschnitt",
        "example": 21.3
       },
       "min": {
        "type": [
         "number",
         "null"
        ],
        "description": "Minimum",
        "example": 12.0
       },
       "max": {
        "type": [
         "number",
         "null"
        ],
        "description": "Maximum",
        "example": 80.1
       }
      }
     },
     "bucket_seconds": {
      "type": "integer",
      "description": "Breite eines Zeitreihen-Punkts",
      "example": 900
     },
     "series": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "time": {
         "type": "string",
         "description": "Beginn des Intervalls",
         "format": "date-time",
         "example": "2026-10-10T12:00:00+02:00"
        },
        "measurements": {
         "type": "integer",
         "description": "Messungen",
         "example": 3
        },
        "availability_percent": {
         "type": "number",
         "description": "Verfügbarkeit",
         "example": 100
        },
        "latency_avg_ms": {
         "type": [
          "number",
          "null"
         ],
         "description": "Durchschnitt",
         "example": 20.1
        },
        "latency_max_ms": {
         "type": [
          "number",
          "null"
         ],
         "description": "Maximum",
         "example": 25.0
        }
       }
      }
     }
    }
   },
   "Integration": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID, 0 = Account-E-Mail",
      "example": 12
     },
     "type": {
      "type": "string",
      "description": "Art",
      "enum": [
       "account_email",
       "telegram",
       "gotify",
       "ntfy",
       "pushover",
       "discord",
       "webhook",
       "email",
       "sms",
       "app"
      ],
      "example": "telegram"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Mein Telegram"
     },
     "status": {
      "type": "string",
      "description": "E-Mail und SMS müssen erst bestätigt werden",
      "enum": [
       "active",
       "pending_verification"
      ],
      "example": "active"
     },
     "default": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Wird bei neuen Healthchecks vorausgewählt",
      "example": false
     },
     "options": {
      "type": "object",
      "description": "Einstellungen je Typ. Geheimnisse sind gekürzt, außer mit include_secrets=true.",
      "example": {
       "chatid": "123456789",
       "apitoken": "…AbCd"
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_used_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Zuletzt benutzt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "uses": {
      "type": "integer",
      "description": "Anzahl Nachrichten",
      "example": 17
     }
    }
   },
   "FailoverPolicy": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Policy-ID (16 Zeichen)",
      "example": "QTl4iPM2swRaxWdz"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Webserver"
     },
     "status": {
      "type": "string",
      "description": "pending = wird eingerichtet, active = überwacht, failed_over = Ersatz aktiv, paused, failover_requested / fallback_requested = Umschaltung läuft",
      "enum": [
       "pending",
       "active",
       "failed_over",
       "paused",
       "failover_requested",
       "fallback_requested"
      ],
      "example": "active"
     },
     "manual": {
      "type": "boolean",
      "description": "Letzte Umschaltung war manuell",
      "example": false
     },
     "mode": {
      "type": "string",
      "description": "auto_failover = automatisch umschalten, manuell zurück; auto_failover_and_fallback = beides automatisch; manual = nur manuell",
      "enum": [
       "auto_failover",
       "auto_failover_and_fallback",
       "manual"
      ],
      "example": "auto_failover"
     },
     "fallback_requires_all": {
      "type": "boolean",
      "description": "Rückschaltung erst, wenn alle Monitore wieder UP sind",
      "example": false
     },
     "linking": {
      "type": "string",
      "description": "and = alle Monitore müssen DOWN sein, or = einer reicht",
      "enum": [
       "and",
       "or"
      ],
      "example": "or"
     },
     "notifications_enabled": {
      "type": "boolean",
      "description": "Benachrichtigungen aktiv",
      "example": true
     },
     "integrations": {
      "type": "array",
      "items": {
       "type": "integer",
       "example": 0
      },
      "description": "Integrationen für Benachrichtigungen"
     },
     "monitors_down": {
      "type": "integer",
      "description": "Anzahl Monitore, die gerade als DOWN zählen",
      "example": 0
     },
     "last_check_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzte Prüfung",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "monitors": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "healthcheck": {
         "type": "string",
         "description": "Healthcheck-Token",
         "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
        },
        "name": {
         "type": "string",
         "description": "Name",
         "example": "Webserver HTTP"
        },
        "negate": {
         "type": "boolean",
         "description": "Umgekehrt werten (UP zählt als DOWN)",
         "example": false
        },
        "healthcheck_status": {
         "type": [
          "string",
          "null"
         ],
         "description": "Aktueller Status",
         "example": "up"
        }
       }
      }
     },
     "rules": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "record": {
         "type": "string",
         "description": "Record-Token des geschützten Records",
         "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
        },
        "fqdn": {
         "type": [
          "string",
          "null"
         ],
         "description": "Name",
         "example": "www.beispiel.ipv64.de"
        },
        "record_type": {
         "type": "string",
         "description": "A oder AAAA",
         "example": "A"
        },
        "state": {
         "type": "string",
         "description": "Zustand",
         "enum": [
          "standby",
          "failed_over"
         ],
         "example": "standby"
        },
        "target": {
         "type": "object",
         "properties": {
          "kind": {
           "type": "string",
           "description": "Art des Ziels",
           "enum": [
            "ip",
            "record",
            "offline_page"
           ],
           "example": "ip"
          },
          "ip": {
           "type": "string",
           "description": "Ersatz-IP",
           "example": "198.51.100.5"
          },
          "record": {
           "type": "string",
           "description": "Ziel-Record-Token",
           "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
          },
          "offline_page": {
           "type": "string",
           "description": "default oder Offline-Page-ID",
           "example": "default"
          }
         }
        }
       }
      }
     }
    }
   },
   "StatusPage": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 1053
     },
     "name": {
      "type": "string",
      "description": "Titel",
      "example": "Mein Status"
     },
     "slug": {
      "type": "string",
      "description": "Adresse hinter /status/",
      "example": "meinstatus"
     },
     "url": {
      "type": "string",
      "description": "Öffentliche Adresse",
      "example": "https://ipv64.net/status/meinstatus"
     },
     "description": {
      "type": "string",
      "description": "Beschreibung",
      "example": ""
     },
     "password_protected": {
      "type": "boolean",
      "description": "Mit Passwort geschützt",
      "example": false
     },
     "design": {
      "type": "integer",
      "description": "Design 1 bis 4",
      "example": 1
     },
     "autorefresh": {
      "type": "boolean",
      "description": "Seite lädt automatisch neu",
      "example": true
     },
     "healthchecks": {
      "type": "array",
      "items": {
       "type": "string",
       "description": "Healthcheck-Token",
       "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
      },
      "description": "Angezeigte Healthchecks in dieser Reihenfolge"
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "last_viewed_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Zuletzt aufgerufen",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "OfflinePage": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Offline-Page-ID (16 Zeichen)",
      "example": "aB3dE6gH9jK2mN5p"
     },
     "name": {
      "type": "string",
      "description": "Überschrift",
      "example": "Wartungsarbeiten"
     },
     "domain": {
      "type": "string",
      "description": "Domain, unter der die Seite erscheint",
      "example": "www.example.com"
     },
     "email": {
      "type": "string",
      "description": "Kontakt-E-Mail",
      "example": "info@example.com"
     },
     "phone": {
      "type": "string",
      "description": "Telefon",
      "example": "+49301234567"
     },
     "alternative_url": {
      "type": "string",
      "description": "Ausweichadresse",
      "example": "https://status.example.com"
     },
     "text": {
      "type": "string",
      "description": "Text als HTML",
      "example": "Wir sind gleich wieder da."
     },
     "icon_url": {
      "type": [
       "string",
       "null"
      ],
      "description": "Logo"
     },
     "views": {
      "type": "integer",
      "description": "Aufrufe",
      "example": 0
     },
     "in_use_by_policy": {
      "type": [
       "string",
       "null"
      ],
      "description": "Failover-Policy, die diese Seite nutzt"
     },
     "active": {
      "type": "boolean",
      "description": "Wird gerade ausgeliefert",
      "example": false
     },
     "preview_url": {
      "type": "string",
      "description": "Vorschau",
      "example": "https://ipv64.net/offline?domain=www.example.com&preview"
     }
    }
   },
   "CdnMapping": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Mapping-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Minecraft"
     },
     "listen_port": {
      "type": "integer",
      "description": "Öffentlicher Port am CDN-Server",
      "example": 51234
     },
     "transport": {
      "type": "string",
      "description": "Protokoll",
      "enum": [
       "tcp",
       "udp"
      ],
      "example": "tcp"
     },
     "target_port": {
      "type": "integer",
      "description": "Port bei dir",
      "example": 25565
     },
     "record": {
      "type": "string",
      "description": "Record-Token des Ziels",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "fqdn": {
      "type": [
       "string",
       "null"
      ],
      "description": "Name des Ziels",
      "example": "mc.beispiel.ipv64.de"
     }
    }
   },
   "CdnDomain": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "CDN-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "domain": {
      "type": [
       "string",
       "null"
      ],
      "description": "Domain",
      "example": "beispiel.ipv64.de"
     },
     "domain_id": {
      "type": "integer",
      "description": "Domain-ID",
      "example": 17597
     },
     "active": {
      "type": "boolean",
      "description": "CDN aktiv",
      "example": true
     },
     "pending": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "server_assignment",
        "dns",
        "config_deploy",
        "certificate",
        "server_move",
        "deletion"
       ],
       "example": "config_deploy"
      },
      "description": "Offene Arbeiten des CDN-Bots"
     },
     "dns_records_enabled": {
      "type": "boolean",
      "description": "Mindestens ein Record läuft über das CDN",
      "example": true
     },
     "server": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "name": {
        "type": "string",
        "description": "Name",
        "example": "CDN-FSN-1"
       },
       "hostname": {
        "type": "string",
        "description": "Hostname",
        "example": "cdn1.ipv64.net"
       },
       "ipv4": {
        "type": "string",
        "description": "IPv4",
        "example": "203.0.113.1"
       },
       "ipv6": {
        "type": "string",
        "description": "IPv6",
        "example": "2001:db8::1"
       }
      }
     },
     "proxy": {
      "type": "object",
      "properties": {
       "state": {
        "type": "string",
        "description": "Reverse Proxy",
        "enum": [
         "off",
         "on",
         "disabling"
        ],
        "example": "on"
       },
       "frontend": {
        "type": [
         "string",
         "null"
        ],
        "description": "http, https_redirect (HTTP wird auf HTTPS umgeleitet) oder http_and_https",
        "enum": [
         "http",
         "https_redirect",
         "http_and_https"
        ],
        "example": "https_redirect"
       },
       "backend": {
        "type": "object",
        "properties": {
         "scheme": {
          "type": "string",
          "description": "Protokoll zu deinem Server",
          "enum": [
           "http",
           "https"
          ],
          "example": "http"
         },
         "port": {
          "type": "integer",
          "description": "Port deines Servers",
          "example": 80
         }
        }
       },
       "websocket": {
        "type": "boolean",
        "description": "WebSocket-Unterstützung",
        "example": false
       },
       "certificate": {
        "type": "string",
        "description": "Zertifikat",
        "enum": [
         "default",
         "letsencrypt",
         "issuing"
        ],
        "example": "letsencrypt"
       },
       "caching": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean",
          "description": "Cache aktiv",
          "example": false
         },
         "time_minutes": {
          "type": "integer",
          "description": "Cache-Dauer",
          "example": 60
         },
         "size_mb": {
          "type": "integer",
          "description": "Cache-Größe",
          "example": 100
         }
        }
       },
       "access_list": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean",
          "description": "Zugriffsliste aktiv",
          "example": false
         },
         "mode": {
          "type": "string",
          "description": "allowlist = nur Einträge erlaubt, denylist = Einträge gesperrt",
          "enum": [
           "allowlist",
           "denylist"
          ],
          "example": "denylist"
         }
        }
       }
      }
     },
     "portmapper": {
      "type": "object",
      "properties": {
       "state": {
        "type": "string",
        "description": "Portmapper",
        "enum": [
         "off",
         "on",
         "disabling",
         "suspended_traffic_limit"
        ],
        "example": "off"
       }
      }
     },
     "traffic_mb": {
      "type": "object",
      "properties": {
       "in": {
        "type": "number",
        "description": "Eingehend",
        "example": 120.5
       },
       "out": {
        "type": "number",
        "description": "Ausgehend",
        "example": 830.2
       }
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "CdnDomainDetail": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "CDN-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "domain": {
      "type": [
       "string",
       "null"
      ],
      "description": "Domain",
      "example": "beispiel.ipv64.de"
     },
     "domain_id": {
      "type": "integer",
      "description": "Domain-ID",
      "example": 17597
     },
     "active": {
      "type": "boolean",
      "description": "CDN aktiv",
      "example": true
     },
     "pending": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "server_assignment",
        "dns",
        "config_deploy",
        "certificate",
        "server_move",
        "deletion"
       ],
       "example": "config_deploy"
      },
      "description": "Offene Arbeiten des CDN-Bots"
     },
     "dns_records_enabled": {
      "type": "boolean",
      "description": "Mindestens ein Record läuft über das CDN",
      "example": true
     },
     "server": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "name": {
        "type": "string",
        "description": "Name",
        "example": "CDN-FSN-1"
       },
       "hostname": {
        "type": "string",
        "description": "Hostname",
        "example": "cdn1.ipv64.net"
       },
       "ipv4": {
        "type": "string",
        "description": "IPv4",
        "example": "203.0.113.1"
       },
       "ipv6": {
        "type": "string",
        "description": "IPv6",
        "example": "2001:db8::1"
       }
      }
     },
     "proxy": {
      "type": "object",
      "properties": {
       "state": {
        "type": "string",
        "description": "Reverse Proxy",
        "enum": [
         "off",
         "on",
         "disabling"
        ],
        "example": "on"
       },
       "frontend": {
        "type": [
         "string",
         "null"
        ],
        "description": "http, https_redirect (HTTP wird auf HTTPS umgeleitet) oder http_and_https",
        "enum": [
         "http",
         "https_redirect",
         "http_and_https"
        ],
        "example": "https_redirect"
       },
       "backend": {
        "type": "object",
        "properties": {
         "scheme": {
          "type": "string",
          "description": "Protokoll zu deinem Server",
          "enum": [
           "http",
           "https"
          ],
          "example": "http"
         },
         "port": {
          "type": "integer",
          "description": "Port deines Servers",
          "example": 80
         }
        }
       },
       "websocket": {
        "type": "boolean",
        "description": "WebSocket-Unterstützung",
        "example": false
       },
       "certificate": {
        "type": "string",
        "description": "Zertifikat",
        "enum": [
         "default",
         "letsencrypt",
         "issuing"
        ],
        "example": "letsencrypt"
       },
       "caching": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean",
          "description": "Cache aktiv",
          "example": false
         },
         "time_minutes": {
          "type": "integer",
          "description": "Cache-Dauer",
          "example": 60
         },
         "size_mb": {
          "type": "integer",
          "description": "Cache-Größe",
          "example": 100
         }
        }
       },
       "access_list": {
        "type": "object",
        "properties": {
         "enabled": {
          "type": "boolean",
          "description": "Zugriffsliste aktiv",
          "example": false
         },
         "mode": {
          "type": "string",
          "description": "allowlist = nur Einträge erlaubt, denylist = Einträge gesperrt",
          "enum": [
           "allowlist",
           "denylist"
          ],
          "example": "denylist"
         }
        }
       }
      }
     },
     "portmapper": {
      "type": "object",
      "properties": {
       "state": {
        "type": "string",
        "description": "Portmapper",
        "enum": [
         "off",
         "on",
         "disabling",
         "suspended_traffic_limit"
        ],
        "example": "off"
       }
      }
     },
     "traffic_mb": {
      "type": "object",
      "properties": {
       "in": {
        "type": "number",
        "description": "Eingehend",
        "example": 120.5
       },
       "out": {
        "type": "number",
        "description": "Ausgehend",
        "example": 830.2
       }
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "mappings": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/CdnMapping"
      }
     }
    }
   },
   "AccessListEntry": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 7
     },
     "address": {
      "type": "string",
      "description": "IP oder Netz",
      "example": "198.51.100.0/24"
     }
    }
   },
   "Peer": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Peer-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Laptop"
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying",
       "deleting"
      ],
      "example": "ready"
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "site_to_site": {
      "type": "boolean",
      "description": "Als Site-to-Site markiert",
      "example": false
     },
     "ipv4": {
      "type": [
       "string",
       "null"
      ],
      "description": "Tunnel-IPv4 (CIDR)",
      "example": "10.7.0.2/32"
     },
     "ipv6": {
      "type": [
       "string",
       "null"
      ],
      "description": "Tunnel-IPv6 (CIDR)"
     },
     "dns_server": {
      "type": [
       "string",
       "null"
      ],
      "description": "DNS-Server in der Client-Config"
     },
     "endpoint": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fester Endpunkt des Peers"
     },
     "endpoint_port": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Port des Endpunkts"
     },
     "keepalive": {
      "type": "string",
      "description": "Keepalive hh:mm:ss",
      "example": "00:00:25"
     },
     "public_key": {
      "type": [
       "string",
       "null"
      ],
      "description": "Öffentlicher Schlüssel",
      "example": "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="
     },
     "has_preshared_key": {
      "type": "boolean",
      "description": "Preshared Key gesetzt",
      "example": true
     },
     "current_endpoint": {
      "type": [
       "string",
       "null"
      ],
      "description": "Zuletzt gesehene Adresse",
      "example": "198.51.100.7:51820"
     },
     "last_handshake": {
      "type": [
       "string",
       "null"
      ],
      "description": "Letzter Handshake"
     },
     "traffic_bytes": {
      "type": "object",
      "properties": {
       "in": {
        "type": "number",
        "description": "Eingehend",
        "example": 1024
       },
       "out": {
        "type": "number",
        "description": "Ausgehend",
        "example": 2048
       }
      }
     },
     "allowed_ips": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "integer",
         "description": "ID",
         "example": 3
        },
        "network": {
         "type": "string",
         "description": "Netz",
         "example": "192.168.50.0/24"
        }
       }
      },
      "description": "Nur in der Detailansicht: zusätzliche AllowedIPs der Client-Config"
     }
    }
   },
   "Gateway": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Gateway-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Gateway Frankfurt"
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "creating",
       "applying",
       "deleting"
      ],
      "example": "ready"
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "traffic_limited": {
      "type": "boolean",
      "description": "Durch Traffic-Limit gesperrt",
      "example": false
     },
     "server": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "name": {
        "type": "string",
        "description": "Name",
        "example": "VPN-FSN-1"
       },
       "hostname": {
        "type": "string",
        "description": "Hostname",
        "example": "vpn1.ipv64.net"
       },
       "location": {
        "type": "string",
        "description": "Standort",
        "example": "Falkenstein"
       }
      }
     },
     "listen_port": {
      "type": [
       "integer",
       "null"
      ],
      "description": "WireGuard-Port am Server",
      "example": 51820
     },
     "ipv4": {
      "type": [
       "string",
       "null"
      ],
      "description": "Gateway-Adresse IPv4 (CIDR)",
      "example": "10.7.0.1/24"
     },
     "ipv6": {
      "type": [
       "string",
       "null"
      ],
      "description": "Gateway-Adresse IPv6 (CIDR)"
     },
     "public_key": {
      "type": [
       "string",
       "null"
      ],
      "description": "Öffentlicher Schlüssel",
      "example": "HIgo9xNzJMWLKASShiTqIybxZ0U3wGLiUeJ1PKf8ykw="
     },
     "ospf": {
      "type": [
       "object",
       "null"
      ],
      "properties": {
       "area_id": {
        "type": "string",
        "description": "Area",
        "example": "0.0.0.0"
       },
       "ospf_version": {
        "type": "integer",
        "description": "Version",
        "example": 2
       },
       "cost": {
        "type": "integer",
        "description": "Kosten",
        "example": 10
       }
      }
     },
     "traffic_bytes": {
      "type": "object",
      "properties": {
       "in": {
        "type": "number",
        "description": "Eingehend",
        "example": 1024
       },
       "out": {
        "type": "number",
        "description": "Ausgehend",
        "example": 2048
       }
      }
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "peers": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Peer"
      },
      "description": "Nur in der Detailansicht"
     }
    }
   },
   "PublicIp": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 5
     },
     "ip": {
      "type": "string",
      "description": "Adresse",
      "example": "2001:db8:64::1a2b:3c4d"
     },
     "type": {
      "type": "string",
      "description": "Familie",
      "example": "ipv6"
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying"
      ],
      "example": "ready"
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     }
    }
   },
   "CloudRouter": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Router-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Home Lab"
     },
     "vrf": {
      "type": "string",
      "description": "Interner VRF-Name",
      "example": "vrf522a"
     },
     "traffic_limited": {
      "type": "boolean",
      "description": "Durch Traffic-Limit gesperrt",
      "example": false
     },
     "gateways": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Gateway"
      }
     },
     "public_ips": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/PublicIp"
      },
      "description": "Nur in der Detailansicht"
     }
    }
   },
   "PortForward": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 9
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Webserver"
     },
     "destination": {
      "type": "string",
      "description": "Ziel-IP im Tunnel",
      "example": "10.7.0.2"
     },
     "target_port": {
      "type": "integer",
      "description": "Ziel-Port",
      "example": 443
     },
     "protocol": {
      "type": "string",
      "description": "Protokoll",
      "enum": [
       "tcp",
       "udp"
      ],
      "example": "tcp"
     },
     "public_port": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Vom Server vergebener öffentlicher Port",
      "example": 30443
     },
     "public_ip": {
      "type": "string",
      "description": "server = Adresse des VPN-Servers, router = öffentliche IP des Routers",
      "enum": [
       "server",
       "router"
      ],
      "example": "server"
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying",
       "deleting"
      ],
      "example": "ready"
     }
    }
   },
   "Route": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 21
     },
     "destination": {
      "type": "string",
      "description": "Zielnetz",
      "example": "192.168.50.0/24"
     },
     "gateway": {
      "type": "string",
      "description": "Next Hop",
      "example": "10.7.0.2"
     },
     "distance": {
      "type": "integer",
      "description": "Distanz",
      "example": 1
     },
     "peer": {
      "type": [
       "string",
       "null"
      ],
      "description": "Peer-ID"
     },
     "system": {
      "type": "boolean",
      "description": "Vom System angelegt, nicht löschbar",
      "example": false
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying",
       "deleting"
      ],
      "example": "ready"
     }
    }
   },
   "FirewallRule": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "description": "ID",
      "example": 4
     },
     "chain": {
      "type": "string",
      "description": "Kette",
      "enum": [
       "forward",
       "input",
       "output"
      ],
      "example": "forward"
     },
     "action": {
      "type": "string",
      "description": "Aktion",
      "enum": [
       "accept",
       "drop"
      ],
      "example": "drop"
     },
     "family": {
      "type": "string",
      "description": "Familie",
      "enum": [
       "ipv4",
       "ipv6"
      ],
      "example": "ipv4"
     },
     "source": {
      "type": [
       "string",
       "null"
      ],
      "description": "Quelle",
      "example": "10.7.0.0/24"
     },
     "destination": {
      "type": [
       "string",
       "null"
      ],
      "description": "Ziel"
     },
     "disabled": {
      "type": "boolean",
      "description": "Deaktiviert",
      "example": false
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying",
       "deleting"
      ],
      "example": "ready"
     }
    }
   },
   "Dns64Client": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Client-ID",
      "example": "Ab3dEf6hIj9kLm2nOp5qRs8tUv1wXy4z"
     },
     "name": {
      "type": "string",
      "description": "Name",
      "example": "Familie"
     },
     "client_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "Kurzkennung in den Resolver-Adressen",
      "example": "k3x9m2"
     },
     "state": {
      "type": "string",
      "description": "Zustand",
      "enum": [
       "ready",
       "applying"
      ],
      "example": "ready"
     },
     "blocking_enabled": {
      "type": "boolean",
      "description": "Filter aktiv",
      "example": true
     },
     "blocklists": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "ads",
        "adult",
        "threats"
       ],
       "example": "ads"
      },
      "description": "Aktive Blocklisten"
     },
     "servers": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "location": {
         "type": "string",
         "description": "Standort",
         "example": "Falkenstein"
        },
        "hostname": {
         "type": "string",
         "description": "Hostname",
         "example": "dns64-1.ipv64.net"
        },
        "doh": {
         "type": "string",
         "description": "DNS over HTTPS",
         "example": "https://dns64-1.ipv64.net/k3x9m2"
        },
        "dot": {
         "type": "string",
         "description": "DNS over TLS",
         "example": "k3x9m2.dns64-1.ipv64.net"
        },
        "doq": {
         "type": "string",
         "description": "DNS over QUIC",
         "example": "k3x9m2.dns64-1.ipv64.net"
        },
        "ipv6": {
         "type": "string",
         "description": "Persönliche IPv6 des Resolvers",
         "example": "2001:db8:53::k3:x9m2"
        },
        "ipv4_shared": {
         "type": "string",
         "description": "Gemeinsame IPv4 (Zuordnung über Quell-Adressen)",
         "example": "203.0.113.53"
        },
        "ipv6_shared": {
         "type": "string",
         "description": "Gemeinsame IPv6",
         "example": "2001:db8:53::53"
        },
        "stamps": {
         "type": [
          "object",
          "null"
         ],
         "properties": {
          "doh": {
           "type": "string",
           "example": "sdns://AgcAAA..."
          },
          "dot": {
           "type": "string",
           "example": "sdns://AwcAAA..."
          },
          "doq": {
           "type": "string",
           "example": "sdns://BAcAAA..."
          }
         },
         "description": "DNS-Stamps, nur in der Detailansicht"
        }
       }
      }
     },
     "queries_total": {
      "type": "integer",
      "description": "Anfragen gesamt",
      "example": 12000
     },
     "queries_blocked": {
      "type": "integer",
      "description": "Davon blockiert",
      "example": 800
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ],
      "description": "Angelegt",
      "format": "date-time",
      "example": "2026-10-10T12:00:00+02:00"
     },
     "rules": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "integer",
         "description": "ID",
         "example": 3
        },
        "domain": {
         "type": "string",
         "description": "Domain",
         "example": "example.com"
        },
        "action": {
         "type": "string",
         "description": "Aktion",
         "enum": [
          "allow",
          "block"
         ],
         "example": "block"
        },
        "state": {
         "type": "string",
         "description": "Zustand",
         "enum": [
          "ready",
          "applying"
         ],
         "example": "ready"
        }
       }
      },
      "description": "Nur in der Detailansicht: eigene Allow- und Blockliste"
     },
     "sources": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "id": {
         "type": "string",
         "description": "Numerische ID bei kind ip, Record-Token bei kind record",
         "example": "8"
        },
        "kind": {
         "type": "string",
         "description": "Art",
         "enum": [
          "ip",
          "record"
         ],
         "example": "ip"
        },
        "address": {
         "type": "string",
         "description": "Adresse",
         "example": "203.0.113.10"
        },
        "fqdn": {
         "type": "string",
         "description": "Nur bei kind record",
         "example": "home.beispiel.ipv64.de"
        }
       }
      },
      "description": "Nur in der Detailansicht: Quell-Adressen für die gemeinsamen Resolver-IPs"
     }
    }
   }
  }
 }
}