読み込み中

APIドキュメント

概要

本サイト「ハイウェイラジオ 情報まとめ」が提供する公開APIの説明ページです。左のサイドバーから各APIを選択すると、右側に説明が表示されます(初期表示はこの概要です)。URLのハッシュに #/api-map のように付けると、そのAPIの説明を直接表示できます。

基本仕様

  • レスポンスは application/json(ナンバリング画像等の画像系を除く)
  • 成功時は status: true と、用途に応じた data などのフィールドが返ります
  • 失敗時は status: falsecode(エラーコード)が返ります。詳細を含む場合は 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。