Open-Meteo(オープンメテオ)は、緯度と経度を指定するだけで天気予報や過去の気象データをJSONで返すオープンソースの天気APIです。スイスのOpenMeteo GmbHが運営しています。非商用なら登録もAPIキーも要らず、URLを1本送れば結果が返ります。一方で、広告を載せたサイトや社内の業務システムで使うと商用利用に当たり、有料プランが必要です。本記事では、動作を確認したcurl・Python・JavaScriptのコード、無料枠の上限と商用利用の線引き、日本の座標で既定のbest_matchがどのモデルを使っているか、アメダスの観測値と比べた誤差、過去データの取り方を、2026年10月時点の公式情報と実測で整理します。
まとめ:Open-Meteoの利用条件とAPI選択
- 非商用なら無料・キー不要:上限は1分600回・1時間5,000回・1日10,000回・1か月300,000回です。
- 広告付きサイトや業務利用は商用:有料プランを契約し、専用ドメイン
customer-api.open-meteo.comにapikeyを付けて呼び出します。 - 東京の既定値は3日余り先まで気象庁MSM:その先は気象庁GSMではなくECMWF IFS(9km)に切り替わります。気象庁のモデルだけでつなぎたいときは
/v1/jmaを使います。 - 精度は「何日前の予報か」で測る:アメダス東京との9日間の比較では、24時間前の予報の気温誤差(MAE)が約1.0℃、72時間前の予報では既定値が1.43℃でした。
- timezoneは必ず指定する:省略するとGMT基準で日付を切るため、日別の最高気温や降水量の値が変わる場合があります。
- 過去データはHistorical Weather API:ERA5で1940年まで遡れます。予報の当たり方を測るときはPrevious Model Runs APIを使います。
- データはCC BY 4.0:表示する画面やレポートには出典のクレジットが必要です。
Open-Meteoの仕組みと主なエンドポイント
Open-Meteoは、ECMWF・DWD・NOAA・Météo-France・JMAなど各国の気象機関が公開する数値予報モデルの出力を集め、座標を指定すると該当地点の値を返す形に整えたサービスです。公式の料金ページによると30以上のモデルを扱い、既定のbest_matchは指定した座標で最も解像度の高いモデルを自動で選びます。ソースコードはAGPLv3でGitHubに公開されており、自前のサーバーで動かすこともできます。
用途ごとにドメインとパスが分かれています。
| API | エンドポイント | 主な用途 |
|---|---|---|
| Forecast | api.open-meteo.com/v1/forecast | 最大16日先の予報 |
| JMA | api.open-meteo.com/v1/jma | 気象庁モデルの予報 |
| Historical Weather | archive-api.open-meteo.com/v1/archive | 1940年以降の過去データ |
| Historical Forecast | historical-forecast-api.open-meteo.com/v1/forecast | 過去の予報値 |
| Previous Model Runs | previous-runs-api.open-meteo.com/v1/forecast | 1〜7日前に出た予報 |
| Geocoding | geocoding-api.open-meteo.com/v1/search | 地名から座標 |
| Marine | marine-api.open-meteo.com/v1/marine | 波高など海洋 |
| Air Quality | air-quality-api.open-meteo.com/v1/air-quality | PM2.5など大気質 |
| Flood | flood-api.open-meteo.com/v1/flood | 河川流量 |
Open-Meteo APIの使い方:curl・Python・JavaScriptの実装例
公式ドキュメント画面によるAPI URL生成とCSV出力
コードを書く前に、公式ドキュメントの画面で試せます。地点(緯度・経度、または地名検索)と取得したい変数にチェックを入れると、ページ下部の「API URL」欄にリクエストURLが組み上がり、同じ画面にグラフとPython・TypeScript・Swiftのコード例が出ます。「Download CSV」「Download XLSX」でファイルとしても保存できるので、ExcelやBIツールで一度眺めるだけならこれで足ります。組み上がったURLをそのまま次のcurlやfetchに貼れば、画面で選んだ条件のまま実装に移れます。
curlによる現在の気温・天気コードの取得
もっとも短い呼び出しは、座標と取得したい変数を並べるだけです。東京(新宿付近)の現在の気温・風速・天気コードを日本時間で取得します。
curl "https://api.open-meteo.com/v1/forecast?latitude=35.6895&longitude=139.6917¤t=temperature_2m,wind_speed_10m,weather_code&timezone=Asia/Tokyo"
2026年10月14日15時24分(日本時間)に実行した応答のうち、値はcurrent、単位はcurrent_unitsに入ります。currentは観測値ではなく、15分間隔の予報モデルのデータに基づく値です。風速の既定単位はkm/hなので、m/sで扱いたいときはwind_speed_unit=msを付けます。
"current_units": {"time":"iso8601","interval":"seconds","temperature_2m":"°C","wind_speed_10m":"km/h","weather_code":"wmo code"},
"current": {"time":"2026-10-14T15:15","interval":900,"temperature_2m":22.2,"wind_speed_10m":2.5,"weather_code":1}
データ出典:Weather data by Open-Meteo.com(CC BY 4.0)
Python公式SDK(openmeteo-requests)によるDataFrame変換
Pythonでは公式SDKのopenmeteo-requests(2026年1月19日公開の1.7.5が2026年10月14日時点の最新)を使います。応答はJSONではなくFlatBuffers形式で受け取り、公式READMEはこの方式を長い時系列を大量に扱う場面で効率がよいと説明しています。変数はparamsに書いた順番でVariables(0)、Variables(1)…として取り出す点に注意してください。
pip install openmeteo-requests requests-cache retry-requests pandas
import openmeteo_requests
import pandas as pd
client = openmeteo_requests.Client()
params = {
"latitude": 35.6895,
"longitude": 139.6917,
"hourly": ["temperature_2m", "precipitation", "weather_code"],
"timezone": "Asia/Tokyo",
"forecast_days": 3,
}
response = client.weather_api("https://api.open-meteo.com/v1/forecast", params=params)[0]
hourly = response.Hourly()
# 変数は params["hourly"] に書いた順で Variables(0), (1), (2) になる
df = pd.DataFrame({
"time": pd.date_range(
start=pd.to_datetime(hourly.Time(), unit="s", utc=True),
end=pd.to_datetime(hourly.TimeEnd(), unit="s", utc=True),
freq=pd.Timedelta(seconds=hourly.Interval()),
inclusive="left",
).tz_convert("Asia/Tokyo"),
"temperature_2m": hourly.Variables(0).ValuesAsNumpy(),
"precipitation": hourly.Variables(1).ValuesAsNumpy(),
"weather_code": hourly.Variables(2).ValuesAsNumpy(),
})
print(df.head(3))
Python 3.14.6・pandas 3.0.6の環境で実行すると、3日分72行のDataFrameが日本時間の時刻付きで得られました。本番では、公式READMEのとおりrequests_cache.CachedSession(".cache", expire_after=3600)をretry(..., retries=5, backoff_factor=0.2)で包み、openmeteo_requests.Client(session=...)に渡します。同じ条件(座標・変数・期間)のリクエストはキャッシュから返り、一時的な失敗はリトライで吸収されます(1.7.5で動作確認)。DataFrameの基本操作はPandasとは?できること・使い方とPandas 3.0の変更点を解説で整理しています。
JavaScriptのfetchによる日別予報の取得
ブラウザやNode.jsでは、SDK(npmのopenmeteo 1.2.3)を使わずにfetchだけでも十分です。札幌の3日間の最高・最低気温と天気コードを取得する例です(Node.js 26.5.0で動作確認)。トップレベルのawaitを使っているので、Node.jsでは.mjsファイルとして実行し、ブラウザではtype="module"を指定したscript内に置きます。
const params = new URLSearchParams({
latitude: "43.0667",
longitude: "141.35",
daily: "temperature_2m_max,temperature_2m_min,weather_code",
timezone: "Asia/Tokyo",
forecast_days: "3",
});
const res = await fetch(`https://api.open-meteo.com/v1/forecast?${params}`);
const data = await res.json();
if (!res.ok) throw new Error(`HTTP ${res.status}: ${data.reason}`);
data.daily.time.forEach((day, i) => {
console.log(day, data.daily.temperature_2m_max[i], data.daily.temperature_2m_min[i], data.daily.weather_code[i]);
});
timezoneの省略による日別集計値の違い
見落としやすいのがtimezoneです。省略すると応答はGMT基準になり、dailyの集計もGMTの0時、つまり日本時間の9時で日付を区切ります。時刻表示がずれるだけでなく、日別の最高気温や降水量が「日本時間9時から翌9時まで」の値になります。2026年9月26日7時10分(日本時間)に、同じ東京の座標でtimezoneだけを変えた2本のリクエストを続けて送ったところ、同じ「9月26日」の値が次のように食い違いました。
| 指定 | 9月26日の最高気温 | 9月26日の降水量 |
|---|---|---|
| timezone=Asia/Tokyo | 21.9℃ | 27.8mm |
| 指定なし(GMT) | 19.5℃ | 18.9mm |
データ出典:Weather data by Open-Meteo.com(CC BY 4.0)
2026年10月14日に同じ2本を送り直したときは、10月14日・15日とも値が一致しました。降水量は集計窓から外れる当日0〜9時と、新たに入る翌日0〜9時の雨量が違えば差が出ます。最高気温も、それぞれの集計窓内の最大値で決まります。差が出るかどうかは天気次第なので、日本国内だけを扱うならtimezone=Asia/Tokyo、利用者の現在地で切り替えるならtimezone=auto(座標から現地のタイムゾーンを自動判定)を常に付けます。
予報日数はforecast_daysで0〜16日(既定7日)、直近のアーカイブ済み予報も並べたいときはpast_daysで最大92日まで指定できます。範囲外を指定するとHTTP 400で{"reason":"Forecast days is invalid. Allowed range 0 to 16. ...","error":true}という形のJSONが返るので、reasonをログに残すと原因をすぐ特定できます。
Open-Meteoの料金:無料枠の上限と商用利用の線引き
無料枠(非商用)の上限は1日10,000回
無料のAPIは非商用に限り、1分600回・1時間5,000回・1日10,000回・1か月300,000回までです(利用規約と料金ページ)。稼働率の保証はなく、規約では乱用するアプリやIPアドレスを遮断する権利を留保しています。1地点を10分おきに取得すると1日144リクエストです。ただし、10変数超や2週間超の取得は、1リクエストでも複数コールとして計算されます。数千地点を一斉に取得するバッチは1分600回の上限に当たるため、呼び出しの間隔を空けて待つ設計が要ります。考え方はAPIレート制限(レートリミット)とは?5方式の比較と429設計・分散実装【2026年版】が参考になります。
商用利用に当たる使い方・当たらない使い方
非商用の定義はクリエイティブ・コモンズの考え方に従い、利用規約に具体例が挙がっています。判断に迷いやすいのは、個人ブログでも広告を載せていれば商用に当たる点と、社内の非公開の研究・分析も商用に当たる点です。
| 非商用(無料APIで可) | 商用(有料プランが必要) |
|---|---|
| 購読・広告のない個人や非営利のサイト・アプリ | 購読制や広告付きのサイト・アプリ |
| 個人のホームオートメーション | 商用製品や販促への組み込み |
| 公的機関による公開の研究 | 企業内での非公開の研究 |
| 教育用コンテンツ | 業務システムでの利用全般 |
有料プランのコール数と専用ドメインへの切り替え
商用プランはStandard(月100万回)、Professional(月500万回)、Enterprise(月5,000万回超)の3段階で、1分・1時間・1日の上限はありません。契約するとAPIキーが発行されます。Forecast APIの場合は、呼び出し先をapi.open-meteo.comからcustomer-api.open-meteo.comに変え、&apikey=を付けるだけで移行できます。パラメータの書き方は無料版と同じです。ほかのAPIも同じ要領で、Historical Weather APIならcustomer-archive-api.open-meteo.comのようにホスト名の先頭にcustomer-を付けます。ただし、本記事で扱うHistorical Weather API・Historical Forecast API・Previous Model Runs APIはStandardに含まれず、商用で使うにはProfessional以上が必要です。
月額は固定で、呼び出し数に応じた超過課金はありません。公式FAQによると、月間の利用量が上限の80%・90%・100%に達した時点でメールが届き、利用状況のダッシュボードが公開されるまでは月間上限を強制していないとのことです。上限を超えても止まらないことを前提に設計するのは危険です。月額料金は改定で変わるため、契約前に料金ページで確認してください。既存の業務システムに組み込む場合の設計や開発を外部に任せたいときは、API開発・システム連携の支援も選択肢です。
CC BY 4.0のクレジット表記とAGPLv3
APIで得たデータはCC BY 4.0で提供されており、利用する画面やレポートに出典のクレジットを表示し、ライセンスへのリンクを付け、データを加工した場合はその旨を明示する必要があります。これは無料・有料を問わずデータ側に付く条件です。公式の表記例は「Weather data by Open-Meteo.com」で、データ表示箇所の隣にOpen-Meteoへのリンクを置きます。一方、AGPLv3はOpen-Meteoのソースコードに付くライセンスで、APIを呼び出すだけのアプリには影響しません。セルフホスト版を改変してネットワーク越しに提供する場合は、その利用者が改変版の対応するソースコードを無償で取得できるようにする必要があります。なお利用規約はスイス法に準拠し、紛争はスイスの裁判所の専属管轄とされています。
日本で使うときの精度とJMAモデル(MSM・GSM)
best_matchが東京で選ぶモデル:MSMの後はECMWF IFS
モデルを指定しない既定のbest_matchが、日本の座標で実際にどのモデルの値を返しているかを確かめました。2026年10月14日15時台(日本時間)に、東京(新宿付近)の座標でmodels=best_match,jma_msm,jma_gsm,ecmwf_ifs,ecmwf_ifs025を1回のリクエストで並べ、1時間ごとの気温がどのモデルと一致するかを照合しています。
curl "https://api.open-meteo.com/v1/forecast?latitude=35.6895&longitude=139.6917&hourly=temperature_2m,precipitation&models=best_match,jma_msm,jma_gsm,ecmwf_ifs,ecmwf_ifs025&timezone=Asia/Tokyo&forecast_days=10"
| 時間帯(日本時間) | best_matchの値と一致したモデル |
|---|---|
| 10月14日0時〜17日13時 | JMA MSM(約5km) |
| 10月17日14時〜15時 | 切り替わりの境目 |
| 10月17日16時〜23日23時 | ECMWF IFS HRES(9km) |
データ出典:Weather data by Open-Meteo.com(CC BY 4.0)
MSMの値はこの応答では10月17日15時で途切れ、その先はGSM(約55km)ではなくECMWFの9kmモデルに引き継がれていました。天気コードでも同じで、MSMの値がある88時間はweather_codeが全時間でMSMと一致し、残り80時間は全時間でECMWF IFSと一致しました。モデルが替わると値の傾向も変わります。日別にすると、10月23日の降水量はbest_match(ECMWF由来)が183.6mm、気象庁のGSMが4.0mmと大きく割れました。4日目以降の予報を画面に出すなら、その日数から別のモデルの値になっていると理解しておきます。
気象庁のモデルだけで通したいときは、/v1/jmaでmodels=jma_seamlessを指定します。公式の説明では、Seamlessは同じ提供元のモデルを1本の予報につなぐもので、気象庁ならMSMの後をGSMで埋めます。
JMA APIで選べるMSMとGSMの違い
JMA APIの公式ドキュメントは、日本向けに最適化していると断ったうえで、ほとんどの用途では汎用のForecast APIを勧めています。気象庁のモデルに固定して比べたいときに、/v1/jmaでモデルを明示的に指定します。
| モデル | 範囲 | 解像度 | 元データの間隔 | 予報期間 | 更新 |
|---|---|---|---|---|---|
| MSM | 日本・韓国 | 約5km | 1時間 | 4日 | 3時間ごと |
| GSM | 全球 | 約55km | 6時間 | 11日 | 6時間ごと |
curl "https://api.open-meteo.com/v1/jma?latitude=35.68&longitude=139.69&hourly=temperature_2m,precipitation&models=jma_msm&timezone=Asia/Tokyo"
予報期間の「4日」は公式表の値で、前の節の実測ではMSMの値は取得時刻から約3日後に途切れました。GSMの6時間間隔の元データは、APIでは1時間間隔に補間されます。また、気象庁のデータはライセンスの制約で提供される変数が限られ、元データには突風・CAPE・雪の項目がなく、GSMには日射もありません。ただし、APIの降雪量は気温と降水量から算出されます。天気コードはOpen-Meteoが雲量・気温・降水量・降雪量から計算しており、大気の安定度の情報がないため雷雨と霧のコードは生成されません。
アメダス東京の観測値と比べた予報の誤差
「Open-Meteoは日本で当たるか」は、どのモデルの、何日前の予報かで答えが変わります。そこで、Previous Model Runs APIで通常系列と、各予報対象時刻の24時間前・72時間前に予測された気温の系列を取り、気象庁のアメダス東京(地点番号44132、北緯35度41.5分・東経139度45.0分)の毎正時の気温と比べました。期間は2026年10月5日〜13日の9日間(216時間)で、10月5日6〜8時のファイルが404だった3時間と、公開ファイルに毎正時の値が無かった11時間を除く202時間です。アメダスのJSONは直近の期間しか置かれないため、同じ期間で後から計算し直すなら、取得した観測値をその場で保存しておきます。
import json, urllib.request, urllib.error, datetime as dt
# アメダス東京(44132)の毎正時の気温(3時間ごとのJSONに10分値が入る)
obs = {}
d = dt.date(2026, 10, 5)
while d <= dt.date(2026, 10, 13):
for h in range(0, 24, 3):
url = f"https://www.jma.go.jp/bosai/amedas/data/point/44132/{d:%Y%m%d}_{h:02d}.json"
try:
data = json.load(urllib.request.urlopen(url))
except urllib.error.HTTPError as exc:
if exc.code != 404:
raise
print(f"取得不可(404): {url}")
continue
for k, v in data.items():
if k.endswith("0000") and v.get("temp") and v["temp"][0] is not None:
obs[f"{k[:4]}-{k[4:6]}-{k[6:8]}T{k[8:10]}:00"] = v["temp"][0]
d += dt.timedelta(days=1)
q = ("https://previous-runs-api.open-meteo.com/v1/forecast?latitude=35.6917&longitude=139.75"
"&hourly=temperature_2m,temperature_2m_previous_day1,temperature_2m_previous_day3"
"&models=best_match,jma_msm,jma_gsm,ecmwf_ifs&timezone=Asia/Tokyo"
"&start_date=2026-10-05&end_date=2026-10-13")
fc = json.load(urllib.request.urlopen(q))["hourly"]
for m in ["best_match", "jma_msm", "jma_gsm", "ecmwf_ifs"]:
for lead in ["temperature_2m", "temperature_2m_previous_day1", "temperature_2m_previous_day3"]:
err = [abs(v - obs[t]) for t, v in zip(fc["time"], fc.get(f"{lead}_{m}", []))
if v is not None and t in obs]
print(m, lead, len(err), round(sum(err) / len(err), 2) if err else "no data")
| モデル | 通常系列 | 24時間前の予報 | 72時間前の予報 |
|---|---|---|---|
| best_match | 0.98℃ | 0.98℃ | 1.43℃ |
| JMA MSM | 0.98℃ | 0.98℃ | 値なし |
| JMA GSM | 0.99℃ | 1.03℃ | 1.05℃ |
| ECMWF IFS(9km) | 0.78℃ | 1.09℃ | 1.43℃ |
数値は平均絶対誤差(MAE)。データ出典:Weather data by Open-Meteo.com(CC BY 4.0)、気象庁アメダス。
24時間前の予報まではbest_matchがMSMと同じ値で、誤差は約1.0℃でした。72時間前の予報ではMSMの値が返らず、best_matchはECMWF IFSと同じ1.43℃になっています。この9日間に限ると、72時間前の予報はGSMの方が誤差が小さく出ました。ただし、地点は1つ、期間は9日、比べたのは気温だけです。降水の有無や雨量は別の指標(的中率など)で測る必要があり、季節が変われば順位も入れ替わり得ます。この表から「どのモデルが日本で一番当たる」とは言えません。自社の用途で使うなら、対象地点・対象期間・使う変数で同じ比較を回し、使うモデルと何日先まで信用するかを決めてください。
日本語の地名で座標が返らないケース
Geocoding APIの一致条件は、2文字なら登録名と完全一致、3文字以上なら登録名の先頭からの一致です(Geocoding APIの公式ドキュメント)。これに加えて、日本語の地名を検索するときはlanguage=jaの有無で結果が変わります。countryCode=JPとcount=3(最大3件)を付けて検索した結果は次のとおりで、2026年9月26日と10月14日の2回とも同じでした。
| name | languageなし | language=ja |
|---|---|---|
| 東京 | 0件 | 0件 |
| 東京都 | 0件 | 東京都 |
| 札幌 | 0件 | 0件 |
| 札幌市 | 0件 | 札幌市(北海道) |
| 渋谷 | 0件 | 渋谷(東京都・大阪府・千葉県) |
| 渋谷区 | 0件 | 0件 |
| Tokyo | Tokyo(英語名)ほか | 東京都ほか |
データ出典:Weather data by Open-Meteo.com(CC BY 4.0)
漢字の検索語は、language=jaを付けない限り1件も返りませんでした。付けた場合も、2文字の「東京」「札幌」は登録名の「東京都」「札幌市」と完全一致しないため0件で、「渋谷区」は登録名「渋谷」の先頭と一致しないため0件です。利用者の入力をそのまま渡すなら、language=jaとcountryCode=JPを必ず付け、0件のときは「都・市」を補う・ローマ字で再検索する・候補から選ばせる、の順でフォールバックを用意します。住所から座標への変換精度が要る用途では、地図系のジオコーダーとの組み合わせも検討します。座標系や地理データの扱いはGISデータとは?形式・座標系・取り込み設計を実装目線で解説【2026年8月時点】で整理しています。
過去データ:Historical Weather APIとHistorical Forecast APIの使い分け
過去データのAPIは目的で選び分けます。公式ドキュメントの整理では、数十年単位の分析はHistorical Weather API、直近数年の気象を予報APIと同じ形式で再現したいときはHistorical Forecast API、何日前の予報がどれだけ当たったかを測るときはPrevious Model Runs API、特定の日に発表された予報をそのまま再現するときはSingle Runs APIです。長期の統計では、modelsでERA5またはERA5-Landを明示して、途中でデータソースが切り替わらないようにします。
| API | データの中身 | 期間・解像度 | 向く用途 |
|---|---|---|---|
| Historical Weather | 再解析・IFSの解析/予報データ | ERA5:1940年〜・約25km ERA5-Land:1950年〜・約11km ECMWF IFS:2017年〜・9km |
数十年単位の統計 |
| Historical Forecast | 各予報ランの先頭部分を連結 | おおむね2021年以降 | 直近数年の再現 |
| Previous Model Runs | 1〜7日前に発表された予報 | 多くは2024年1月以降(JMAは2018年以降) | 予報精度の検証 |
curl "https://archive-api.open-meteo.com/v1/archive?latitude=35.68&longitude=139.69&start_date=1940-01-01&end_date=1940-01-31&daily=temperature_2m_max,temperature_2m_min&timezone=Asia/Tokyo"
Historical Forecast APIは、予報モデルの更新ごとに先頭の数時間をつなげた時系列なので、途中でモデルの版が変わると値の性質も変わります。公式も長期の時系列には向かないとしているので、10年単位の傾向分析には使わないでください(詳しくはHistorical Weather APIの公式ドキュメント)。取得したデータの欠損補間や集計の単位合わせは時系列データの前処理|欠損補間・リサンプリング・特徴量生成とリーク回避を実装手順で解説の手順がそのまま使えます。気温や降水を販売数の予測に入れるときの手法選びは需要予測アルゴリズムの選び方と実装手順|時系列・機械学習・Pythonを参照してください。予測時点では「その時点で手に入った予報」しか使えないので、学習データにも予測対象時刻までのリードタイムを合わせた予報値を使います。Previous Model Runsは固定リードタイムの比較に使い、特定の実行時点で利用できた予報を再現する場合は、配信の遅延も考慮してSingle Runsからランを選びます。
天気コード(weather_code)の意味と日本語への読み替え
APIは天気を数値のWMOコードで返すため、画面表示には文言やアイコンへの変換が必要です。
| コード | 意味 |
|---|---|
| 0 | 快晴 |
| 1 / 2 / 3 | おおむね晴れ / 一部曇り / 曇り |
| 45 / 48 | 霧 / 着氷性の霧 |
| 51 / 53 / 55 | 霧雨(弱 / 中 / 濃い) |
| 56 / 57 | 着氷性の霧雨(弱 / 濃い) |
| 61 / 63 / 65 | 雨(弱 / 中 / 強) |
| 66 / 67 | 着氷性の雨(弱 / 強) |
| 71 / 73 / 75 | 雪(弱 / 中 / 強) |
| 77 | 雪粒 |
| 80 / 81 / 82 | にわか雨(弱 / 中 / 激しい) |
| 85 / 86 | にわか雪(弱 / 強) |
| 95 / 97 | 雷雨 / 激しい雷雨 |
| 96 / 99 | ひょうを伴う雷雨(弱 / 強) |
先の東京の例で返った1はおおむね晴れです。hourlyとcurrentのweather_codeはその時点の状態を、dailyのweather_codeはその日のうちで最も荒れた天気を表します。1日の天気を1つのアイコンで見せる画面では、時間ごとの値を自分で集約するよりdailyを使う方が公式の定義とずれません。
どのコードが出るかはモデルで決まります。Forecast APIの公式ドキュメントによると、96と99はDWD ICONやUKMOのように、ひょうを明示的に予報するモデルでしか出ず、それ以外のモデルは雷雨を95と97で返します。さらに気象庁のモデルは雷雨と霧のコードを生成しません。前の節のとおり東京のbest_matchは3日余り先までMSMの値なので、その期間は雷が予想されていても95や45は返りません。雷の可能性を画面に出したい用途では、気象庁の雷注意報など別の情報源と組み合わせます。
運用で詰まる点:エラー応答・429・セルフホスト
パラメータの誤りはHTTP 400とreason付きのJSONで返ります。無料版で1日の上限を超えると、HTTP 429と「Daily API request limit exceeded. Please try again tomorrow.」という応答が返った事例が公式のGitHub Discussionsで報告されています。429の理由が日次上限超過なら、即時の再試行を繰り返さず、キャッシュ済みの値を表示するか、翌日まで取得を止める処理に切り替えます。一時的な失敗と上限超過を分けて扱う設計はリトライパターンとは?指数バックオフ・ジッター・リトライ予算の実装判断を解説で詳しく解説しています。
無料APIには稼働率の保証がありません。障害時に止まると困るサービスを無料APIだけで作るのは避け、有料プラン(予約サーバーで稼働率99.9%を目標)か、Dockerでのセルフホストを検討します。セルフホストの公式手順の要件は、AVX2などのSIMD命令を備えたx86-64またはArmのCPU、メモリ8GB以上(推奨16GB)、ストレージ100GB以上で、高IOPSのNVMe SSDが推奨されています。イメージはghcr.io/open-meteo/open-meteoで公開され、環境変数REMOTE_DATA_DIRECTORYにOpen-MeteoのAWS S3上のデータを指定すると、必要な分だけ取得してローカルにキャッシュします。セルフホストは商用でも使えます(データはCC BY 4.0、コードとDockerイメージはAGPLv3)。ただし同じ手順書は、キャッシュが温まっていないと1回の応答に数秒かかり、無料APIより遅くなるのが普通だとしています。同じ地点を繰り返し引く業務向けの選択肢で、1人で数回試すだけなら無料APIの方が速いです。外部APIの呼び出し全般に共通する認証やエラー処理の設計はAPI連携の実装方法:REST・認証・エラー処理の手順をcurlとPythonのコード例で解説も参考になります。
よくある質問
Open-MeteoはAPIキーなしで使えますか?
非商用の無料APIは、登録もAPIキーも不要です。URLに緯度・経度と変数を指定すればすぐに結果が返ります。APIキーが必要になるのは、有料プランの専用ドメインcustomer-api.open-meteo.comを使う場合だけです。
Open-Meteoは商用利用できますか?
できますが、有料プランの契約が必要です。広告付きのサイトやアプリ、商用製品への組み込み、企業内での非公開の研究は、無料APIでは利用できない商用利用に当たります。セルフホストなら商用でも使えますが、データのクレジット表記(CC BY 4.0)は必要です。
Open-Meteoの日本での精度はどのくらいですか?
使うモデルと予報の日数で変わります。アメダス東京との9日間の比較では、24時間前の予報の気温誤差(MAE)が既定のbest_matchで0.98℃、72時間前の予報で1.43℃でした。東京のbest_matchは3日余り先まで気象庁MSM(約5km)、その先はECMWF IFS(9km)の値です。自分の用途での誤差は、Previous Model Runs APIで同じ比較を回して確かめます。
過去の天気データは何年前から取れますか?
Historical Weather APIのERA5で1940年から取得できます。より細かいERA5-Land(約11km)は1950年から、ECMWF IFS(9km)は2017年からです。
weather_codeの61や80は何を意味しますか?
WMOの天気コードで、61は弱い雨、80は弱いにわか雨です。APIは数値しか返さないため、本記事の対応表のように日本語の文言へ変換して表示します。