概要
本サイト「ハイウェイラジオ 情報まとめ」が提供する公開APIの説明ページです。左のサイドバーから各APIを選択すると、右側に説明が表示されます(初期表示はこの概要です)。URLのハッシュに #/api-map のように付けると、そのAPIの説明を直接表示できます。
基本仕様
- レスポンスは
application/json(ナンバリング画像等の画像系を除く)
- 成功時は
status: true と、用途に応じた data などのフィールドが返ります
- 失敗時は
status: false と code(エラーコード)が返ります。詳細を含む場合は err も返ります
- GET はクエリパラメータ、POST は
application/json のJSONボディ(またはフォーム)で受け取ります
- 一部のAPIは レート制限(HTTP 429 / 403)があります
- 本APIは非公式であり、予告なく仕様が変更される可能性があります
エラーコードの慣例
code の値はAPIごとに定義されています。負の値は認証・権限関連、正の値は入力エラー・処理エラーであることが多くなっています。詳細は各APIのページを参照してください。
サンプルについて
このページに記載しているサンプル値はすべて架空のものです。実際の値を確認するには、各APIを実際に呼び出してみてください。
放送マップ検索
GET
/api/map
認証不要
指定座標(緯度・経度)を基準に、近い順に放送局(ハイウェイラジオ局)を最大 limit 件返す。上下線ラインの中央点からの ST_Distance_Sphere で距離を計算し、dist に丸めて返す。road_name・exclude・status・operator による絞り込みが可能。各局に GeoJSON ラインと、detail テーブルに調査があるか(has_detail)を含む。
パラメータ
| 名前 | 型 | 必須 | 説明 |
lat |
float |
必須 |
基準点の緯度。例: 35.466 |
lng |
float |
必須 |
基準点の経度。例: 139.622 |
road_name |
string |
任意 |
道路名で完全一致絞り込み。例: 東名高速道路 |
limit |
int |
任意 |
取得件数。デフォルト5、最大60 |
exclude |
string |
任意 |
除外する局IDをカンマ区切りで指定。例: exclude=10,23 |
status |
string |
任意 |
放送状態(-2〜3の整数)をカンマ区切りで複数指定。例: status=0,-1 |
operator |
string |
任意 |
事業者をカンマ区切りで複数指定。例: operator=e-nexco-1,c-nexco-2。other で上記以外を指定可能 |
リクエスト例
GET /api/map?lat=35.466&lng=139.622&limit=10&status=0,-1
レスポンス例
{
"data": [
{
"id": 42,
"name": "大井松田PA(サンプル)",
"operator": "e-nexco-1",
"road_code": "E84",
"road_name": "東名高速道路",
"pref": 14,
"move_id": null,
"status": 0,
"data_status": -1,
"kp1": "123.4",
"kp2": "125.0",
"line_up_geojson": {"type": "LineString", "coordinates": [[139.6, 35.4]]},
"line_down_geojson": {},
"has_detail": true,
"dist": 123.45
}
],
"status": true
}
補足
lat/lng が不正なら HTTP 400 で {"status":false,"code":2}。SQL エラー時は HTTP 400 で {"status":false,"code":1,"err":"..."}。status は -2,-1,0,1,2,3 のみ有効で、それ以外は無視される。operator の other は主要事業者以外を NOT IN で抽出。
局・調査詳細
GET
/api/detail
認証不要
局IDを指定して詳細情報を返す。type=all(デフォルト)は局情報に加えて detail テーブルの調査履歴(details)を含み、type=map は局情報のみ、type=detail は調査レコード(detail)単体を返す。ytbe・img・audio は JSON 文字列として保存されているものが配列にデコードされる。
パラメータ
| 名前 | 型 | 必須 | 説明 |
id |
string |
必須 |
局ID(type=detail の場合は調査レコードID)。例: 42 |
type |
string |
任意 |
all(デフォルト)/ map / detail のいずれか |
リクエスト例
GET /api/detail?id=42&type=all
レスポンス例
{
"status": true,
"data": {
"id": 42,
"name": "大井松田PA(サンプル)",
"description": "...",
"generation": 1,
"operator": "e-nexco-1",
"road_code": "E84",
"road_name": "東名高速道路",
"pref": 14,
"line_up_geojson": {"type": "LineString"},
"line_down_geojson": null,
"kp1": "123.4",
"kp2": "125.0",
"ic1": "大井松田IC",
"ic2": "秦野中井IC",
"cable": "",
"move_id": null,
"data_status": -1,
"status": 0,
"like": 0,
"updated_at": "2025-01-10 12:00:00",
"updated_at_map": "2025-01-10",
"started_at": null,
"closed_at": null,
"details": [
{"id": "0190abc123", "user": "u_001", "date": "2025-01-10", "ytbe": [], "img": ["img1.jpg"], "audio": [], "memo": "確認済み"}
]
}
}
補足
id 未指定は HTTP 400 {"status":false,"code":1}。該当なしは HTTP 404 {"status":false,"code":2}。例外時は HTTP 500 {"status":false,"code":99}。type=detail では data が {id,map,user,img,audio,date,ytbe,memo} になる。
局検索
GET
/api/search
認証不要
キーワード・状態・事業者で放送局を検索し、1ページ20件で返す。q は空白区切りで複数キーワードに対応し、mode=or で OR 結合になる。キーワードに「pref:」「gen:」「op:」「road:」等のプレフィックスを付けると対応カラムを LIKE 検索できる。完全一致・前方一致の順に並ぶ優先順位付けあり。
パラメータ
| 名前 | 型 | 必須 | 説明 |
q |
string |
任意 |
検索キーワード。空白区切りで複数指定可。例: q=東名 pref:14 |
mode |
string |
任意 |
and(デフォルト)/ or。複数キーワードの結合方法 |
status |
string |
任意 |
状態をカンマ区切りで複数指定(-2〜3)。例: status=0,3 |
operator |
string |
任意 |
事業者をカンマ区切りで複数指定。例: operator=e-nexco-1,c-nexco-2 |
page |
int |
任意 |
ページ番号。デフォルト1、最小1 |
リクエスト例
GET /api/search?q=東名&status=0,3&page=1
レスポンス例
{
"status": true,
"total": 32,
"page": 1,
"totalPages": 2,
"perPage": 20,
"data": [
{"id": 42, "name": "大井松田PA(サンプル)", "road_name": "東名高速道路", "road_code": "E84", "status": 0, "operator": "e-nexco-1", "survey": 3, "img": 5, "thumbnail": "img1.jpg"}
]
}
補足
プレフィックス対応: pref/gen/gen2/status/op/road/code/kp/kp1/kp2/ic/ic1/ic2。pref は数値または都道府県名(部分一致)で解決。サムネイルは調査画像の先頭1枚。
都道府県別局一覧
GET
/api/search/pref
認証不要
都道府県ID(1〜47)を指定して、その都道府県内の放送局一覧を road_code, name 順で返す。各局に調査件数・画像枚数・サムネイル(ランダムな調査画像の先頭1枚)を含む。
パラメータ
| 名前 | 型 | 必須 | 説明 |
id |
int |
必須 |
都道府県ID(1〜47)。例: 14(神奈川県) |
リクエスト例
GET /api/search/pref?id=14
レスポンス例
{
"status": true,
"total": 12,
"data": [
{"id": 42, "name": "大井松田PA(サンプル)", "road_name": "東名高速道路", "road_code": "E84", "status": 0, "operator": "e-nexco-1", "survey": 3, "img": 5, "thumbnail": "img1.jpg"}
]
}
補足
id が 1〜47 の範囲外の場合は HTTP 200 のまま {"status":false,"code":1} を返す(ステータスコード変更なし)。
都道府県別集計一覧
GET
/api/search/pref-list
認証不要
全都道府県について、局数(total)、調査済み局数(checked)、画像総数(img)、音声総数(audio)、調査件数(survey)、調査率(rate)、未調査局数(unchecked)、最終更新日時(last_update)、ステータスメッセージ(status / status_type)、ヒートマップ色クラス(heat)を集計して返す。局が1件もない都道府県は結果から除外される。
リクエスト例
GET /api/search/pref-list
レスポンス例
{
"status": true,
"data": [
{"id": 14, "name": "神奈川県", "total": 12, "checked": 8, "img": 45, "audio": 6, "survey": 20, "unchecked": 4, "rate": 67, "heat": "heat-4", "last_update": "2026-08-01 12:00:00", "status": "調査は順調に進んでいます", "status_type": "good"}
]
}
補足
img / audio は detail テーブルの JSON_LENGTH の合計。checked は DISTINCT map 数。rate = checked / total の四捨五入%。
ユーザー検索
GET
/api/search/user
認証不要
登録ユーザーを名前・ユーザーID・自己紹介文の部分一致で検索し、ポイント順(同点は名前順)で1ページ20件返す。退会・BAN(status -3/-2)と、プロフィール全体非公開(visibility 14)のユーザーは除外される。
パラメータ
| 名前 | 型 | 必須 | 説明 |
q |
string |
任意 |
検索キーワード。name / user_id / description を LIKE 検索 |
page |
int |
任意 |
ページ番号。デフォルト1、最小1 |
リクエスト例
GET /api/search/user?q=yu-&page=1
レスポンス例
{
"status": true,
"total": 3,
"page": 1,
"totalPages": 1,
"perPage": 20,
"data": [
{"id": 1, "user_id": "sagashi0120", "name": "yu-", "role": 3, "point": 1200, "description": "管理人です", "hidden_point": false, "hidden_role": false}
]
}
補足
hidden_point / hidden_role はプロフィール可視性フラグ(ビット1/2)から算出。
サイト統計
GET
/api/status
認証不要
現地調査・確認・画像・音声の登録件数を、data/internal/ 配下のカウントファイルから読み取って返す統計エンドポイント。値は整数にキャストされ、登録のたびに更新StatusCount系関数で加算される。
リクエスト例
GET /api/status
レスポンス例
{
"all": 1234,
"check": 800,
"img": 4500,
"survey": 900
}
補足
パラメータ不要の公開API。値はサンプル。
最新情報一覧
GET
/api/latest
認証不要
最新の現地調査5件(detail テーブルを updated_at 降順)と、最新のマップ更新5件(map テーブルを updated_at 降順)を返す。調査の station はマップ名を LEFT JOIN で取得し、存在しない場合は「不明な局」になる。memo は40文字で切り詰められ「…」が付く。
リクエスト例
GET /api/latest
レスポンス例
{
"status": true,
"survey": [
{"id": "0190abc123", "map_id": 42, "date": "2025-01-10", "station": "大井松田PA(サンプル)", "road_code": "E84", "memo": "本線路肩にて確認…"}
],
"check": [
{"id": 42, "name": "大井松田PA(サンプル)", "road_code": "E84", "road_name": "東名高速道路", "updated_at": "2025-01-10 12:00:00"}
]
}
補足
各リスト最大5件。memo は mb_strimwidth で40字に切り詰め。
サイト情報
GET
/api/info
認証不要
サイトのタイトル・説明・バージョン・メンテナンス/ロック状態・管理者情報などを返す。maintenance と lock は data/internal/ 配下のファイル有無で判定される。updated_at はコンテンツの最終更新時刻(ISO8601形式)。feed は常に null。
リクエスト例
GET /api/info
レスポンス例
{
"title": "ハイウェイラジオ 情報まとめ",
"description": "日本全国の高速道路で放送されている「ハイウェイラジオ」の情報をまとめているサイトです。",
"version": "1.2.3",
"feed": null,
"maintenance": false,
"lock": false,
"updated_at": "2025-01-10T12:00:00+09:00",
"admin": {
"name": "𛃤ー / yu-",
"twitter": "@hotate_hokudo",
"mastodon": "@sagashi0120",
"github": "sagashi0120",
"discord": "sagashi0120"
}
}
補足
version は定数 VERSION の値。maintenance/lock はファイル存在フラグ。
情報パネル
GET
/api/info-panel
認証不要
トップページ等に表示する情報パネルを、data/internal/info_panel_1〜4.csv から読み込んで返す。各CSV行が1エントリで、desc1/desc2 と任意のアイコン(svgファイル名)、前景画像、中央寄せフラグを持つ。天気情報のマージ処理は現在コメントアウトされている。
リクエスト例
GET /api/info-panel
レスポンス例
{
"info-1": [
{"desc1": "お知らせ", "desc2": "システムメンテナンスのお知らせ(サンプル)", "icon": null, "foreground": null, "center1": false, "center2": false}
],
"info-2": [],
"info-3": [],
"info-4": []
}
補足
キーは info-1〜info-4 の4つ。CSVは最低2列必要で、両方空の行はスキップ。icon は data/img/info/{name}.svg、foreground は data/img/C2-info-2.svg 等のパスになる。
お知らせ一覧・詳細
GET
/api/notice
認証不要
お知らせの一覧または詳細を返す。id 未指定なら一覧(id, title, type, updated_at, user, for のみ)を updated_at 降順で、id 指定なら本文 content を含む詳細を返す。content は改行が <br> に変換される。for パラメータで表示対象(アカウント向け/一般向け/全員)を絞り込める。
パラメータ
| 名前 | 型 | 必須 | 説明 |
id |
string |
任意 |
お知らせID(UUID)。指定時は詳細を返す |
for |
string |
任意 |
act(デフォルト)/ normal / all。act は for=act または all を表示 |
リクエスト例
GET /api/notice?for=normal
レスポンス例
{
"status": true,
"notice": [
{"id": "0190abc123", "title": "メンテナンスのお知らせ(サンプル)", "type": "info", "updated_at": "2025-01-10 12:00:00", "user": "u_001", "for": "all"}
]
}
補足
id 指定で該当なしは HTTP 404 {"status":false}。詳細レスポンスの notice には全カラム + nl2br 済み content が含まれる。for=all は絞り込みなし(1=1)。
コメント
GET
/api/comment
認証不要
局に対するコメントの取得・投稿・削除を行う。GET は map_id を指定してコメント一覧を新しい順に返し、投稿ユーザーの表示名はプロフィール可視性(visibility 14 で全非公開)に応じて null になる。POST は JSON で投稿し、DELETE は自身のコメントを削除する(admin フラグで管理者が他人のコメントも削除可)。
パラメータ
| 名前 | 型 | 必須 | 説明 |
map_id |
string |
必須 |
GET 時必須・POST 時必須。局ID(map テーブルの id) |
name |
string |
任意 |
POST 時。表示名。空なら「名無し」になる |
content |
string |
必須 |
POST 時必須。コメント本文(2500文字以内) |
id |
string |
必須 |
DELETE 時必須。削除するコメントID |
admin |
bool |
任意 |
DELETE 時。true で管理者(role >= 3)が任意のコメントを削除 |
リクエスト例
GET /api/comment?map_id=42
レスポンス例
{
"status": true,
"data": [
{"id": "0190abc123", "name": "yu-", "content": "確認しました<br>", "updated_at": "2025-01-10 12:00:00", "user": 1, "user_name": "yu-", "user_id": "sagashi0120"}
]
}
補足
POST/DELETE はセッション必須で、未認証は HTTP 401 {"status":false,"code":-1}。POST で map_id/content 空は HTTP 400 {"status":false,"code":1}、content 2500文字超は {"status":false,"code":2}。GET の content は nl2br + htmlspecialchars 済み。DELETE 成功は {"status":true}。admin 削除で role < 3 は HTTP 403。
お問い合わせ送信
POST
/api/contact
認証不要
お問い合わせ内容を JSON で受け取り、data/internal/contact/ 配下にテキストファイルとして保存する。Cloudflare Turnstile の検証(cf-turnstile-response)が必須で、IP ごとに60秒間5回までのレート制限がある。メールアドレスは形式検証される。
パラメータ
| 名前 | 型 | 必須 | 説明 |
cf-turnstile-response |
string |
必須 |
Cloudflare Turnstile のトークン |
title |
string |
必須 |
件名(100文字以内)。ファイル名にも使われる |
name |
string |
必須 |
氏名(100文字以内) |
email |
string |
必須 |
メールアドレス(200文字以内、形式検証あり) |
type |
string |
必須 |
問い合わせ種別(50文字以内) |
content |
string |
必須 |
本文(2000文字以内) |
リクエスト例
POST /api/contact (JSON body: {"title":"質問","name":"山田太郎","email":"taro@example.com","type":"bug","content":"本文","cf-turnstile-response":"..."})
レスポンス例
{
"status": true,
"code": 0
}
補足
レート制限超過は {"status":false,"code":429}(HTTP 429 ではなくボディの code)。Turnstile 失敗・メール形式不正は {"status":false,"code":3}。必須フィールド欠落は {"status":false,"code":2,"message":"Missing field: ..."}。ボディ空は code 1、保存失敗は code 500。IP は HTTP_CF_CONNECTING_IP を優先。
路線番号標識画像
GET
/api/web/numbering
認証不要
路線番号(ナンバリング)に応じた道路標識風の画像(AVIF または SVG)を返す。number の形式に応じて阪神高速([番号])、高速道路ナンバリング(C/E 系)、一般国道風プレート(R###-####)、都道府県道(R###)などを生成・配信する。既存ファイルが無い場合は SVG テンプレートから動的に生成する。
パラメータ
| 名前 | 型 | 必須 | 説明 |
number |
string |
必須 |
路線番号。例: [1](阪神高速)、E1、C2、R16-1234、R16。無指定・未知形式は 404 |
リクエスト例
GET /api/web/numbering?number=E1
レスポンス例
画像バイナリ(Content-Type: image/avif または image/svg+xml)。例: 高速道路ナンバリング「E1」の AVIF 画像
補足
JSON ではなく画像を返す。Cache-Control: public,max-age=86400。number が空または該当なしは 404。R###-#### 形式は data/img/pref/{prefCode}.svg テンプレートの {number} を置換。
ユーザー報告
POST
/api/report/user
要ログイン
不適切なユーザーを管理者に報告する。対象ユーザーID・理由・詳細を data/internal/report_user/ 配下にテキストファイルとして保存する(お問い合わせと同じ方式)。理由は spam/abuse/impersonation/illegal/other のいずれかで、不正な値は other に丸められる。
パラメータ
| 名前 | 型 | 必須 | 説明 |
target |
string |
必須 |
報告対象のユーザーID(user_id、例: bad_user(サンプル)) |
reason |
string |
任意 |
報告理由: spam / abuse / impersonation / illegal / other(不正値は other) |
detail |
string |
必須 |
報告の詳細(1000文字以内) |
リクエスト例
POST /api/report/user body: {"target":"bad_user","reason":"abuse","detail":"暴言が見られます(サンプル)"}
レスポンス例
成功: {"status":true,"code":0} / 失敗: {"status":false,"code":1}(target/detail 不足)、{"status":false,"code":2}(detail>1000文字)、{"status":false,"code":3}(404 対象なし)、{"status":false,"code":4}(自己報告)
補足
TOTP 未認証でも可(accountCheck(false))。報告は YYYYmmdd-HHMMSS_乱数.txt として保存され、ファイル書き込み失敗は 500 で code 99。
受信報告一覧(ヒートマップ用)
GET
/api/reception
認証不要
指定局に対する受信可否報告(聞こえた/聞こえなかった)の座標一覧を返す。/app/mobile/ のヒートマップ描画専用。投稿者を特定できる情報(ユーザーID等)は一切含まない。
パラメータ
| 名前 | 型 | 必須 | 説明 |
map_id |
string |
必須 |
局ID(map テーブルの id) |
limit |
int |
任意 |
取得件数。デフォルト500、最大1000(created_at 降順) |
リクエスト例
GET /api/reception?map_id=42
レスポンス例
{
"status": true,
"data": [
{"heard": 1, "lat": 35.466, "lng": 139.622, "created_at": "2026-08-20 12:00:00"}
]
}
補足
map_id 未指定は HTTP 400 code 1。該当局なしは HTTP 404 code 2。
受信可否を報告
POST
/api/reception/report
要ログイン
現在地でその局が「聞こえた/聞こえなかった」を1件報告する。報告地点が対象局のライン(line_up/line_down)から著しく離れている場合は拒否する。同一ユーザー×同一局には5分間のクールダウンがあり、成功時は reception_report ポイントが加算される。
パラメータ
| 名前 | 型 | 必須 | 説明 |
map_id |
string |
必須 |
対象局ID |
heard |
int |
必須 |
1: 聞こえた / 0: 聞こえなかった |
lat |
float |
必須 |
報告地点の緯度 |
lng |
float |
必須 |
報告地点の経度 |
accuracy |
int |
任意 |
GPSの精度(m)。任意 |
リクエスト例
POST /api/reception/report body: {"map_id":"42","heard":1,"lat":35.466,"lng":139.622,"accuracy":15}
レスポンス例
成功: {"status":true,"code":0,"id":"...","point_awarded":true} / 失敗: code 1(必須項目不足) / 2(座標範囲外) / 3(404 局なし) / 4(局から遠すぎる) / 5(429 クールダウン中) / 6(429 1日上限)
補足
TOTP 未認証でも可(accountCheck(false))。/app/mobile/ 専用の新規エンドポイント。
自分の受信報告履歴
GET
/api/reception/history
要ログイン
ログイン中ユーザー自身が過去に投稿した受信可否報告の一覧を、局名付きで新しい順に返す。
パラメータ
| 名前 | 型 | 必須 | 説明 |
page |
int |
任意 |
ページ番号。デフォルト1、最小1(1ページ20件) |
リクエスト例
GET /api/reception/history?page=1
レスポンス例
{
"status": true,
"data": [
{"id": "...", "map_id": "42", "station": "大井松田PA(サンプル)", "road_name": "東名高速道路", "heard": 1, "lat": 35.466, "lng": 139.622, "created_at": "2026-08-20 12:00:00"}
],
"page": 1
}
補足
未ログインは 401。