{"openapi":"3.1.0","info":{"title":"Alert-JP API","description":"日本の緊急速報リアルタイム配信API\n\n## 特徴\n- ⚡ 低レイテンシ配信（Cloudflare Workers）\n- 🌐 世界310拠点のエッジネットワーク\n- 📡 REST API、WebSocket、SSE対応\n- 🔒 セキュアな認証（API Key）\n- 📊 99.9%以上の稼働率\n\n## データソース\n| ソース | 種別 | 更新間隔 | 説明 |\n|--------|------|----------|------|\n| JMA (気象庁) | 地震・津波・気象・火山 | 10秒 | 日本国内の公式速報 |\n| USGS | 地震 | 1分 | 日本周辺の海外地震 |\n| P2P地震情報 | 地震 | 30秒 | コミュニティベースの地震情報 |\n| IHR (Internet Health Report) | ネットワーク障害 | 5分 | BGP/ネットワーク異常検知 |\n\n## 速報種別\n- 地震速報（気象庁/USGS/P2P）\n- 津波警報（気象庁）\n- 気象警報（気象庁）\n- 火山情報（気象庁）\n- ネットワーク障害（IHR）\n\n## Getting Started\n1. [アカウント登録](https://www.alert-jp.org/signup)\n2. API Keyを取得\n3. エンドポイントを呼び出し\n\n## サポート\n- ドキュメント: https://docs.alert-jp.org\n- ステータス: https://status.alert-jp.org\n- お問い合わせ: https://www.alert-jp.org/contact\n","version":"1.1.0","contact":{"name":"Alert-JP","url":"https://www.alert-jp.org"},"license":{"name":"利用規約","url":"https://www.alert-jp.org/terms"}},"servers":[{"url":"https://api.alert-jp.org","description":"本番環境"},{"url":"http://localhost:3083","description":"ローカル開発環境"}],"tags":[{"name":"Standard","description":"標準エンドポイント（ヘルスチェック等）- Marduk仕様準拠"},{"name":"Alerts","description":"アラート情報取得"},{"name":"Realtime","description":"リアルタイム配信（SSE/WebSocket）"},{"name":"Admin","description":"管理機能（内部用）"},{"name":"External Pollers","description":"外部ポーラー管理（USGS/P2P/IHR）"},{"name":"Feeds","description":"RSSフィード"},{"name":"Statistics","description":"統計情報"},{"name":"Education","description":"教育・防災啓発"},{"name":"Business","description":"Business API（メディア・企業向け）- X-Business-API-Key 認証必須"}],"paths":{"/health":{"get":{"tags":["Standard"],"summary":"Health check","description":"APIの稼働状況を確認","responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"healthy"},"service":{"type":"string","example":"alert-jp-api"},"timestamp":{"type":"string","format":"date-time"}}}}}}},"operationId":"getHealth","security":[]}},"/version":{"get":{"tags":["Standard"],"summary":"Get the API version and build info.","description":"APIのバージョン情報とMarduk仕様バージョン","responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionResponse"}}}}},"operationId":"getVersion"}},"/ready":{"get":{"tags":["Standard"],"summary":"Readiness probe — returns 200 when ready to serve traffic.","description":"Kubernetes/orchestrator用のReadinessプローブ","responses":{"200":{"description":"準備完了","content":{"application/json":{"schema":{"type":"object","properties":{"ready":{"type":"boolean","example":true},"timestamp":{"type":"string","format":"date-time"}}}}}}},"operationId":"getReady"}},"/metrics":{"get":{"tags":["Standard"],"summary":"API metrics in JSON or Prometheus format.","description":"Prometheus形式のメトリクス情報","responses":{"200":{"description":"メトリクス","content":{"text/plain":{"schema":{"type":"string","example":"# HELP http_requests_total Total HTTP requests\n# TYPE http_requests_total counter\nhttp_requests_total{method=\"GET\",status=\"200\"} 1234\n"}}}}},"operationId":"getMetrics"}},"/stats":{"get":{"tags":["Statistics"],"summary":"Aggregated alert statistics across all regions and alert types.","description":"アラート統計と配信パフォーマンス","responses":{"200":{"description":"統計情報","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}},"operationId":"getStats"}},"/api/v1/alerts":{"get":{"tags":["Alerts"],"summary":"List recent Japanese emergency alerts (earthquake, weather, etc.).","description":"最新のアラート情報を取得","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100},"description":"Maximum number of results to return","example":20},{"name":"type","in":"query","description":"アラート種別でフィルタ","schema":{"$ref":"#/components/schemas/AlertType"},"example":"standard"},{"name":"source","in":"query","description":"データソースでフィルタ","schema":{"$ref":"#/components/schemas/AlertSource"},"example":"jma"},{"name":"severity","in":"query","schema":{"type":"string","enum":["minor","moderate","severe","extreme"]},"description":"Severity","example":"severe"}],"responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Alert"}}}}}}}},"operationId":"getAlerts"}},"/api/v1/alerts/{id}":{"get":{"tags":["Alerts"],"summary":"Get the full record for one Japanese emergency alert by ID.","description":"Returns the full record for one alert — original source feed payload, parsed structured fields, affected regions, severity escalation history.\n","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique resource identifier","example":"abc-123"}],"responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"404":{"description":"アラートが見つかりません"}},"operationId":"getAlertsId"}},"/api/v1/stream/alerts":{"get":{"tags":["Realtime"],"summary":"Server-Sent Events stream of live emergency alerts as they arrive.","description":"Server-Sent Eventsでリアルタイムアラート配信\n\n## 使用例\n```javascript\nconst es = new EventSource('https://api.alert-jp.org/api/v1/stream/alerts', {\n  headers: {\n    'X-API-Key': 'YOUR_API_KEY'\n  }\n});\n\nes.addEventListener('alert', (event) => {\n  const alert = JSON.parse(event.data);\n  console.log('新しいアラート:', alert);\n});\n\nes.addEventListener('connected', (event) => {\n  const data = JSON.parse(event.data);\n  console.log('接続ID:', data.sessionId);\n});\n```\n\n## イベント種別\n- `connected`: 接続確立時\n- `alert`: 新しいアラート受信時\n- `heartbeat`: 接続維持用（30秒ごと）\n","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"SSE接続確立","content":{"text/event-stream":{"schema":{"type":"string"},"example":"event: connected\ndata: {\"sessionId\":\"abc123\",\"timestamp\":\"2025-01-15T12:00:00Z\"}\n\nevent: alert\ndata: {\"id\":\"earthquake-001\",\"type\":\"earthquake\",\"title\":\"震度5強\",\"severity\":\"high\"}\n"}}},"401":{"description":"認証エラー"}},"operationId":"getSseAlerts"}},"/api/v1/ws/alerts":{"get":{"tags":["Realtime"],"summary":"WebSocket stream of live emergency alerts (alternative to SSE).","description":"WebSocketでリアルタイムアラート配信\n\n## 使用例\n```javascript\nconst ws = new WebSocket('wss://api.alert-jp.org/api/v1/ws/alerts?apiKey=YOUR_API_KEY');\n\nws.onopen = () => {\n  console.log('WebSocket接続確立');\n};\n\nws.onmessage = (event) => {\n  const data = JSON.parse(event.data);\n  if (data.event === 'alert') {\n    console.log('新しいアラート:', data.data);\n  }\n};\n\nws.onerror = (error) => {\n  console.error('WebSocketエラー:', error);\n};\n```\n\n## メッセージ形式\n- `{\"event\":\"connected\",\"data\":{...}}`: 接続確立\n- `{\"event\":\"alert\",\"data\":{...}}`: 新しいアラート\n- `{\"event\":\"heartbeat\",\"data\":{...}}`: 接続維持\n","parameters":[{"name":"apiKey","in":"query","required":true,"schema":{"type":"string"},"description":"API Key（クエリパラメータで指定）","example":"pk_live_..."}],"responses":{"101":{"description":"WebSocket接続確立"},"401":{"description":"認証エラー"}},"operationId":"getWsAlerts"}},"/api/v1/admin/polling/status":{"get":{"tags":["Admin"],"summary":"Get JMA-polling status (admin) — last fetch time, errors.","description":"Returns current status of the JMA-polling worker — last successful fetch time, error count, items ingested.\n","responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"totalPollers":{"type":"integer"},"activePollers":{"type":"integer"},"effectiveInterval":{"type":"string"},"mostRecentPoll":{"type":"string","format":"date-time"}}}}}}}}},"operationId":"getAdminPollingStatus"}},"/api/v1/admin/polling/start":{"post":{"tags":["Admin"],"summary":"Start JMA polling (admin). Resumes alert ingest from JMA feeds.","description":"Starts the JMA-polling worker if stopped. Idempotent — no-op if already running.\n","responses":{"200":{"description":"開始成功"}},"operationId":"createAdminPollingStart"}},"/api/v1/admin/external-pollers/status":{"get":{"tags":["External Pollers"],"summary":"Get status of all external alert-source pollers (admin).","description":"USGS、P2P、IHRの全ポーラー状態を一括取得","responses":{"200":{"description":"ポーラー状態一覧","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalPollersStatus"}}}}},"operationId":"getAdminExternalPollersStatus"}},"/api/v1/admin/external-pollers/start":{"post":{"tags":["External Pollers"],"summary":"Start all external alert-source pollers (admin).","description":"USGS、P2P、IHRの全ポーラーを一括開始","responses":{"200":{"description":"開始成功","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"results":{"type":"object"}}}}}}},"operationId":"createAdminExternalPollersStart"}},"/api/v1/admin/external-pollers/stop":{"post":{"tags":["External Pollers"],"summary":"Stop all external alert-source pollers (admin).","description":"Stops every external alert-source poller. Used during incidents to halt ingest.\n","responses":{"200":{"description":"停止成功"}},"operationId":"createAdminExternalPollersStop"}},"/api/v1/admin/external-pollers/{name}/status":{"get":{"tags":["External Pollers"],"summary":"Get status of one named external alert-source poller (admin).","description":"Returns status for one named external alert-source poller.\n","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","enum":["usgs","p2p","ihr"]},"description":"ポーラー名","example":"usgs"}],"responses":{"200":{"description":"ポーラー状態","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollerStatus"}}}}},"operationId":"getAdminExternalPollersNameStatus"}},"/api/v1/admin/external-pollers/{name}/start":{"post":{"tags":["External Pollers"],"summary":"Start one named external alert-source poller (admin).","description":"Starts one named external alert-source poller. Idempotent.\n","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","enum":["usgs","p2p","ihr"]},"description":"Name","example":"usgs"}],"responses":{"200":{"description":"開始成功"}},"operationId":"createAdminExternalPollersNameStart"}},"/api/v1/admin/external-pollers/{name}/test":{"get":{"tags":["External Pollers"],"summary":"Test connectivity to one external alert source (admin).","description":"外部APIへの接続テストを実行","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","enum":["usgs","p2p","ihr"]},"description":"Name","example":"usgs"}],"responses":{"200":{"description":"テスト成功","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}}},"operationId":"getAdminExternalPollersNameTest"}},"/api/v1/feed/rss":{"get":{"tags":["Feeds"],"summary":"RSS 2.0 feed of recent emergency alerts (for feed readers).","description":"Returns recent alerts as an RSS 2.0 feed for compatibility with feed readers.\n","responses":{"200":{"description":"RSSフィード","content":{"application/rss+xml":{"schema":{"type":"string"}}}}},"operationId":"getFeedRss"}},"/api/v1/feed/atom":{"get":{"tags":["Feeds"],"summary":"Atom 1.0 feed of recent emergency alerts (for feed readers).","description":"Returns recent alerts as an Atom 1.0 feed for compatibility with feed readers.\n","responses":{"200":{"description":"Atomフィード","content":{"application/atom+xml":{"schema":{"type":"string"}}}}},"operationId":"getFeedAtom"}},"/api/v1/education/tips":{"get":{"tags":["Education"],"summary":"List disaster-preparedness tips (educational content).","description":"防災豆知識の一覧を取得します。カテゴリでフィルタできます。","parameters":[{"name":"category","in":"query","description":"カテゴリでフィルタ","schema":{"type":"string","enum":["earthquake","tsunami","typhoon","flood","general"]},"example":"general"}],"responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/PreventionTip"}},"meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"total":{"type":"integer"},"categories":{"type":"array","items":{"type":"string"}}}}}}}}}},"operationId":"getEducationTips"}},"/api/v1/education/tips/{id}":{"get":{"tags":["Education"],"summary":"Get one disaster-preparedness tip (educational) by ID.","description":"指定IDの防災豆知識を取得します。","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"豆知識ID","example":"abc-123"}],"responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/PreventionTip"},"meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"}}}}}}}},"404":{"description":"豆知識が見つかりません"}},"operationId":"getEducationTipsId"}},"/api/v1/education/quiz":{"get":{"tags":["Education"],"summary":"Get a random disaster-preparedness quiz question.","description":"防災に関するランダムなクイズを出題します。カテゴリでフィルタできます。","parameters":[{"name":"category","in":"query","description":"カテゴリでフィルタ","schema":{"type":"string","enum":["earthquake","tsunami","typhoon","flood","general"]},"example":"general"}],"responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Quiz"},"meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"total_quizzes":{"type":"integer"}}}}}}}},"404":{"description":"該当カテゴリのクイズが見つかりません"}},"operationId":"getEducationQuiz"}},"/api/v1/education/prevention-tip":{"get":{"tags":["Education"],"summary":"Get a random disaster-preparedness tip (educational).","description":"ランダムな防災豆知識（地震、津波、台風など）を返します。教育目的や日常の備えとして利用できます。","responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/PreventionTip"},"meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"total_tips":{"type":"integer"}}}}}}}}},"operationId":"getEducationPreventionTip"}},"/api/v1/alerts/easy":{"get":{"tags":["Education"],"summary":"Get alerts rewritten in simplified \"easy\" Japanese (やさしい日本語).","description":"最新の防災アラートを、外国人や子供にも分かりやすい「やさしい日本語」に変換して返します。AI (Claude 3.5 Sonnet) を使用します。","responses":{"200":{"description":"正常","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EasyAlert"},"meta":{"type":"object","properties":{"tokens_used":{"type":"integer"},"model":{"type":"string"},"cached":{"type":"boolean"}}}}}}}},"503":{"description":"AIサービス未設定または利用不可","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string","example":"CONFIG_ERROR"},"message":{"type":"string"}}}}}}}}},"operationId":"getAlertsEasy"}},"/api/business/v1/alerts":{"get":{"tags":["Business"],"summary":"List alerts via the Business-tier alerts endpoint (auth required).","description":"高優先度アラート配信（5秒以内保証）。\nフィルタリング、XML形式出力に対応。\n","security":[{"BusinessApiKeyAuth":[]}],"parameters":[{"name":"types","in":"query","description":"アラート種別でフィルタ（カンマ区切り）","schema":{"type":"string","example":"earthquake,tsunami"}},{"name":"areas","in":"query","description":"地域でフィルタ（カンマ区切り）","schema":{"type":"string"},"example":"tokyo,osaka,kanagawa"},{"name":"severity","in":"query","description":"深刻度でフィルタ（カンマ区切り）","schema":{"type":"string","example":"extreme,severe"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100},"description":"Maximum number of results to return","example":20},{"name":"format","in":"query","description":"レスポンス形式","schema":{"type":"string","enum":["json","xml"],"default":"json"},"example":"json"}],"responses":{"200":{"description":"アラート一覧","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/BusinessAlert"}},"meta":{"$ref":"#/components/schemas/BusinessMeta"}}}}}},"401":{"description":"認証エラー"}},"operationId":"getBusinessV1Alerts"}},"/api/business/v1/alerts/{id}":{"get":{"tags":["Business"],"summary":"Get one alert via the Business-tier endpoint (auth required).","description":"Returns one alert via the Business-tier endpoint with full extended fields.\n","security":[{"BusinessApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Unique resource identifier","example":"abc-123"}],"responses":{"200":{"description":"アラート詳細","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/BusinessAlert"}}}}}},"401":{"description":"認証エラー"},"404":{"description":"アラートが見つかりません"}},"operationId":"getBusinessV1AlertsId"}},"/api/business/v1/alerts/stream":{"get":{"tags":["Business"],"summary":"Business-tier SSE stream of live alerts (auth required).","description":"Server-Sent Eventsでリアルタイムアラート配信（Business専用・優先配信）","security":[{"BusinessApiKeyAuth":[]}],"responses":{"200":{"description":"SSE接続確立","content":{"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"認証エラー"}},"operationId":"getBusinessV1AlertsStream"}},"/api/business/v1/usage":{"get":{"tags":["Business"],"summary":"Get the caller's API usage and remaining quota.","description":"当月のAPI使用状況をD1データベースから取得","security":[{"BusinessApiKeyAuth":[]}],"responses":{"200":{"description":"使用状況","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/BusinessUsage"}}}}}},"401":{"description":"認証エラー"}},"operationId":"getBusinessV1Usage"}},"/v1/metadata/enums":{"get":{"summary":"List every enum used by the alert-jp API.","description":"Returns the directory of enums (alert types, severity levels, region\ncodes, source feeds) with localised labels. Use when building UIs\nthat mirror the API's vocabulary.\n","operationId":"listEnums","tags":["Metadata"],"security":[],"responses":{"200":{"description":"Enum metadata"}}}},"/v1/metadata/enums/{name}":{"get":{"summary":"Get one alert-jp enum (alert_type, severity, region_code) by name.","description":"Returns localised values for one enum. See `listEnums` for the directory of available enum names.\n","operationId":"getEnum","tags":["Metadata"],"security":[],"parameters":[{"name":"name","in":"path","required":true,"example":"alert_type","schema":{"type":"string"}}],"responses":{"200":{"description":"Enum values"}}}}},"components":{"schemas":{"AlertType":{"type":"string","enum":["earthquake","tsunami","weather","volcanic","network","other"],"description":"アラート種別:\n- `earthquake`: 地震速報\n- `tsunami`: 津波警報\n- `weather`: 気象警報\n- `volcanic`: 火山情報\n- `network`: ネットワーク障害\n- `other`: その他\n"},"AlertSource":{"type":"string","enum":["jma","usgs","p2p","ihr","manual"],"description":"データソース:\n- `jma`: 気象庁（Japan Meteorological Agency）\n- `usgs`: 米国地質調査所（US Geological Survey）\n- `p2p`: P2P地震情報\n- `ihr`: Internet Health Report\n- `manual`: 手動登録\n"},"Alert":{"type":"object","required":["id","type","title","severity","issuedAt"],"properties":{"id":{"type":"string","example":"usgs-earthquake-us7000n3gb","description":"アラートの一意識別子"},"type":{"$ref":"#/components/schemas/AlertType"},"source":{"$ref":"#/components/schemas/AlertSource"},"title":{"type":"string","example":"M6.2 - 150km ENE of Katsuura, Japan"},"description":{"type":"string","description":"アラートの詳細説明"},"severity":{"type":"string","enum":["minor","moderate","severe","extreme"],"description":"深刻度レベル"},"areas":{"type":"array","items":{"type":"string"},"description":"影響を受ける地域"},"location":{"type":"object","properties":{"latitude":{"type":"number","example":35.6895},"longitude":{"type":"number","example":139.6917},"depth":{"type":"number","description":"震源の深さ（km）"}},"description":"位置情報（地震の場合）"},"magnitude":{"type":"number","example":6.2,"description":"マグニチュード（地震の場合）"},"issuedAt":{"type":"string","format":"date-time","description":"アラート発行時刻"},"validUntil":{"type":"string","format":"date-time","description":"アラート有効期限"},"metadata":{"type":"object","additionalProperties":true,"description":"ソース固有の追加データ"},"rawData":{"type":"object","description":"元データ（デバッグ用）"}}},"VersionResponse":{"type":"object","properties":{"service":{"type":"string","example":"alert-jp-api"},"version":{"type":"string","example":"1.1.0"},"marduk_version":{"type":"string","example":"2.1.0"},"api_version":{"type":"string","example":"v1"},"commit":{"type":"string","description":"Gitコミットハッシュ"},"build_time":{"type":"string","format":"date-time"}}},"StatsResponse":{"type":"object","properties":{"totalAlerts":{"type":"integer","description":"総アラート数"},"alertsByType":{"type":"object","additionalProperties":{"type":"integer"}},"alertsBySource":{"type":"object","additionalProperties":{"type":"integer"}},"recentAlerts":{"type":"integer","description":"過去24時間のアラート数"},"averageDeliveryTime":{"type":"number","description":"平均配信時間（ミリ秒）"}}},"PollerStatus":{"type":"object","properties":{"name":{"type":"string","example":"usgs-poller"},"isActive":{"type":"boolean"},"lastPollTime":{"type":"string","format":"date-time"},"nextPollTime":{"type":"string","format":"date-time"},"pollInterval":{"type":"integer","description":"ポーリング間隔（ミリ秒）"},"successRate":{"type":"number","description":"成功率（0-1）"},"recentPolls":{"type":"array","items":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"duration":{"type":"integer"},"alertsFound":{"type":"integer"},"status":{"type":"string","enum":["success","error"]}}}}}},"ExternalPollersStatus":{"type":"object","properties":{"usgs":{"$ref":"#/components/schemas/PollerStatus"},"p2p":{"$ref":"#/components/schemas/PollerStatus"},"ihr":{"$ref":"#/components/schemas/PollerStatus"},"summary":{"type":"object","properties":{"totalPollers":{"type":"integer","example":3},"activePollers":{"type":"integer"},"totalAlertsToday":{"type":"integer","example":123}}}}},"PreventionTip":{"type":"object","properties":{"id":{"type":"string","example":"eq-01"},"category":{"type":"string","enum":["earthquake","tsunami","typhoon","flood","general"],"example":"earthquake"},"title":{"type":"string","example":"Drop, Cover, and Hold On"},"content":{"type":"string","example":"When an earthquake strikes, drop to your hands and knees..."}}},"EasyAlert":{"type":"object","properties":{"id":{"type":"string","example":"alert-001"},"type":{"type":"string","example":"earthquake"},"original":{"type":"string","description":"元のアラート文","example":"緊急地震速報。強い揺れに警戒してください。"},"easy_japanese":{"type":"string","description":"やさしい日本語に変換されたアラート文","example":"おおきな じしんが きます。 つよい ゆれに きをつけて ください。"},"timestamp":{"type":"string","format":"date-time"}}},"Quiz":{"type":"object","properties":{"id":{"type":"string","example":"quiz-01"},"category":{"type":"string","enum":["earthquake","tsunami","typhoon","flood","general"],"example":"earthquake"},"question":{"type":"string","example":"What should you do first when an earthquake strikes?"},"choices":{"type":"array","items":{"type":"string"},"example":["Run outside immediately","Drop to your hands and knees","Stand in a doorway","Call emergency services"]},"correct_index":{"type":"integer","example":1},"explanation":{"type":"string","example":"The recommended action is to Drop, Cover, and Hold On."}}},"BusinessAlert":{"allOf":[{"$ref":"#/components/schemas/Alert"},{"type":"object","properties":{"_business":{"type":"object","properties":{"tier":{"type":"string","enum":["standard","premium","enterprise"]},"priority":{"type":"string","enum":["normal","high","critical"]},"deliveryTime":{"type":"string","format":"date-time"},"apiVersion":{"type":"string","example":"business/v1"}}}}}]},"BusinessMeta":{"type":"object","properties":{"count":{"type":"integer"},"tier":{"type":"string","enum":["standard","premium","enterprise"]},"timestamp":{"type":"string","format":"date-time"},"sla":{"type":"object","properties":{"targetLatency":{"type":"string","example":"5s"},"guaranteedUptime":{"type":"string","example":"99.9%"}}}}},"BusinessUsage":{"type":"object","properties":{"customerId":{"type":"string"},"tier":{"type":"string","enum":["standard","premium","enterprise"]},"period":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"usage":{"type":"object","properties":{"apiCalls":{"type":"integer"},"websocketConnections":{"type":"integer"}}},"quota":{"type":"object","properties":{"calls":{"oneOf":[{"type":"integer"},{"type":"string","enum":["unlimited"]}]},"remaining":{"oneOf":[{"type":"integer"},{"type":"string","enum":["unlimited"]}]}}}}}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"APIキー認証"},"BusinessApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Business-API-Key","description":"Business APIキー認証（メディア・企業向け）"}}},"security":[{"ApiKeyAuth":[]}]}