TAF
TAFs (Terminal Aerodrome Forecasts) sind strukturierte Vorhersagen für einen bestimmten Flughafen und seine unmittelbare Umgebung, die in der Regel etwa fünf nautische Meilen um den Flugplatz abdecken. Standard-TAFs werden viermal täglich um 00Z, 06Z, 12Z und 18Z herausgegeben und sind je nach Station 24 oder 30 Stunden gültig. Jeder TAF beschreibt erwarteten Wind, Sicht, Wolkenschichten, Wettererscheinungen und Flugwetterkategorien in zeitlich festgelegten Vorhersagegruppen wie FROM, TEMPO und BECMG. Piloten, Flugdienstberater und Flugplaner nutzen diese Vorhersagen, um bei der Erstellung operativer Pläne die erwarteten Bedingungen an Abflug-, Ziel- und Ausweichflughäfen zu beurteilen. Viele kleine Flughäfen veröffentlichen nur METAR — ein 404 beim TAF ist häufig und bedeutet nicht, dass der Flughafen unbekannt ist.
Anfrage
Voraussetzungen
x-api-key bei jeder Anfrage (Direktabonnement). Mehr erfahren →Senden Sie eine GET-Anfrage mit dem ICAO-Code des Flughafens im Pfad. Optionale Query-Flags steuern die Dekodierung.
https://data.skylinkapi.com/v3.1/weather/taf/{icao}| Parameter | Typ | Erforderlich | Standard | Beschreibung |
|---|---|---|---|---|
icao | string | Ja | - | 4-stelliger ICAO-Code — Suche, z. B. KJFK |
parsed | boolean | Nein | false | Dekodierte Vorhersageperioden unter einem parsed-Schlüssel hinzufügen |
Antwort
Rohdaten (Standard)
{
"raw": "TAF KJFK 072334Z 0800/0906 35014G20KT P6SM FEW050 SCT100 FM080600 03011KT P6SM SCT025 ...",
"icao": "KJFK",
"airport_name": "John F. Kennedy International Airport",
"timestamp": "2026-06-08T23:45:12Z"
}| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
raw | string | Ja | Vollständiger TAF-String im Originalwortlaut |
icao | string | Ja | ICAO-Code |
airport_name | string | Ja | Name des Flughafens |
timestamp | string (ISO 8601) | Ja | Zeitpunkt, zu dem die API diese Daten abgerufen hat — nicht der Ausgabezeitpunkt der Vorhersage |
Dekodiert (parsed=true)
{
"raw": "TAF KJFK 061933Z 0620/0724 ...",
"icao": "KJFK",
"airport_name": "John F. Kennedy International Airport",
"timestamp": "2026-06-06T23:09:48Z",
"parsed": {
"start_time": "2026-06-06T22:00:00+02:00",
"end_time": "2026-06-08T02:00:00+02:00",
"forecast": [
{
"type": "FROM",
"start_time": "2026-06-06T22:00:00+02:00",
"end_time": "2026-06-07T01:00:00+02:00",
"wind": { "direction": 200, "speed": 14, "gust": null, "variable": [] },
"visibility": { "value": null, "repr": "P6" },
"clouds": [
{ "type": "SCT", "base": 70, "repr": "SCT070" },
{ "type": "BKN", "base": 250, "repr": "BKN250" }
],
"wx_codes": [],
"flight_rules": "VFR",
"probability": null,
"turbulence": [],
"icing": []
},
{
"type": "TEMPO",
"start_time": "2026-06-07T01:00:00+02:00",
"end_time": "2026-06-07T05:00:00+02:00",
"wind": { "direction": 290, "speed": 25, "gust": 45, "variable": [] },
"visibility": { "value": 3, "repr": "3" },
"clouds": [
{ "type": "SCT", "base": 25, "repr": "SCT025" },
{ "type": "BKN", "base": 50, "repr": "BKN050CB" }
],
"wx_codes": [
{ "repr": "TSRA", "value": "Thunderstorm Rain" },
{ "repr": "BR", "value": "Mist" }
],
"flight_rules": "MVFR",
"probability": null,
"turbulence": [],
"icing": []
}
]
}
}| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
parsed | object | Ja (bei parsed=true) | Fehlt bei parsed=false — nicht null |
parsed.start_time | string (ISO 8601) | Ja | Beginn des TAF-Gültigkeitszeitraums (DDHH/DDHH im Rohtext) |
parsed.end_time | string (ISO 8601) | Ja | Ende des TAF-Gültigkeitszeitraums |
parsed.forecast | array | Ja | Vorhersageperioden in chronologischer Reihenfolge — siehe Arten von Vorhersageperioden |
parsed.forecast[].type | string | Ja (pro Element) | FROM, TEMPO oder BECMG |
parsed.forecast[].start_time | string (ISO 8601) | Ja (pro Element) | Zeitpunkt, ab dem diese Gruppe gilt |
parsed.forecast[].end_time | string (ISO 8601) | Ja (pro Element) | Zeitpunkt, zu dem diese Gruppe endet |
parsed.forecast[].wind | object | Ja (pro Element) | Gleiche Struktur wie METAR parsed.wind |
parsed.forecast[].visibility | object | Ja (pro Element) | Gleiche Struktur wie METAR parsed.visibility |
parsed.forecast[].clouds | array | Ja (pro Element) | Gleiche Struktur wie METAR parsed.clouds — Codes für den Bedeckungsgrad |
parsed.forecast[].wx_codes | array | Ja (pro Element) | Erwartete Wettererscheinungen — { repr, value }[] |
parsed.forecast[].flight_rules | string | Ja (pro Element) | Erwartete Flugwetterkategorie für diese Gruppe |
parsed.forecast[].probability | object | null | Ja (Schlüssel immer vorhanden) | Bei PROB30/PROB40-Gruppen befüllt — siehe unten |
parsed.forecast[].turbulence | array | Ja (pro Element) | Intensität atmosphärischer Turbulenz, sofern angegeben — [], wenn keine |
parsed.forecast[].icing | array | Ja (pro Element) | Intensität der Vereisung der Flugzeugzelle, sofern angegeben — [], wenn keine |
Objektschemas und Nullbarkeit
Jedes Objekt in parsed.forecast[] enthält in jeder Periode dieselben Schlüssel — für wind, visibility, clouds und wx_codes gelten dieselben Regeln wie bei der Nullbarkeit von METAR.
| Feld | Typ | Erforderlich | Null / leer | Hinweise |
|---|---|---|---|---|
parsed.forecast[].wind | object | Ja | Immer vorhanden | Gleiche Form wie METAR parsed.wind |
parsed.forecast[].visibility | object | Ja | Immer vorhanden | value: null häufig bei P6SM (repr: "P6") |
parsed.forecast[].clouds | array | Ja | [] möglich | Gleiche Elementform wie bei METAR |
parsed.forecast[].wx_codes | array | Ja | [], wenn keine | Gleiche { repr, value }-Elementform wie bei METAR |
parsed.forecast[].probability | object | null | Ja | null bei den meisten Gruppen | Objekt bei PROB30/PROB40 — siehe unten |
parsed.forecast[].turbulence | array | Ja | [], wenn nicht angegeben | Nie null |
parsed.forecast[].icing | array | Ja | [], wenn nicht angegeben | Nie null |
Bei parsed=false fehlt der Schlüssel parsed vollständig.
Wahrscheinlichkeit bei PROB-Gruppen
Im Roh-TAF kennzeichnen PROB30 und PROB40 probabilistische Teilperioden (30 % bzw. 40 % Eintrittswahrscheinlichkeit). Im JSON des Produktivbetriebs erscheinen sie als FROM- oder TEMPO-Eintrag mit befülltem probability-Objekt — es gibt keinen separaten type: "PROB" (überprüft an KORD, EGLL, EDDF).
"probability": {
"repr": "30",
"value": 30,
"spoken": "three zero"
}| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
repr | string | Ja | Roh-Token: "30" oder "40" |
value | integer | Ja | 30 oder 40 |
spoken | string | Ja | Gesprochene Form aus der Meldung |
Wenn die Gruppe nicht probabilistisch ist, ist probability null.
Turbulenz, Vereisung und Arten von VorhersageperiodenAbschnitt aufklappen
Turbulenz- und Vereisungsgruppen
Die meisten Vorhersageperioden liefern "turbulence": [] und "icing": []. Wenn der zugrunde liegende TAF TURB- oder ICE-Gruppen enthält, enthält jedes Array ein oder mehrere Objekte mit mindestens repr (Roh-Token) und value (menschenlesbare Intensität) — dasselbe { repr, value }-Muster wie bei wx_codes. Zusätzliche Höhenschlüssel können erscheinen, wenn die Meldung eine vertikale Schicht angibt; behandeln Sie unbekannte Schlüssel als vorwärtskompatibel.
"turbulence": [{ "repr": "MOD", "value": "Moderate" }],
"icing": []Arten von Vorhersageperioden
Durchlaufen Sie parsed.forecast[] chronologisch: zuerst die aktive FROM-Basis, dann die überlappenden Modifikatoren.
| TAF-Token | type im JSON | Zeitfelder | Bedeutung |
|---|---|---|---|
Anfangsgruppe / FM | FROM | start_time → end_time | Basisbedingungen. Jede FM-Gruppe ersetzt ab start_time alles Vorherige |
TEMPO | TEMPO | start_time → end_time | Vorübergehende Schwankungen innerhalb der Basis — als Hinweis anzeigen, nicht als Ersatz |
BECMG | BECMG | start_time → end_time | Allmähliche Änderung hin zu den Werten dieser Gruppe bis end_time |
PROB30 / PROB40 | FROM oder TEMPO + probability | wie beim übergeordneten Typ | Probabilistische Teilperiode — probability in der Zeile ist nicht null |
Perioden für eine Abflugzeit auslesen
- Filtern Sie
parsed.forecast[]nachtype == "FROM"undstart_time <= departure <= end_time— Basis. - Sammeln Sie überlappende
TEMPO-,BECMG- und probabilistische Zeilen — Modifikatoren. - Zeigen Sie die flight_rules der Basis deutlich an; listen Sie Modifikatoren separat auf.
- Ungünstigster Fall über den gesamten TAF: höchster Rang der flight_rules unter allen
FROM-Gruppen.
Beispiel für KORD: Die Basis-FROM-Gruppe kann VFR sein, während ein überlappendes TEMPO MVFR mit -SHRA zeigt — zeigen Sie beides an.
Client-Typen
Kopieren Sie sie in Ihr Projekt. Die Nullbarkeit entspricht Objektschemas und Nullbarkeit und der Nullbarkeit von METAR für gemeinsam genutzte verschachtelte Objekte.
"""TAF response and departure-summary types - matches weather-taf field tables."""from __future__ import annotationsfrom dataclasses import dataclassfrom typing import LiteralFlightRules = Literal["VFR", "MVFR", "IFR", "LIFR"]TafPeriodType = Literal["FROM", "TEMPO", "BECMG"]@dataclassclass TafRequest: """Path/query input for GET /weather/taf/{icao}.""" icao: str parsed: bool = False@dataclassclass TafWind: direction: int speed: int gust: int | None variable: list[int]@dataclassclass TafVisibility: value: float | None repr: str@dataclassclass TafCloudLayer: type: str base: int repr: str@dataclassclass TafWxCode: repr: str value: str@dataclassclass TafProbability: repr: str value: Literal[30, 40] spoken: str@dataclassclass TafPeriod: type: TafPeriodType start_time: str end_time: str wind: TafWind visibility: TafVisibility clouds: list[TafCloudLayer] wx_codes: list[TafWxCode] flight_rules: FlightRules probability: TafProbability | None turbulence: list[object] icing: list[object]@dataclassclass TafParsed: start_time: str end_time: str forecast: list[TafPeriod]@dataclassclass TafResponse: raw: str icao: str airport_name: str timestamp: str parsed: TafParsed | None = None@dataclassclass TafModifierSummary: type: TafPeriodType category: FlightRules probability: int | None wx: list[str]@dataclassclass TafDepartureSummary: """Shape returned by taf_at_departure() in the fetch example.""" icao: str valid_to: str baseline_category: FlightRules | None modifiers: list[TafModifierSummary] worst_from_category: FlightRules | NoneTafResponse / TafParsed / TafPeriod entsprechen dem JSON der API. TafDepartureSummary ist am Anfang jedes Tabs im Codebeispiel definiert.
Integration
Vorhersageperioden zu einer Abflugzeit abrufen, cachen und interpretieren.
Das Beispiel cacht jeden TAF fünfzehn Minuten lang (TAFs werden viermal täglich neu herausgegeben), verwendet Timeouts von 10 s / 15 s für Verbindungsaufbau/Lesen, wählt zu einer Abflugzeit die aktive FROM-Gruppe aus und listet überlappende TEMPO/BECMG-Modifikatoren auf.
import osimport timefrom dataclasses import dataclassfrom datetime import datetime, timezonefrom typing import Literalimport requests# TafDepartureSummary - helper return type. Full wire types (TafResponse, TafPeriod, …)# are in the Client types section on the TAF docs page.FlightRules = Literal["VFR", "MVFR", "IFR", "LIFR"]TafPeriodType = Literal["FROM", "TEMPO", "BECMG"]@dataclassclass TafModifierSummary: type: TafPeriodType category: FlightRules probability: int | None wx: list[str]@dataclassclass TafDepartureSummary: icao: str valid_to: str baseline_category: FlightRules | None modifiers: list[TafModifierSummary] worst_from_category: FlightRules | NoneHEADERS = { "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}BASE = "https://data.skylinkapi.com/v3.1"CACHE: dict[str, tuple[dict, float]] = {}TAF_TTL = 900CATEGORY_RANK = {"VFR": 0, "MVFR": 1, "IFR": 2, "LIFR": 3}def parse_time(iso: str) -> datetime: return datetime.fromisoformat(iso.replace("Z", "+00:00"))def fetch_taf(icao: str) -> dict | None: cache_key = f"taf:{icao}:parsed" cached = CACHE.get(cache_key) if cached and time.time() < cached[1]: return cached[0] try: r = requests.get( f"{BASE}/weather/taf/{icao}", headers=HEADERS, params={"parsed": "true"}, timeout=(10, 15), ) except requests.Timeout as exc: raise RuntimeError(f"SkyLink timeout fetching TAF for {icao}") from exc if r.status_code == 404: return None r.raise_for_status() data = r.json() CACHE[cache_key] = (data, time.time() + TAF_TTL) return datadef taf_at_departure(icao: str, departure: datetime | None = None) -> TafDepartureSummary | None: taf = fetch_taf(icao) if not taf: return None at = departure or datetime.now(timezone.utc) forecast = taf["parsed"]["forecast"] baseline = next( ( p for p in forecast if p["type"] == "FROM" and parse_time(p["start_time"]) <= at <= parse_time(p["end_time"]) ), None, ) modifiers = [ TafModifierSummary( type=p["type"], category=p["flight_rules"], probability=(p["probability"] or {}).get("value"), wx=[w["repr"] for w in p["wx_codes"]], ) for p in forecast if p is not baseline and parse_time(p["start_time"]) <= at <= parse_time(p["end_time"]) ] from_groups = [p for p in forecast if p["type"] == "FROM"] worst = ( max(from_groups, key=lambda p: CATEGORY_RANK.get(p["flight_rules"], -1))["flight_rules"] if from_groups else None ) return TafDepartureSummary( icao=icao, valid_to=taf["parsed"]["end_time"], baseline_category=baseline["flight_rules"] if baseline else None, modifiers=modifiers, worst_from_category=worst, )if __name__ == "__main__": import json from dataclasses import asdict summary = taf_at_departure("KJFK") print(json.dumps(asdict(summary), indent=2) if summary else "TAF not available")Schritt-für-Schritt-Erklärung der Periodenschichtung: Schichtung der TAF-Perioden.
Hinweise zur Implementierung
TEMPO- und probabilistische Gruppen lesen. TEMPO legt sich über die aktive FROM-Basis. PROB30/PROB40 erscheinen als Zeilen, in denen probability nicht null ist — prüfen Sie probability.value, nicht einen separaten type. Siehe Arten von Vorhersageperioden.
TAFs werden viermal täglich aktualisiert, um 00Z, 06Z, 12Z und 18Z. Ein Caching von 15–30 Minuten ist angemessen.
404 ohne TAF. Viele Plätze der Allgemeinen Luftfahrt (GA) veröffentlichen nur METAR. Behandeln Sie ein 404 beim TAF als fehlende Vorhersagedaten, nicht als fehlgeschlagene Anfrage.
Kombination mit METAR. Rufen Sie beide parallel ab. Verwenden Sie die flight_rules aus dem METAR für die aktuellen Bedingungen und die ungünstigsten FROM-flight_rules über den gesamten TAF als schlechteste erwartete Bedingungen.
Fehlerantworten
Hierher gehören nur TAF-spezifische Fehler. Gemeinsame Fehler: Fehlerbehandlung. 404 bei METAR vs. TAF im Produktivbetrieb: Wenn Wetterdaten fehlen.
404 — kein TAF für diesen ICAO-Code
{
"detail": "No current TAF forecast available for KOXB. Weather station may not issue TAF reports or may be temporarily offline."
}Häufiger Fall: Der Flughafen hat ein METAR, aber keinen TAF. Rufen Sie das METAR wie gewohnt ab; überspringen Sie den TAF und beschriften Sie die UI mit Vorhersage nicht verfügbar.
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Path Parameters
4-letter ICAO airport code
4 <= length <= 4Query Parameters
Include parsed/decoded TAF fields alongside raw text
falseResponse Body
application/json
application/json
curl -X GET "https://data.skylinkapi.com/v3.1/weather/taf/KJFK"{
"raw": "TAF KJFK 271720Z 2718/2824 16012KT P6SM FEW025 SCT250 FM272100 18010KT P6SM SCT025 BKN250",
"icao": "KJFK",
"airport_name": "John F Kennedy International Airport",
"timestamp": "2025-09-27T12:00:00Z"
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}Siehe auch: METAR · Anwendungsfälle · Fehler · Produktivbetrieb