本文へスキップ

気象庁アメダスの観測値JSON(公式APIではない)の使い方:最新時刻・観測所番号・品質フラグの読み方

SHAYOUWORLD 公開 約8分

要点

  1. 最新時刻を先に読む。 https://www.jma.go.jp/bosai/amedas/data/latest_time.txt に、取得できる最新の観測時刻が入っています。
  2. 全国なら map、1地点なら point。 map/20261020100000.json は10分ごとの全国1,286地点、point/44132/20261020_09.json は1地点の3時間分です。
  3. 値は [値, 品質] の2要素。 品質が0か1以外の値は使いません。東京の1時間降雪量は値が0、品質が6(欠測)でした。
  4. 観測所表の緯度経度は [度, 分]。 東京の [35, 41.5] は北緯35.69167度です。
  5. 最高・最低気温の時刻は、実測ではUTCと読むと整合しました(推定)。 {"hour":0,"minute":5} は日本時間の9時5分でした。

気温や降水量の「いまの値」をプログラムやAIエージェントから引くなら、最新時刻を latest_time.txt で確かめ、全国なら map/、1地点なら point/ のJSONをキーなしでGETします。 どちらも気象庁ホームページのアメダスの画面が読み込むファイルで、API仕様書は見つかりませんでした。値ごとに付く品質の番号を見ずに数字だけを取ると、欠測を0として扱ってしまいます。

2026年10月20日の10時17分から10時30分にかけて、Node.js(依存なし)とcurlから合計17回リクエストし、構造と件数を確かめました。天気予報のJSONは気象庁の天気予報JSONの使い方で扱っています。予報JSONの気温の地点は、この記事のアメダスの観測所番号と同じでした(後述)。

取得した4つのファイル

用途URL実測サイズLast-Modified(日本時間)
最新の観測時刻https://www.jma.go.jp/bosai/amedas/data/latest_time.txt25 bytes2026-10-20 10:06:40
観測所表https://www.jma.go.jp/bosai/amedas/const/amedastable.json187,742 bytes2026-10-15 13:09:52
全国の10分値https://www.jma.go.jp/bosai/amedas/data/map/20261020100000.json349,082 bytes2026-10-20 10:13:25
1地点の3時間分https://www.jma.go.jp/bosai/amedas/data/point/44132/20261020_09.json4,176 bytes2026-10-20 10:16:30

4つとも Cache-Control: max-age=60、Access-Control-Allow-Origin: * で、キーなしのGETで返りました。latest_time.txt の中身は 2026-10-20T10:00:00+09:00 の1行です。ファイル名の時刻は、map/ が YYYYMMDDhhmmss、point/ が YYYYMMDD_hh で、どちらも日本時間でした。point/ は3時間ごとのファイルで、10時台の値は _09 のファイルに入っていました。

map/(全国の1時刻)
point/(1地点の3時間)
URL
map/20261020100000.json
point/44132/20261020_09.json
最上位のキー
観測所番号(1,286件)
観測時刻(10分ごと)
入っている要素
気温・降水量・風・日照・湿度・積雪など
左に加えて最高・最低気温と最大瞬間風速、その時刻
向いている用途
全国の地図、しきい値を超えた地点の抽出
1地点の最新値と、その日の推移
2026-10-20 10時台の取得結果。point/ の10時17分の取得では09:00〜10:10の8件が入っていた

最新時刻を先に読む

latest_time.txt を2回取得しました。

10:17:08 取得 -> 2026-10-20T10:00:00+09:00(Last-Modified 10:06:40)
10:25:11 取得 -> 2026-10-20T10:10:00+09:00(Last-Modified 10:16:40)

10時00分の値が latest_time.txt に反映されたのは10時06分40秒で、6分40秒ほど後でした。一方、10時17分に取得した東京の point/ には、latest_time.txt がまだ指していない10時10分の値が入っていました。地点のファイルは、全国の時刻表示より先に更新されることがあります。

全国の map/20261020100000.json は、Last-Modified が10時13分25秒で、latest_time.txt が10時00分を指し始めた10時06分40秒より後でした。同じ時刻のファイルが後から書き直されることがある、と読めます。10時17分と10時25分に取得した中身は同じで、何が書き直されたのかは確かめていません。

時刻を自分で計算して、まだないファイルを取りに行かないでください。 存在しない観測所番号(point/99999/20261020_09.json)を取得すると、HTTP 404 の text/html(2,203 bytes)が返りました。このときの Age ヘッダーは43,516秒で、404の応答が12時間ほど中継サーバーに保持されていたことになります。まだ作られていない時刻のファイルで同じことが起きるかは試していませんが、latest_time.txt の時刻だけを使えば避けられます。

観測所表 amedastable.json

観測所表は、5桁の観測所番号をキーにしたオブジェクトです。東京のエントリです。

"44132": {
"type": "A", "elems": "11111111",
"lat": [35, 41.5], "lon": [139, 45], "alt": 25,
"kjName": "東京", "knName": "トウキョウ", "enName": "Tokyo"
}
1,286
観測所の数
番号はすべて5桁。map/ のキーと過不足なく一致
1,131
種類C(アメダス)
A 気象台は56、B 測候所・特別地域気象観測所は95
37組
同名の観測所
「金山」は北海道・山形・福島・岐阜の4地点
[度, 分]
緯度経度の形
[35, 41.5] は 35 + 41.5 / 60 = 35.69167度
https://www.jma.go.jp/bosai/amedas/const/amedastable.json(2026-10-20取得)

type の名前は、ページのスクリプトにある凡例から読みました。A は気象台、B は測候所・特別地域気象観測所、C は地域気象観測所(アメダス)、D は父島気象観測所、E は南鳥島気象観測所、F は富士山特別地域気象観測所、G はその他の気象観測所です。D〜G は1地点ずつでした。

elems は8桁で、左から気温、降水量、風向、風速、日照時間、積雪深、湿度、気圧の有無です。凡例の組み合わせ(気象台の 11111011 が「気温・降水量・風向風速・日照時間・湿度・気圧」など)から並びを読みました。最も多いのは 11112010(487地点)で、5桁目に 2 が入るのは種類C(687地点)とG(1地点)だけでした。アメダスの解説ページには、2021年3月2日から気象台と特別地域気象観測所以外の観測所で日照時間を推計値で提供しているとあり、それと合います。2 の意味を定義した資料は見つけていません。

降水量だけを観測する 01000000 は351地点です。解説ページの「降水量は約1,300か所」「風・気温・湿度は約840か所」「積雪深は約330か所」に対し、10時00分の map/ で各要素のキーを持つ地点は、降水量1,281、湿度839、積雪深333でした。

値は [値, 品質] の2要素

map/ の東京(44132)の10時00分の値です。

{
"pressure": [1015.6, 0], "normalPressure": [1018.4, 0],
"temp": [22.7, 0], "humidity": [75, 0],
"snow": [null, 5], "snow1h": [0, 6], "snow6h": [0, 6], "snow12h": [0, 6], "snow24h": [0, 6],
"sun10m": [0, 0], "sun1h": [0, 0],
"precipitation10m": [0, 0], "precipitation1h": [0, 0], "precipitation3h": [0, 0], "precipitation24h": [0, 0],
"windDirection": [14, 0], "wind": [2.1, 0]
}

2番目の数字が品質です。ページのスクリプトは次の記号で表示していました。記号の意味は、気象庁の過去の気象データ検索「値欄の記号の説明」によります。

品質画面の記号意味10時00分の全国で見つかった例
0なし正常ほとんどの値
1)準正常値。統計の対象資料が許容範囲内で欠けている巻の24時間降水量 [89, 1] など12地点
2、3#疑問値。値にかなり疑問がある見つからず
4]資料不足値。値そのものは信用できない静岡空港の24時間降水量 [41.5, 4]
5休止中観測を休止している積雪深の333地点すべて、別海の気温 [null, 5]
6×欠測東京の1時間降雪量 [0, 6](336地点)
null空白その要素を観測していない宗谷岬の1時間降雪量 [0, null](950地点)

ページのスクリプトは、品質が0か1で値が null でないときだけを有効な値として扱っていました。値が0でも品質が6なら欠測です。 数字だけを取り出すと、欠測の降雪量を「0cm」と答えてしまいます。積雪深は10月20日時点で全地点が休止中でした。

単位も同じスクリプトにありました。temp は℃、humidity は%、precipitation10m などは mm、wind は m/s、windDirection は16方位(1が北北東、16が北、0が静穏)、sun10m は分、sun1h は時間、snow 系は cm、pressure(現地気圧)と normalPressure(海面気圧)は hPa、visibility は km です。

地点ファイル point/ の構造

point/44132/20261020_09.json は、20261020090000 から 20261020101000 までの8件を持っていました。10分ごとの値に加えて、maxTemp・minTemp・gust(最大瞬間風速)とその時刻が入ります。積雪のキー(snow、snow1h など)は毎正時の09:00と10:00にだけありました。

時刻のキーは日本時間ですが、maxTempTime などの hour と minute は、今回の実測からUTCと推定しています。 公式資料では確認できていないので、値の推移から判断した根拠を書きます。

09:00 temp 23.3 maxTemp 23.3 maxTempTime {"hour":0,"minute":0}
09:10 temp 23.3 maxTemp 23.6 maxTempTime {"hour":0,"minute":5}
(minTempTime はどちらも {"hour":20,"minute":46}、minTemp 18.6)

09:10の時点で、その日の最高気温が23.3から23.6に上がり、時刻が「0時5分」になりました。日本時間の0時5分なら、09:00の時点ですでに23.6が最高気温になっていたはずです。UTCの0時5分、つまり日本時間の9時5分なら、09:00と09:10のあいだに23.6を記録したことになり、値の動きと合います。最低気温の「20時46分」は、同じ読み方で日本時間の5時46分です。

予報JSONの気温の地点はアメダスの番号

天気予報のJSONでは、気温の地点コードが area.json に存在しないことを予報JSONの記事で書きました。10月20日5時発表の forecast/130000.json を取得して照合すると、その4地点はすべてアメダスの観測所表にありました。

44132 東京 -> amedastable の「東京」(種類A)
44172 大島 -> 「大島」(種類B)
44263 八丈島 -> 「八丈島」(種類B)
44301 父島 -> 「父島」(種類D)

予報の気温と、同じ地点の観測値を並べたいときは、この番号でつなげます。東京都以外の府県では照合していません。

Node.jsで1地点の最新値を取る

観測所の名前から候補を探し、1件に決まったときだけ最新値を取得します。観測所表は1日キャッシュします。

// amedas-latest.mjs — 依存なし(Node.js 18 以降の組み込み fetch)
// 使い方: node amedas-latest.mjs 東京
import { readFile, writeFile, mkdir, stat } from 'node:fs/promises';
const UA = 'amedas-example/0.1 (+https://codeagent.jp/)';
const BASE = 'https://www.jma.go.jp/bosai/amedas';
const TABLE_URL = `${BASE}/const/amedastable.json`;
const TABLE_CACHE = './cache/amedastable.json';
const DAY = 24 * 60 * 60 * 1000;
// 画面のスクリプトにある品質の記号。0 と 1 以外は値として使わない
const AQC = { 0: '', 1: ')', 2: '#', 3: '#', 4: ']', 5: '休止中', 6: '×' };
const UNITS = { temp: '℃', humidity: '%', precipitation10m: 'mm', precipitation1h: 'mm', wind: 'm/s', windDirection: '16方位', sun1h: 'h', snow: 'cm', pressure: 'hPa' };
async function get(url, kind) {
const res = await fetch(url, { headers: { 'User-Agent': UA } });
const type = res.headers.get('content-type') ?? '';
// 存在しない観測所は 404 の HTML が返る
if (!res.ok || (kind === 'json' && !type.includes('json'))) {
throw new Error(`取得失敗: ${url} -> HTTP ${res.status} (${type})`);
}
return kind === 'json' ? res.json() : (await res.text()).trim();
}
async function loadTable() {
try {
if (Date.now() - (await stat(TABLE_CACHE)).mtimeMs < DAY) return JSON.parse(await readFile(TABLE_CACHE, 'utf8'));
} catch { /* キャッシュなし */ }
const table = await get(TABLE_URL, 'json');
await mkdir('./cache', { recursive: true });
await writeFile(TABLE_CACHE, JSON.stringify(table));
return table;
}
const toDeg = ([d, m]) => Math.round((d + m / 60) * 1e5) / 1e5; // [度, 分] → 十進の度
// [値, 品質] を { value, aqc, mark } に。品質が 0・1 以外なら値を捨てる
function reading([value, aqc] = []) {
if (aqc === undefined) return undefined; // その要素を観測していない
const usable = (aqc === 0 || aqc === 1) && value !== null;
return { value: usable ? value : null, aqc, mark: aqc === null ? '観測なし' : AQC[aqc] ?? `不明(${aqc})` };
}
// 今回の実測からUTCと推定(公式仕様は未確認)。観測時刻以前で最も近い日時として日本時間に直す
function jstTime(observedAt, t) {
if (!t) return null;
const obs = new Date(observedAt);
const at = new Date(Date.UTC(obs.getUTCFullYear(), obs.getUTCMonth(), obs.getUTCDate(), t.hour, t.minute));
if (at > obs) at.setUTCDate(at.getUTCDate() - 1);
return new Date(at.getTime() + 9 * 3600e3).toISOString().slice(0, 16) + '+09:00';
}
// 風向は 1〜16 が北北東から時計回り、0 は静穏
const WDR = ['静穏', '北北東', '北東', '東北東', '東', '東南東', '南東', '南南東', '南', '南南西', '南西', '西南西', '西', '西北西', '北西', '北北西', '北'];
async function main(name) {
const table = await loadTable();
const candidates = Object.entries(table)
.filter(([, s]) => s.kjName === name)
.map(([code, s]) => ({ code, name: s.kjName, type: s.type, lat: toDeg(s.lat), lon: toDeg(s.lon), alt: s.alt }));
if (candidates.length !== 1) {
console.log(JSON.stringify({ status: candidates.length ? 'ambiguous' : 'not_found', input: name, candidates }, null, 2));
return;
}
const station = candidates[0];
// 最新時刻を先に読む。時刻を自分で計算して先回りしない
const latest = await get(`${BASE}/data/latest_time.txt`, 'text'); // 例 2026-10-20T10:10:00+09:00
const ymd = latest.slice(0, 10).replaceAll('-', '');
const block = String(Math.floor(Number(latest.slice(11, 13)) / 3) * 3).padStart(2, '0');
const pointUrl = `${BASE}/data/point/${station.code}/${ymd}_${block}.json`;
const series = await get(pointUrl, 'json');
const obsKey = latest.slice(0, 19).replace(/[-T:]/g, '');
const row = series[obsKey];
if (!row) throw new Error(`${pointUrl} に ${obsKey} がない`);
const values = Object.fromEntries(Object.keys(UNITS).map((k) => [k, reading(row[k])]).filter(([, v]) => v));
console.log(JSON.stringify({
status: 'ok',
station,
observedAt: latest,
values,
windDirectionLabel: values.windDirection?.value == null ? null : WDR[values.windDirection.value],
units: UNITS,
maxTemp: { ...reading(row.maxTemp), at: jstTime(latest, row.maxTempTime) },
minTemp: { ...reading(row.minTemp), at: jstTime(latest, row.minTempTime) },
newerKeysInFile: Object.keys(series).filter((k) => k > obsKey),
provenance: {
sources: [`${BASE}/data/latest_time.txt`, pointUrl, TABLE_URL],
retrievedAt: new Date().toISOString(),
attribution: '出典:気象庁ホームページ(https://www.jma.go.jp/bosai/amedas/)を加工して作成',
warnings: ['気象庁ホームページが内部で使うJSON。API仕様としては公開されておらず、予告なく変わりうる', '品質が0・1以外の値は value を null にしている'],
},
}, null, 2));
}
await main(process.argv[2]);

筆者のWindows環境(Node.js 24.8.0)では、fetch の後に process.exit() を呼ぶと libuv のアサーションで異常終了したため、関数から return で抜ける形にしています。

「金山」では観測所表だけを使い、4件の候補を返して止まりました(2件目以降は抜粋)。

$ node amedas-latest.mjs 金山
{ "status": "ambiguous", "input": "金山",
"candidates": [
{ "code": "12686", "name": "金山", "type": "C", "lat": 43.13833, "lon": 142.41667, "alt": 284 },
{ "code": "35116", ... "lat": 38.87833 }, { "code": "36342", ... "lat": 37.47333 }, { "code": "52406", ... "lat": 35.66167 } ] }

「東京」は10時30分に実行し、latest_time.txt と point/ の2回だけ取得しました(抜粋)。

$ node amedas-latest.mjs 東京
"station": { "code": "44132", "name": "東京", "type": "A", "lat": 35.69167, "lon": 139.75, "alt": 25 }
"observedAt": "2026-10-20T10:20:00+09:00"
"values": {
"temp": { "value": 22.1, "aqc": 0, "mark": "" },
"humidity": { "value": 81, "aqc": 0, "mark": "" },
"precipitation1h": { "value": 0, "aqc": 0, "mark": "" },
"wind": { "value": 2, "aqc": 0, "mark": "" },
"windDirection": { "value": 15, "aqc": 0, "mark": "" }, ... }
"windDirectionLabel": "北北西"
"maxTemp": { "value": 23.6, "aqc": 0, "mark": "", "at": "2026-10-20T09:05+09:00" }
"minTemp": { "value": 18.6, "aqc": 0, "mark": "", "at": "2026-10-20T05:46+09:00" }
"newerKeysInFile": []

newerKeysInFile は、latest_time.txt より新しい時刻が地点ファイルにあったときに、その時刻を並べる欄です。前述のように地点ファイルが先に更新されることがあるため、最新値として何を返したかを結果に残します。

AIエージェント・MCPツールにするときの設計

  1. ツールを2つに分ける。 find_amedas_station(name) は候補だけを返し、get_amedas_latest(code) は観測所番号だけを受け付けます。同名の37組をモデルの推測で1件に決めさせないためです。
  2. 品質の番号を落とさない。 値と一緒に aqc と記号を返し、0と1以外は null にします。降雪量の [0, 6] を「0cm」と答えさせないためです。
  3. 観測時刻と出典を返す。 observedAt、取得元URL、取得日時を別フィールドにします。型はMCPの出典情報を欠落させないoutputSchema設計に合わせられます。
  4. 取得の間隔はサーバー側で決める。 観測所表は日単位、観測値は max-age=60 の間は取り直しません。時刻を推測して先のファイルを取らず、404が返ったら再試行せずに止めます。共通の考え方は公共データAPIをMCP化する設計パターンにあります。
  5. 観測値の範囲だけを答えさせる。 観測値から天気の予想や警戒の呼びかけを作らせません。気象庁ホームページについてのページは、気象業務法第17条(予報業務の許可)と第23条(警報の制限)による制約に注意を促しています。予報が必要なら予報JSONを出典付きで返します。
- 観測値の回答は get_amedas_latest の結果だけを根拠にし、observedAt と出典を併記する
- value が null の要素は、mark(休止中・×など)を添えて「値なし」と書く。0 で補わない
- 観測所の候補が複数なら候補を示して止まる
- 観測値から予報や警戒の呼びかけを作らない
- 出典は「出典:気象庁ホームページ(URL)を加工して作成」の形で残す

まとめ

  • 最新時刻は latest_time.txt。全国は map/YYYYMMDDhhmmss.json、1地点は point/番号/YYYYMMDD_hh.json。キー不要でGETのみ
  • 10時00分の値が最新時刻に反映されたのは6分40秒後。地点ファイルはそれより先に新しい時刻を持つことがあった
  • 値は [値, 品質]。0と1以外は使わない。値が0でも品質6は欠測
  • 観測所表は1,286地点、緯度経度は [度, 分]、同名が37組。予報JSONの気温の地点コードはアメダスの番号
  • 最高・最低気温の時刻はUTCとして読むと値の推移と合う。公式資料では確認していない

予報の取得は天気予報JSONの使い方、地震の情報は気象庁の地震情報JSONの読み方にあります。ほかの公共データとの使い分けは公共データAPIのガイドを参照してください。

この記事の情報・検証メモ
Tags
公開日
情報確認
参考リンク
5件
更新性
定期更新
更新管理

仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。

検証メモ
Node.js 24.8.0(組み込み fetch、依存なし)、curl(Git Bash) 気象庁ホームページのアメダスJSON・予報JSON 取得日 2026-10-20(10時17分〜10時30分、計17リクエスト)
図解を保存・共有

記事の要点を1枚にまとめました。画像は新しいタブで開いて保存できます。

気象庁アメダスの観測値JSON(公式APIではない)の使い方:最新時刻・観測所番号・品質フラグの読み方 最新時刻を先に読み、品質フラグが0か1の値だけを使う。時刻と出典を結果に残す 取得の順番:latest_time.txt で最新の観測時刻を確かめる。全国は map/時刻.json、1地点は point/番号/日付_時.json。存在しないファイルは404のHTML。先回りして取らない。 値の読み方:値は [値, 品質] の配列。品質5は休止中、6は欠測。値が0でも品質が6なら欠測として扱う。最高気温の時刻はUTCと推定。公式仕様は未確認。 観測所表:1,286地点、番号は5桁の文字列。緯度経度は [度, 分]。十進に直して使う。同名の観測所が37組ある。名前で1件に決めない。
気象庁アメダスの観測値JSON(公式APIではない)の使い方:最新時刻・観測所番号・品質フラグの読み方 記事の要約 2026.10.20 入門・導入ガイド
Primary sources

一次情報・参考リンク

About the author
SHAYOUWORLD

日本の公共データAPIを使うMCPサーバーを作って公開し、ローカルLLMを自分のGPUで測った記録を、一次情報・検証ログ・失敗例とあわせて整理します。