Documentation · v1 · Bêta

API Metar

Les METAR, TAF et infos d'aérodrome du monde entier, décodés en français et en chiffres, en JSON. Gratuite, sans clé, appelable depuis n'importe quel site (CORS ouvert).

✳ 01. Démarrer

Un appel, une météo

Adresse de base : https://metar.wiski.pro/api/v1. Pas d'inscription, pas de clé, seulement des requêtes GET.

curl https://metar.wiski.pro/api/v1/metar/LFPG
  • Codes OACI : 4 lettres ou chiffres (LFPG, LFLL, KJFK), majuscules ou minuscules.
  • Plusieurs aérodromes : jusqu'à 10 par appel, dans le chemin (/metar/LFPG,LFLL) ou en paramètre (/metar?ids=LFPG,LFLL).
  • Format : JSON en UTF-8. Les clés sont en anglais, les textes en français sont dans fr, les valeurs chiffrées dans data.
  • Heures : ISO 8601 en UTC (2026-10-01T17:00:00.000Z).
  • Unités : vent en nœuds (_kt) et km/h (_kmh), visibilité en mètres (10000 = 10 km ou plus), nuages en pieds (_ft) et mètres (_m), pression en hPa.
  • Cache : les réponses sont gardées 2 minutes. Un METAR sort toutes les 30 à 60 minutes, inutile d'appeler plus souvent.

✳ 02. Routes

Cinq routes

RouteRenvoie
/api/v1La liste des routes et la version de l'API.
/api/v1/metar/{OACI}La dernière observation (METAR), décodée.
/api/v1/taf/{OACI}La prévision (TAF), découpée en périodes décodées.
/api/v1/station/{OACI}Nom, code IATA, pays, position et altitude de l'aérodrome.
/api/v1/aerodrome/{OACI}Les trois en un seul appel : station, METAR et TAF.

Chaque route de données répond avec la même enveloppe :

{
  "data": [ ... ],      // un objet par code trouvé, dans l'ordre demandé
  "missing": ["ZZZZ"]   // les codes sans réponse
}

Si aucun des codes demandés n'a de réponse, l'API renvoie une erreur 404.

✳ 03. METAR

Observation décodée

GET/api/v1/metar/{OACI}
{
  "data": [{
    "id": "LFPG",
    "name": "Paris/De Gaulle Arpt, ID, FR",
    "observed_at": "2026-10-01T17:00:00.000Z",
    "age_minutes": 27,
    "flight_category": { "code": "VFR", "fr": "Vol à vue possible" },
    "raw": "METAR LFPG 011700Z 32007KT CAVOK 20/09 Q1027 NOSIG",
    "fr": {
      "summary": "LFPG (VFR) · Vent du nord-ouest (320°), 7 nœuds (13 km/h) · CAVOK · 20 °C · QNH 1027 hPa",
      "wind": "Vent du nord-ouest (320°), 7 nœuds (13 km/h)",
      "visibility": "CAVOK : 10 km ou plus, pas de nuage sous 5 000 ft, pas de mauvais temps",
      "weather": null,
      "clouds": [],
      "temperature": "20 °C, point de rosée 9 °C, humidité 49 %",
      "pressure": "QNH 1027 hPa",
      "trend": "Pas de changement important prévu dans les 2 heures"
    },
    "data": {
      "wind": {
        "direction_deg": 320, "variable": false, "variable_from_deg": null, "variable_to_deg": null,
        "speed_kt": 7, "speed_kmh": 13, "gust_kt": null
      },
      "visibility_m": 10000,
      "cavok": true,
      "weather": null,
      "clouds": [],
      "temperature_c": 20,
      "dewpoint_c": 9,
      "humidity_pct": 49,
      "qnh_hpa": 1027
    },
    "position": { "lat": 49.015, "lon": 2.534, "elevation_m": 107 }
  }],
  "missing": []
}
ChampContenu
flight_category.codeVFR (vol à vue), MVFR (marginal), IFR (instruments), LIFR (très mauvais). Peut être null.
fr.summaryUne ligne de résumé, pratique pour un bot ou une notification.
fr.cloudsUne phrase par couche, de la plus basse à la plus haute.
data.weatherCode du temps présent tel qu'émis (-RA, BR, +TSRA…). Traduit dans fr.weather.
data.clouds[]{ cover, base_ft, base_m, type }. cover : FEW, SCT, BKN, OVC, VV… type : CB, TCU ou null.
data.wind.variabletrue si la direction est variable (VRB) ; variable_from_deg et variable_to_deg donnent l'écart quand il est indiqué (ex. 270V330).
age_minutesMinutes écoulées depuis l'observation, au moment de la réponse.

✳ 04. TAF

Prévision par périodes

GET/api/v1/taf/{OACI}
{
  "data": [{
    "id": "LFPG",
    "issued_at": "2026-10-01T17:00:00.000Z",
    "valid_from": "2026-10-01T18:00:00.000Z",
    "valid_to": "2026-10-03T00:00:00.000Z",
    "raw": "TAF LFPG 011700Z 0118/0300 32008KT CAVOK ...",
    "periods": [{
      "change": null,
      "probability": null,
      "from": "2026-10-01T18:00:00.000Z",
      "to": "2026-10-01T21:00:00.000Z",
      "becoming_by": null,
      "fr": {
        "title": "Prévision de base",
        "wind": "Vent du nord-ouest (320°), 8 nœuds (15 km/h)",
        "visibility": "10 km ou plus",
        "weather": null,
        "clouds": ["Pas de nuage significatif"]
      },
      "data": {
        "wind": { "direction_deg": 320, "variable": false, "speed_kt": 8, "speed_kmh": 15, "gust_kt": null, ... },
        "visibility_m": 10000,
        "weather": null,
        "clouds": [{ "cover": "NSC", "base_ft": null, "base_m": null, "type": null }]
      }
    }]
  }],
  "missing": []
}
ChampContenu
changenull (prévision de base), FM (à partir de), BECMG (devient), TEMPO (temporairement).
probability30 ou 40 (%) pour les groupes PROB, sinon null.
becoming_byPour BECMG : heure à laquelle le changement est terminé.
Champs absentsUne période ne contient que ce qui change : les autres valeurs valent null.

✳ 05. Station

L'aérodrome

GET/api/v1/station/{OACI}
{
  "data": [{
    "id": "LFPG",
    "iata": "CDG",
    "name": "Paris/De Gaulle Arpt",
    "country": "FR",
    "lat": 49.015,
    "lon": 2.534,
    "elevation_m": 107,
    "reports": ["METAR", "TAF"]
  }],
  "missing": []
}

reports indique les messages publiés par l'aérodrome : un petit terrain peut avoir un METAR sans TAF.

✳ 06. Aérodrome

Tout en un appel

GET/api/v1/aerodrome/{OACI}
{
  "data": [{
    "id": "LFLS",
    "station": { ... },   // comme /station, ou null
    "metar":   { ... },   // comme /metar, ou null
    "taf":     { ... }    // comme /taf, ou null (pas de TAF publié)
  }],
  "missing": []
}

✳ 07. Erreurs

Quand ça coince

Toutes les erreurs ont la même forme, avec un message en français :

{
  "error": {
    "code": "invalid_id",
    "message": "« PARIS » n'est pas un code OACI (4 lettres ou chiffres, ex. LFPG).",
    "docs": "https://metar.wiski.pro/docs"
  }
}
HTTPcodeCause
400missing_idsAucun code OACI dans la requête.
400invalid_idUn code ne fait pas 4 lettres ou chiffres.
400too_many_idsPlus de 10 codes dans un appel.
404not_foundAucun des codes n'a de données (code inconnu, ou aérodrome sans message).
404unknown_routeRoute inexistante.
405method_not_allowedAutre méthode que GET.
502source_unavailableaviationweather.gov ne répond pas (après un second essai). Réessaie un peu plus tard.
500server_errorErreur inattendue de l'API.

✳ 08. Exemples

Dans ton code

JavaScript (navigateur ou Node)

const res = await fetch('https://metar.wiski.pro/api/v1/metar/LFPG,LFLL');
const { data, missing } = await res.json();
for (const m of data) console.log(m.fr.summary);

Python

import requests

r = requests.get("https://metar.wiski.pro/api/v1/aerodrome/LFLS", timeout=10)
a = r.json()["data"][0]
print(a["station"]["name"], a["metar"]["flight_category"]["code"])
print(a["metar"]["data"]["wind"]["speed_kt"], "kt")

Bot Discord (discord.js)

const r = await fetch(`https://metar.wiski.pro/api/v1/metar/${code}`);
const body = await r.json();
await interaction.reply(r.ok ? body.data[0].fr.summary : body.error.message);

✳ 09. Conditions

À savoir

  • Gratuite et en bêta : la v1 garde ses champs actuels ; un changement incompatible passerait par une /api/v2.
  • Pas pour préparer un vol : outil de découverte. Pour voler, utilise les sources officielles (Météo-France aéronautique, AEROWEB, SIA).
  • Données : service météo aviation de la NOAA (aviationweather.gov), traduites par Metar.
  • Usage raisonnable : garde les réponses au moins 2 minutes chez toi, et regroupe tes aérodromes dans un seul appel (jusqu'à 10).
  • Un souci, une idée ? Écris-moi depuis Wiski.pro.