有影儀表板公開 API

公開、唯讀的 YouTube 觀測資料。本頁內容由 OpenAPI 目錄產生的 docs/api.md 呈現,與機器可讀規格同一來源;完整限制以 OpenAPI 規格為準。

公開取用有影儀表板的影片、頻道排行、直播觀測與議題標籤資料。標籤來源:新文易數(tag.observe.tw)。YouTube 頻道分類(/tags)與內容標籤(/vocabulary、/keywords)分開;新聞文章數不等於影片數。標籤快照的 coverage 與 version 說明同步範圍,觀測期間快照不代表完整標籤池。

使用規則

  • 基底網址 https://youtube.observe.tw。查詢使用 GET(也接受 HEAD),回傳 UTF-8 JSON。一般報表使用 data 與 meta;null 表示未知,不是零。
  • 公開查詢不需金鑰。每個 IP 每分鐘60次(IPv6 合併 /64);回應帶 x-ratelimit-limit、x-ratelimit-remaining、x-ratelimit-reset,超過回429與 Retry-After。請依 Retry-After 等待,勿更換來源規避限流。
  • 登入後在 /my/settings 建立個人 API 金鑰,每人最多3把有效金鑰、累計最多建立100把(含已撤銷);以 x-api-key: ytb_… 傳送,同一帳號所有金鑰合計每分鐘1000次。伺服器只存 SHA-256,明文只在建立時顯示。失效或撤銷的金鑰使用匿名額度;金鑰不授予帳號或管理權限,勿放在網址、日誌或公開程式碼中。
  • 額外防濫用預算:每個 IP 網段每分鐘最多1000次金鑰驗證;IPv6 /48 合計4000次;單一 gateway 每分鐘保留匿名4000次與金鑰8000次,合計12000次;兩者不互相借用。未知金鑰每網段最多20次未命中驗證,超過後使用匿名額度並禁止共享快取。共享網路或過載時,這些上限可能先於個別額度生效。
  • 允許跨網域,CORS Access-Control-Allow-Origin: *,不傳送跨站憑證。
  • v1 所有時間點(instant)一律為 UTC ISO 8601,以 Z 結尾,例如 2026-10-11T16:00:00.000Z;需要台北時間請自行轉換為 Asia/Taipei(UTC+8)。「一天」與日期視窗指台北日曆日,日期型欄位(YYYY-MM-DD)與 from/to 日期參數不轉換時區。舊 PHP API 保留相容格式。
  • 回應帶 Cache-Control:直播通常30秒、一般報表60秒、詞彙300秒、規格3600秒;快取時間不是來源保證更新頻率。請勿更頻繁輪詢,並檢查 meta.updatedAt 與 coverage。CDN 命中不消耗源站額度,限流標頭可能是建立快取時的快照。
  • 帶 x-api-key、Authorization、Cookie 或 Set-Cookie 的回應 private, no-store;私人追蹤、個人 RSS 與管理介面不屬於公開 API。
  • 公開 v1 錯誤格式為 {"error":"訊息","code":"MACHINE_CODE"}(code 可省略)。400參數錯誤、404找不到、409狀態已改變、422讀取預算不足、429太頻繁、500非預期錯誤、501未支援、503資料來源暫時無法使用。舊 PHP 與私人帳號路徑保留既有錯誤格式。
  • 路徑參數須 URL 編碼,結尾不加 /。v1 發布後只做向後相容新增;移除或改名會先公告。部分報表的欄位文件仍標示 partial 或 envelope-only,這表示文件深度,不表示功能未實作。
  • YouTube 標題、縮圖與影片內容著作權屬原頻道。本 API 提供公開標題、連結、統計與短摘要,不提供完整逐字稿。引用請註明「資料來源:有影儀表板 youtube.observe.tw」並保留原影片連結。
  • 不寫程式也能追:RSS /feeds/videos.xml 支援影片搜尋條件(q 最長100個 UTF-16 字元);網址清單在 /sitemap.xml。

分頁與狀態

影片列表保留 limit/offset。依 publishedAt 排序時,可將 nextCursor 放入 cursor,保持其他篩選條件相同,offset 省略或為0;limit 可以調整。其他排序不提供 cursor。游標是有界公開選取器,並非憑證或資料庫一致性快照,24小時後過期。下一頁排除第一頁之後新增的較大 PK;既有資料更新仍可能改變結果。游標或標籤版本不相容回400。nextCursor 為 null 或不存在時停止;total 為 null 時請查看 totalStatus 與 hasNext。

相容性變更紀錄

  • 2026-10:時間戳統一改為 UTC(破壞性變更)。先前部分 v1 欄位輸出台北偏移,例如 2026-10-12T00:00:00+08:00,少數欄位輸出無時區的台北時間,例如 2026-10-12 00:00:00;本次發布起同一時間點一律改為 2026-10-11T16:00:00.000Z。表示的時間點不變,但字串不同:直接比較字串、切字串取日期或小時、或比對 +08:00 的程式須改用 ISO 8601 解析,需要時再轉換為 Asia/Taipei。影響範圍:影片與頻道 publishedAt/updatedAt、直播 startedAt 與逐時 trend/series 的 time、meta.updatedAt 與報表 updatedAt、報表 datetime 欄(例如 /groups/:name 的 updatedAt、留言收錄 latestComment/observedAt、頻道 AI 來源 from/to)、影片分析逐時 time 與 latestAt、首頁標籤 from/to/comparison/vocabularyWindow、/vocabulary 的 window 與 publishedAt、標籤關係 createdAt、/ai/days 的 dateFrom/dateTo、AI 提示詞預覽 period,以及文字雲 periods.*.observedUntil。YYYY-MM-DD 日期欄位、台北日曆日視窗、說明文字中的「台北時間」與舊 PHP API 不受影響。

/api/status 在瀏覽器呈現 HTML,以 Accept: application/json 取得 JSON。只顯示 API 回應狀態與端點用途,不代表資料新鮮度或背景擷取正常。/api/v1/status 保留端點清單格式。36支舊 PHP API 保留相容輸出,新舊對照見下方。未知 /api/v1/* 報表回501。

規格與文件入口

  • API index: GET /api/v1
  • OpenAPI 3.1: GET /api/v1/openapi.json
  • Availability: GET /api/status with Accept: application/json
  • Human documentation: /api

快速開始

Examples below use synthetic fixtures. Availability and quotas depend on the deployed release; this generated document is not deployment evidence.

bash

curl --fail-with-body --get 'https://youtube.observe.tw/api/v1/videos' \
  --data-urlencode 'q=交通' --data-urlencode 'limit=20' \
  | jq '{rows: .data.rows, nextCursor: .data.nextCursor, totalStatus: .data.totalStatus, coverage: .meta.coverage}'

curl --fail-with-body --get 'https://youtube.observe.tw/api/v1/vocabulary' \
  --data-urlencode 'q=交通' --data-urlencode 'limit=20' \
  | jq '.data | {version, source, coverage, rows}'

Follow a cursor without changing filters. Keep API keys in an HTTP header, never in the URL. Respect Retry-After if a request returns 429.

js

const base = new URL('https://youtube.observe.tw/api/v1/videos');
base.searchParams.set('q', '交通');
base.searchParams.set('limit', '20');
let cursor;
do {
  const url = new URL(base);
  if (cursor) url.searchParams.set('cursor', cursor);
  const response = await fetch(url);
  if (!response.ok) throw new Error(`API HTTP ${response.status}`);
  const {data, meta} = await response.json();
  console.log(data.rows, meta.coverage);
  cursor = data.nextCursor;
} while (cursor);
常用情境(curl + jq)

bash

# 熱門標籤:今日與近七日、比對覆蓋率與已知觀看值
curl --fail-with-body 'https://youtube.observe.tw/api/v1/home' | jq '.data.exploration | {keywordToday, keywords}'

# 頻道排行:每週觀看數前十名
curl --fail-with-body 'https://youtube.observe.tw/api/v1/channels?column=view_week&limit=10' | jq '.data.rows'

# 某頻道最新影片:8為站內頻道ID,可從頻道目錄取得
curl --fail-with-body 'https://youtube.observe.tw/api/v1/channels/8/videos?limit=20' | jq '.data | {rows, nextCursor}'

# 目前直播中的頻道與觀眾數
curl --fail-with-body 'https://youtube.observe.tw/api/v1/live/current?limit=20' | jq '.data.rows'

# 人工確認的事件清單;取得UUID後查看同事件各來源(空清單表示尚未建立)
curl --fail-with-body 'https://youtube.observe.tw/api/v1/editorial/events?limit=10' | jq '.data'
curl --fail-with-body 'https://youtube.observe.tw/api/v1/editorial/events/<事件UUID>' | jq '.data | {event, sources, metricPolicy}'
Synthetic response: /api/v1/channels

json

{
  "data": {
    "rows": [
      {
        "id": 990001,
        "youtubeId": "UCSynthetic990001",
        "title": "範例新聞甲(合成)",
        "avatar": null,
        "thumbnail": null,
        "description": null,
        "publishedAt": null,
        "youtubeUrl": "https://www.youtube.com/channel/UCSynthetic990001",
        "views": null,
        "subscribers": null,
        "videoCount": null,
        "weeklyViews": 1000,
        "monthlyViews": null,
        "weeklySubscribers": null,
        "weeklyVideos": null,
        "monthlySubscribers": null,
        "monthlyVideos": null,
        "estimatedWeeklyViews": null,
        "estimatedMonthlyViews": null,
        "monthlyEstimateGap": null,
        "legacyGrowthPercent": null,
        "averageWeeklyViewsPerVideo": null,
        "updatedAt": "2026-10-11T10:00:00.000Z",
        "tags": [
          {
            "id": 990001,
            "name": "範例分類(合成)",
            "kind": "channel"
          }
        ]
      }
    ],
    "total": 1,
    "limit": 50,
    "offset": 0,
    "ranking": {
      "column": "view_week",
      "scope": "directory",
      "min": null,
      "minMetric": "subscribers"
    }
  },
  "meta": {
    "schemaVersion": 1,
    "requestedAt": "2026-10-11T10:00:00.000Z",
    "updatedAt": "2026-10-11T10:00:00.000Z",
    "timezone": "Asia/Taipei",
    "source": "mariadb",
    "dataset": "fixture",
    "coverage": {},
    "warnings": [
      "Synthetic documentation example; not production observations."
    ]
  }
}
Synthetic response: /api/v1/videos

json

{
  "data": {
    "rows": [
      {
        "id": "FixtureAa01",
        "channelId": 990001,
        "youtubeChannelId": "UCSynthetic990001",
        "channelTitle": "範例新聞甲(合成)",
        "title": "合成:城市交通規劃",
        "description": "",
        "channelAvatar": null,
        "thumbnail": "https://i.ytimg.com/vi/FixtureAa01/mqdefault.jpg",
        "publishedAt": "2026-10-11T10:00:00.000Z",
        "views": 200,
        "likes": 5,
        "comments": null,
        "updatedAt": "2026-10-11T10:00:00.000Z",
        "youtubeUrl": "https://www.youtube.com/watch?v=FixtureAa01"
      }
    ],
    "total": null,
    "totalStatus": "not-computed",
    "hasNext": false,
    "limit": 50,
    "offset": 0,
    "nextCursor": null
  },
  "meta": {
    "schemaVersion": 1,
    "requestedAt": "2026-10-11T10:00:00.000Z",
    "updatedAt": "2026-10-11T10:00:00.000Z",
    "timezone": "Asia/Taipei",
    "source": "mariadb",
    "dataset": "fixture",
    "coverage": {},
    "warnings": [
      "Synthetic documentation example; not production observations."
    ]
  }
}
Synthetic response: /api/v1/keywords/:keyword/relations

json

{
  "data": {
    "keyword": "交通",
    "source": "https://tag.observe.tw",
    "sourceUrl": "https://tag.observe.tw/tag/%E4%BA%A4%E9%80%9A/",
    "status": "disabled",
    "reason": "disabled",
    "tagId": null,
    "truncated": false,
    "relations": [],
    "retryAfterSeconds": null
  },
  "meta": {
    "schemaVersion": 1,
    "requestedAt": "2026-10-11T10:00:00.000Z",
    "updatedAt": null,
    "timezone": "Asia/Taipei",
    "source": "tag.observe.tw",
    "dataset": "fixture",
    "coverage": {},
    "warnings": [
      "Synthetic documentation example; not production observations."
    ]
  }
}
Synthetic response: /api/v1/videos/:id/tags

json

{
  "data": {
    "videoId": "FixtureAa01",
    "version": "synthetic-vocabulary",
    "status": "matched",
    "matchedAt": "2026-10-11T10:00:00.000Z",
    "source": "https://tag.observe.tw",
    "rows": [
      {
        "key": "example-term-key",
        "term": "交通",
        "field": "title",
        "start": 5,
        "end": 7,
        "text": "交通",
        "snippet": "合成:城市交通規劃",
        "snippetStart": 0,
        "ruleVersion": "exact-text-v1"
      }
    ]
  },
  "meta": {
    "schemaVersion": 1,
    "requestedAt": "2026-10-11T10:00:00.000Z",
    "updatedAt": "2026-10-11T10:00:00.000Z",
    "timezone": "Asia/Taipei",
    "source": "mariadb",
    "dataset": "fixture",
    "coverage": {},
    "warnings": [
      "Synthetic documentation example; not production observations."
    ]
  }
}
Synthetic response: /api/v1/vocabulary

json

{
  "data": {
    "rows": [
      {
        "key": "example-term-key",
        "term": "交通",
        "articleCount": 3,
        "media": [
          "範例媒體"
        ],
        "provenance": "upstream-article-tag-origin-unspecified"
      }
    ],
    "total": 1,
    "limit": 50,
    "offset": 0,
    "version": "synthetic-vocabulary",
    "source": "https://tag.observe.tw",
    "attribution": "標籤來源:新文易數(tag.observe.tw)",
    "window": {
      "since": "2026-10-09T16:00:00.000Z",
      "until": "2026-10-10T16:00:00.000Z"
    },
    "publishedAt": "2026-10-11T01:00:00.000Z",
    "coverage": "observed-article-window",
    "upstreamSnapshotConsistent": false
  },
  "meta": {
    "schemaVersion": 1,
    "requestedAt": "2026-10-11T10:00:00.000Z",
    "updatedAt": "2026-10-11T10:00:00.000Z",
    "timezone": "Asia/Taipei",
    "source": "mariadb",
    "dataset": "fixture",
    "coverage": {},
    "warnings": [
      "Synthetic documentation example; not production observations."
    ]
  }
}

端點一覽

Schema coverage partial or envelope-only explicitly identifies incomplete field documentation. Legacy entries retain their existing wire types. HEAD may be generated by Fastify for GET; private auth/ops routes are excluded.

MethodPathSummarySchema coverage
GET
/api/v1Public API catalogdetailed
GET
/api/v1/openapi.jsonOpenAPI 3.1 specificationpartial
GET
/api/v1/statusExisting read-only route inventorydetailed
GET
/api/statusPublic API availabilitydetailed
GET
/api/v1/filter-options/{kind}Bounded channel or taxonomy selectordetailed
GET
/api/v1/homeHome dashboard and independent today/seven-day explorationpartial
GET
/api/v1/channelsChannel directory and observed rankingsdetailed
GET
/api/v1/channels/{id}Channel profiledetailed
GET
/api/v1/channels/{id}/videosChannel videosdetailed
GET
/api/v1/tags/videosTaxonomy-filtered videosdetailed
GET
/api/v1/videosVideo searchdetailed
GET
/api/v1/keywords/{keyword}/videosVideos with fresh maintained vocabulary evidencedetailed
GET
/api/v1/keywords/illustrationsBulk maintained tag pictures for many keywords (word cloud): kind, same-origin image path, emoji and optional width/height aspect clamped to 0.25–8. Valid avatars win over visuals; malformed upstream entries are omitted, so a missing keyword is not proof of absence. No license attribution; read /keywords/{keyword}/illustration for credits. Enabled reads remain private/no-store.detailed
GET
/api/v1/keywords/{keyword}/relationsMaintained upstream tag relations; explicit activation after F1 publication. is-a is directional, related is not co-occurrence, and aliases do not merge identities. target.href is relative to https://tag.observe.tw, never this site. Enabled upstream reads remain private/no-store; no shared downstream caching.detailed
GET
/api/v1/keywords/{keyword}/illustrationMaintained tag picture and license attribution; optional explicit public/source-service mode. Browser images use same-origin bounded reads; no visitor credentials reach tag.detailed
GET
/api/v1/videos/{id}Video details and stored observationspartial
GET
/api/v1/videos/{id}/tagsVideo vocabulary matching evidencedetailed
GET
/api/v1/live/currentCurrent observed livestreamsdetailed
GET
/api/v1/tagsYouTube channel taxonomydetailed
GET
/api/v1/tags/{id}/channelsChannels in a taxonomy categorydetailed
GET
/api/v1/tags/{id}/videosVideos in a taxonomy categorydetailed
GET
/api/v1/ai/daysDaily AI topic evidenceenvelope-only
GET
/api/v1/ai/events/{id}AI event detailsenvelope-only
GET
/api/v1/ai/days/{id}/eventsNamed event in an AI daily recordenvelope-only
GET
/api/v1/vocabularyMaintained tag.observe.tw content vocabularydetailed
GET
/api/v1/keywordsContent vocabulary aliasdetailed
GET
/api/v1/videos/{id}/analyticsvideos · id · analyticsenvelope-only
GET
/api/v1/comments/authors/{key}comments · authors · keyenvelope-only
GET
/api/v1/ai/aspectsai · aspectsenvelope-only
GET
/api/v1/groupsgroupsenvelope-only
GET
/api/v1/groups/{name}groups · nameenvelope-only
GET
/api/v1/groups/{name}/rankinggroups · name · rankingenvelope-only
GET
/api/v1/groups/{name}/trendsgroups · name · trendsenvelope-only
GET
/api/v1/mayormayorenvelope-only
GET
/api/v1/mayor/cities/{city}mayor · cities · cityenvelope-only
GET
/api/v1/mayor/cities/{city}/people/{person}mayor · cities · city · people · personenvelope-only
GET
/api/v1/mayor/cities/{city}/people/{person}/days/{date}mayor · cities · city · people · person · days · dateenvelope-only
GET
/api/v1/editorial/eventseditorial · eventsenvelope-only
GET
/api/v1/editorial/events/{id}editorial · events · idenvelope-only
GET
/api/v1/channels/{id}/promptchannels · id · promptenvelope-only
GET
/api/v1/ai/days/promptai · days · promptenvelope-only
GET
/api/v1/ai/days/{date}/promptai · days · date · promptenvelope-only
GET
/api/v1/ai/days/{date}/{condition}/promptai · days · date · condition · promptenvelope-only
GET
/api/v1/ai/events/{id}/peopleai · events · id · peopleenvelope-only
GET
/api/v1/ai/events/{id}/wallai · events · id · wallenvelope-only
GET
/api/v1/ai/events/{id}/historyai · events · id · historyenvelope-only
GET
/api/v1/ai/days/{id}/events/historyai · days · id · events · historyenvelope-only
GET
/api/v1/live/dayslive · daysenvelope-only
GET
/api/v1/live/periodslive · periodsenvelope-only
GET
/api/v1/live/days/{date}live · days · dateenvelope-only
GET
/api/v1/live/channelslive · channelsenvelope-only
GET
/api/v1/live/trends/dailylive · trends · dailyenvelope-only
GET
/api/v1/live/hourslive · hoursenvelope-only
GET
/api/v1/live/tagslive · tagsenvelope-only
GET
/api/v1/live/groups/{group}/hourslive · groups · group · hoursenvelope-only
GET
/api/v1/keywords/{keyword}/live/trendskeywords · keyword · live · trendsenvelope-only
GET
/api/v1/groups/{name}/livegroups · name · liveenvelope-only
GET
/api/v1/tags/live/videostags · live · videosenvelope-only
GET
/api/v1/tags/{id}/live/videostags · id · live · videosenvelope-only
GET
/api/v1/live/continuouslive · continuousenvelope-only
GET
/api/v1/live/videos/{id}/trendlive · videos · id · trendenvelope-only
GET
/api/v1/live/walls/{variant}live · walls · variantenvelope-only
GET
/api/v1/tags/comparetags · compareenvelope-only
GET
/api/v1/keywords/{keyword}/groups/trendskeywords · keyword · groups · trendsenvelope-only
GET
/api/v1/ai/hoursai · hoursenvelope-only
GET
/api/v1/ai/periodsai · periodsenvelope-only
GET
/api/v1/channels/{id}/cloudchannels · id · cloudenvelope-only
GET
/api/v1/tags/cloudtags · cloudenvelope-only
GET
/api/v1/tags/{id}/cloudtags · id · cloudenvelope-only
GET
/api/v1/keywords/{keyword}/cloudkeywords · keyword · cloudenvelope-only
GET
/api/v1/tags/daystags · daysenvelope-only
GET
/api/v1/tags/trendstags · trendsenvelope-only
GET
/api/v1/tags/{id}/daystags · id · daysenvelope-only
GET
/api/v1/tags/{id}/trendstags · id · trendsenvelope-only
GET
/api/v1/keywords/{keyword}/dayskeywords · keyword · daysenvelope-only
GET
/api/v1/channels/{id}/commentschannels · id · commentsenvelope-only
GET
/api/v1/tags/commentstags · commentsenvelope-only
GET
/api/v1/tags/{id}/commentstags · id · commentsenvelope-only
GET
/api/v1/channels/{id}/trendschannels · id · trendsenvelope-only
GET
/api/v1/channels/{id}/aichannels · id · aienvelope-only
GET
/api/v1/channels/{id}/ai/dayschannels · id · ai · daysenvelope-only
GET
/api/v1/channels/{id}/peoplechannels · id · peopleenvelope-only
GET
/api/api_live_day.phpapi_live_daylegacy-wire
GET
/api/api_live_date.phpapi_live_datelegacy-wire
GET
/api/api_live_hour.phpapi_live_hourlegacy-wire
GET
/api/api_live_tag_date.phpapi_live_tag_datelegacy-wire
GET
/api/live_date.phplive_datelegacy-wire
GET
/api/live_tvbs.phplive_tvbslegacy-wire
GET
/api/video_live.phpvideo_livelegacy-wire
GET
/api/csv_live_line.phpcsv_live_linelegacy-wire
GET
/api/tags_list.phptags_listlegacy-wire
GET
/api/tags_index.phptags_indexlegacy-wire
GET
/api/tags_all.phptags_alllegacy-wire
GET
/api/video_tags.phpvideo_tagslegacy-wire
GET
/api/video_tags_title.phpvideo_tags_titlelegacy-wire
GET
/api/channels_list.phpchannels_listlegacy-wire
GET
/api/channel_videos.phpchannel_videoslegacy-wire
GET
/api/channels_videos.phpchannels_videoslegacy-wire
GET
/api/api_tag.phpapi_taglegacy-wire
GET
/api/api_tag_log.phpapi_tag_loglegacy-wire
GET
/api/tags_day.phptags_daylegacy-wire
GET
/api/tags_video.phptags_videolegacy-wire
GET
/api/tags_relation_date.phptags_relation_datelegacy-wire
GET
/api/tag_month.phptag_monthlegacy-wire
GET
/api/tag_period.phptag_periodlegacy-wire
GET
/api/tag_tags_days.phptag_tags_dayslegacy-wire
GET
/api/cloud.phpcloudlegacy-wire
GET
/api/cloud_tag_date.phpcloud_tag_datelegacy-wire
GET
/api/cloud_tag_date_noapi.phpcloud_tag_date_noapilegacy-wire
GET
/api/group_view.phpgroup_viewlegacy-wire
GET
/api/api_channel_log.phpapi_channel_loglegacy-wire
GET
/api/channel_pred.phpchannel_predlegacy-wire
GET
/api/ai_day.phpai_daylegacy-wire
GET
/api/api_topic.phpapi_topiclegacy-wire
GET
/api/api_event.phpapi_eventlegacy-wire
GET
/api/api_comment.phpapi_commentlegacy-wire
GET
/api/api_duration.phpapi_durationlegacy-wire
GET
/api/api_get_photo.phpapi_get_photolegacy-wire

參數

All path parameters are required. Query parameters are optional unless marked otherwise. For envelope-only reports, route-specific query documentation remains incomplete. Runtime rejects out-of-range values rather than silently clamping them.

/api/v1/filter-options/{kind}

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
kind (required)
path{"type":"string"}Route selector; preserve exact spelling.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
ids
query{"type":"string","maxLength":256}Up to twenty comma-separated IDs; cannot combine with nonempty q.
limit
query{"type":"integer","minimum":1,"maximum":20,"default":20}Maximum selector rows.
/api/v1/channels

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
column
query{"type":"string","enum":["viewCount","subscriberCount","videoCount","view_week","view_month","views_pred_week","views_pred_month","sub_week","sub_month","video_week","video_month"]}Directory default view_week; taxonomy default view_month. Estimates remain explicitly distinct from observations.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum subscribers, or cumulative views when an or taxonomy selector is supplied.
/api/v1/channels/{id}

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/channels/{id}/videos

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
limit
query{"type":"integer","minimum":1,"maximum":1000,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged. Cursor requests require 0 or omission.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
channelIds
query{"type":"string","maxLength":256}Up to twenty comma-separated local channel IDs.
column
query{"type":"string","enum":["publishedAt","viewCount","likeCount","commentCount"]}Descending order, with source PK as deterministic tie-breaker; default publishedAt.
from
query{"type":"string","format":"date"}Inclusive Taipei publication date.
to
query{"type":"string","format":"date"}Inclusive Taipei publication date.
since
query{"type":"string","format":"date-time"}Exact UTC publication start, inclusive; paired with until. Cannot combine with from/to/days/hours.
until
query{"type":"string","format":"date-time"}Exact UTC publication end, exclusive; paired with since, past window at most 90 days.
rankingPool
query{"type":"string","enum":["early"]}For keyword evidence with exact since/until: keep only same-window qualified news labels and display rules.
hours
query{"type":"integer","minimum":1,"maximum":8760}Relative publication window, anchored by the first cursor page.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum cumulative video views.
keyword
query{"type":"string","minLength":1,"maxLength":240}Exact maintained content term; not a taxonomy ID.
days
query{"type":"integer","minimum":1,"maximum":90}Optional relative date window when keyword filtering is used.
cursor
query{"type":"string","maxLength":1024}Opaque nextCursor from a previous publishedAt page; keep the same filters.
/api/v1/tags/videos

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":1000,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged. Cursor requests require 0 or omission.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
channelId
query{"type":"integer","minimum":1,"maximum":9007199254740991}Local numeric channel ID.
channelIds
query{"type":"string","maxLength":256}Up to twenty comma-separated local channel IDs.
column
query{"type":"string","enum":["publishedAt","viewCount","likeCount","commentCount"]}Descending order, with source PK as deterministic tie-breaker; default publishedAt.
from
query{"type":"string","format":"date"}Inclusive Taipei publication date.
to
query{"type":"string","format":"date"}Inclusive Taipei publication date.
since
query{"type":"string","format":"date-time"}Exact UTC publication start, inclusive; paired with until. Cannot combine with from/to/days/hours.
until
query{"type":"string","format":"date-time"}Exact UTC publication end, exclusive; paired with since, past window at most 90 days.
rankingPool
query{"type":"string","enum":["early"]}For keyword evidence with exact since/until: keep only same-window qualified news labels and display rules.
hours
query{"type":"integer","minimum":1,"maximum":8760}Relative publication window, anchored by the first cursor page.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum cumulative video views.
keyword
query{"type":"string","minLength":1,"maxLength":240}Exact maintained content term; not a taxonomy ID.
days
query{"type":"integer","minimum":1,"maximum":90}Optional relative date window when keyword filtering is used.
cursor
query{"type":"string","maxLength":1024}Opaque nextCursor from a previous publishedAt page; keep the same filters.
/api/v1/videos

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":1000,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged. Cursor requests require 0 or omission.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
channelId
query{"type":"integer","minimum":1,"maximum":9007199254740991}Local numeric channel ID.
channelIds
query{"type":"string","maxLength":256}Up to twenty comma-separated local channel IDs.
column
query{"type":"string","enum":["publishedAt","viewCount","likeCount","commentCount"]}Descending order, with source PK as deterministic tie-breaker; default publishedAt.
from
query{"type":"string","format":"date"}Inclusive Taipei publication date.
to
query{"type":"string","format":"date"}Inclusive Taipei publication date.
since
query{"type":"string","format":"date-time"}Exact UTC publication start, inclusive; paired with until. Cannot combine with from/to/days/hours.
until
query{"type":"string","format":"date-time"}Exact UTC publication end, exclusive; paired with since, past window at most 90 days.
rankingPool
query{"type":"string","enum":["early"]}For keyword evidence with exact since/until: keep only same-window qualified news labels and display rules.
hours
query{"type":"integer","minimum":1,"maximum":8760}Relative publication window, anchored by the first cursor page.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum cumulative video views.
keyword
query{"type":"string","minLength":1,"maxLength":240}Exact maintained content term; not a taxonomy ID.
days
query{"type":"integer","minimum":1,"maximum":90}Optional relative date window when keyword filtering is used.
cursor
query{"type":"string","maxLength":1024}Opaque nextCursor from a previous publishedAt page; keep the same filters.
/api/v1/keywords/{keyword}/videos

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
keyword (required)
path{"type":"string"}Exact maintained content term, percent-encoded as UTF-8.
limit
query{"type":"integer","minimum":1,"maximum":1000,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged. Cursor requests require 0 or omission.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
channelId
query{"type":"integer","minimum":1,"maximum":9007199254740991}Local numeric channel ID.
channelIds
query{"type":"string","maxLength":256}Up to twenty comma-separated local channel IDs.
column
query{"type":"string","enum":["publishedAt","viewCount","likeCount","commentCount"]}Descending order, with source PK as deterministic tie-breaker; default publishedAt.
from
query{"type":"string","format":"date"}Inclusive Taipei publication date.
to
query{"type":"string","format":"date"}Inclusive Taipei publication date.
since
query{"type":"string","format":"date-time"}Exact UTC publication start, inclusive; paired with until. Cannot combine with from/to/days/hours.
until
query{"type":"string","format":"date-time"}Exact UTC publication end, exclusive; paired with since, past window at most 90 days.
rankingPool
query{"type":"string","enum":["early"]}For keyword evidence with exact since/until: keep only same-window qualified news labels and display rules.
hours
query{"type":"integer","minimum":1,"maximum":8760}Relative publication window, anchored by the first cursor page.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum cumulative video views.
days
query{"type":"integer","minimum":1,"maximum":90}Optional relative date window when keyword filtering is used.
cursor
query{"type":"string","maxLength":1024}Opaque nextCursor from a previous publishedAt page; keep the same filters.
/api/v1/keywords/{keyword}/relations

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
keyword (required)
path{"type":"string","minLength":1,"maxLength":60,"description":"Unicode scalar characters; no surrounding whitespace or control characters."}Exact maintained content term, percent-encoded as UTF-8.
/api/v1/keywords/{keyword}/illustration

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
keyword (required)
path{"type":"string","minLength":1,"maxLength":60,"description":"Unicode scalar characters; no surrounding whitespace or control characters."}Exact maintained content term, percent-encoded as UTF-8.
/api/v1/videos/{id}

Core response fields are specified; nested presentation extensions remain open.

ParameterInSchema / boundsDescription
id (required)
path{"type":"string"}Byte-exact YouTube video ID.
/api/v1/videos/{id}/tags

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
id (required)
path{"type":"string"}Byte-exact YouTube video ID.
/api/v1/live/current

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
hours
query{"type":"integer","minimum":1,"maximum":168}Optional maximum time since livestream start; current observations must also have been updated within the last hour.
/api/v1/tags

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
sort
query{"type":"string","enum":["num","total","ave","median"]}Order by channel count (default), total, average or median weekly views.
min
query{"type":"integer","minimum":0,"maximum":2147483647,"default":10}Minimum weekly channel views included in category aggregation.
/api/v1/tags/{id}/channels

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
column
query{"type":"string","enum":["viewCount","subscriberCount","videoCount","view_week","view_month","views_pred_week","views_pred_month","sub_week","sub_month","video_week","video_month"]}Directory default view_week; taxonomy default view_month. Estimates remain explicitly distinct from observations.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum subscribers, or cumulative views when an or taxonomy selector is supplied.
/api/v1/tags/{id}/videos

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
limit
query{"type":"integer","minimum":1,"maximum":1000,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged. Cursor requests require 0 or omission.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
tagid
query{"type":"string","maxLength":256}Comma-separated channel taxonomy IDs, all required.
or
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs, any may match.
not
query{"type":"string","maxLength":256}Comma-separated taxonomy IDs to exclude.
channelId
query{"type":"integer","minimum":1,"maximum":9007199254740991}Local numeric channel ID.
channelIds
query{"type":"string","maxLength":256}Up to twenty comma-separated local channel IDs.
column
query{"type":"string","enum":["publishedAt","viewCount","likeCount","commentCount"]}Descending order, with source PK as deterministic tie-breaker; default publishedAt.
from
query{"type":"string","format":"date"}Inclusive Taipei publication date.
to
query{"type":"string","format":"date"}Inclusive Taipei publication date.
since
query{"type":"string","format":"date-time"}Exact UTC publication start, inclusive; paired with until. Cannot combine with from/to/days/hours.
until
query{"type":"string","format":"date-time"}Exact UTC publication end, exclusive; paired with since, past window at most 90 days.
rankingPool
query{"type":"string","enum":["early"]}For keyword evidence with exact since/until: keep only same-window qualified news labels and display rules.
hours
query{"type":"integer","minimum":1,"maximum":8760}Relative publication window, anchored by the first cursor page.
min
query{"type":"integer","minimum":0,"maximum":9007199254740991}Minimum cumulative video views.
keyword
query{"type":"string","minLength":1,"maxLength":240}Exact maintained content term; not a taxonomy ID.
days
query{"type":"integer","minimum":1,"maximum":90}Optional relative date window when keyword filtering is used.
cursor
query{"type":"string","maxLength":1024}Opaque nextCursor from a previous publishedAt page; keep the same filters.
/api/v1/ai/events/{id}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/ai/days/{id}/events

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/vocabulary

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
/api/v1/keywords

Typed report response; additive response fields are permitted.

ParameterInSchema / boundsDescription
limit
query{"type":"integer","minimum":1,"maximum":200,"default":50}Page size.
offset
query{"type":"integer","minimum":0,"maximum":100000,"default":0}Offset pagination; keep filters and ordering unchanged.
q
query{"type":"string","maxLength":100}Literal search text; runtime limit is 100 JavaScript UTF-16 code units.
/api/v1/videos/{id}/analytics

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"string"}Byte-exact YouTube video ID.
/api/v1/comments/authors/{key}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
key (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/groups/{name}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
name (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/groups/{name}/ranking

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
name (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/mayor/cities/{city}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
city (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/mayor/cities/{city}/people/{person}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
city (required)
path{"type":"string"}Route selector; preserve exact spelling.
person (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/mayor/cities/{city}/people/{person}/days/{date}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
city (required)
path{"type":"string"}Route selector; preserve exact spelling.
person (required)
path{"type":"string"}Route selector; preserve exact spelling.
date (required)
path{"type":"string","format":"date"}Taipei calendar date.
/api/v1/editorial/events/{id}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"string"}Canonical editorial event UUID.
/api/v1/channels/{id}/prompt

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/ai/days/{date}/prompt

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
date (required)
path{"type":"string","format":"date"}Taipei calendar date.
/api/v1/ai/days/{date}/{condition}/prompt

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
date (required)
path{"type":"string","format":"date"}Taipei calendar date.
condition (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/ai/events/{id}/people

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/ai/events/{id}/wall

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/ai/events/{id}/history

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/ai/days/{id}/events/history

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/live/days/{date}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
date (required)
path{"type":"string","format":"date"}Taipei calendar date.
/api/v1/live/groups/{group}/hours

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
group (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/groups/{name}/live

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
name (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/tags/{id}/live/videos

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/live/videos/{id}/trend

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"string"}Byte-exact YouTube video ID.
/api/v1/live/walls/{variant}

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
variant (required)
path{"type":"string"}Route selector; preserve exact spelling.
/api/v1/channels/{id}/cloud

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/tags/{id}/cloud

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/keywords/{keyword}/cloud

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
keyword (required)
path{"type":"string"}Exact maintained content term, percent-encoded as UTF-8.
/api/v1/tags/{id}/days

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/keywords/{keyword}/days

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
keyword (required)
path{"type":"string"}Exact maintained content term, percent-encoded as UTF-8.
/api/v1/channels/{id}/comments

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/tags/{id}/comments

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/channels/{id}/ai

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/channels/{id}/ai/days

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.
/api/v1/channels/{id}/people

Report is implemented. Only its data/meta envelope is specified in this catalog; route-specific data and query parameter documentation remains incomplete.

ParameterInSchema / boundsDescription
id (required)
path{"type":"integer","minimum":1,"maximum":9007199254740991}Local positive numeric record ID.

回應欄位

The machine-readable spec is authoritative for complete constraints. Additive fields are allowed. Tables expand nested objects to depth three; deeper objects and route-specific extensions are not flattened here.

ReportMeta
FieldTypeRequired in parentDescription
schemaVersion
numberyes
requestedAt
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
timezone
stringyes
source
stringyes
dataset
stringyes
coverage
objectyesRoute-specific provenance, completeness and source-quality evidence; inspect the route description. Nested evidence is permitted.
warnings
arrayyes
warnings[]
stringno
ApiError
FieldTypeRequired in parentDescription
error
stringyes
code
stringno
VideoCollection
FieldTypeRequired in parentDescription
rows
arrayyes
rows[]
objectno
rows[].id
stringyes
rows[].channelId
integeryes
rows[].youtubeChannelId
stringyes
rows[].channelTitle
stringyes
rows[].title
stringyes
rows[].description
stringyes
rows[].thumbnail
string | nullyes
rows[].publishedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
rows[].views
number | nullyes
rows[].likes
number | nullyes
rows[].comments
number | nullyes
rows[].updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
rows[].youtubeUrl
stringyes
rows[].keywordEvidence
arraynoAt most three fresh matching snippets for each of the first fifty keyword-result videos; offsets are UTF-16 positions in the original source. Absence means enrichment unavailable.
total
integer | nullyes
limit
integeryes
offset
integeryes
hasNext
booleanyes
totalStatus
stringyes
nextCursor
string | nullno
evidenceCoverage
objectnoRoute-specific provenance, completeness and source-quality evidence; inspect the route description. Nested evidence is permitted.
ChannelCollection
FieldTypeRequired in parentDescription
rows
arrayyes
rows[]
objectno
rows[].id
integeryes
rows[].youtubeId
stringyes
rows[].title
stringyes
rows[].thumbnail
string | nullyes
rows[].description
string | nullyes
rows[].publishedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
rows[].youtubeUrl
stringyes
rows[].views
number | nullyes
rows[].subscribers
number | nullyes
rows[].videoCount
number | nullyes
rows[].weeklyViews
number | nullyes
rows[].monthlyViews
number | nullyes
rows[].weeklySubscribers
number | nullyes
rows[].weeklyVideos
number | nullyes
rows[].monthlySubscribers
number | nullyes
rows[].monthlyVideos
number | nullyes
rows[].estimatedWeeklyViews
number | nullyes
rows[].estimatedMonthlyViews
number | nullyes
rows[].monthlyEstimateGap
number | nullyes
rows[].legacyGrowthPercent
number | nullyes
rows[].averageWeeklyViewsPerVideo
number | nullyes
rows[].updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
rows[].tags
arrayyes
total
integeryes
limit
integeryes
offset
integeryes
ranking
objectyes
ranking.column
stringyes
ranking.scope
stringyes
ranking.min
number | nullyes
ranking.minMetric
stringyes
Vocabulary
FieldTypeRequired in parentDescription
rows
arrayyes
rows[]
objectno
rows[].key
stringyes
rows[].term
stringyes
rows[].articleCount
integeryes
rows[].media
arrayyes
rows[].provenance
stringyes
rows[].displayExclusion
string | nullnoExplainable display exclusion code; null means eligible. Original vocabulary terms and evidence are retained.
rows[].rankingEligibility
objectno
total
integeryes
limit
integeryes
offset
integeryes
version
string | nullyes
source
stringyes
attribution
stringyes
window
unionyes
window
objectno
window.since
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
window.until
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
window
nullno
publishedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
coverage
stringyes
upstreamSnapshotConsistent
booleanyes
sourceQuality
objectno
sourceQuality.normalizedTags
integeryes
sourceQuality.rejectedTags
integeryes
sourceQuality.articlesWithRejectedTags
integeryes
VideoTagEvidence
FieldTypeRequired in parentDescription
videoId
stringyes
version
string | nullyes
status
stringyes
matchedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
source
stringyes
rows
arrayyes
rows[]
objectno
rows[].key
stringyes
rows[].term
stringyes
rows[].field
stringyes
rows[].start
integeryes
rows[].end
integeryes
rows[].text
stringyes
rows[].snippet
stringyes
rows[].snippetStart
integeryes
rows[].ruleVersion
stringyes
Home
FieldTypeRequired in parentDescription
summary
objectyes
summary.channels
integeryes
summary.videos
integeryes
summary.weeklyViews
numberyes
summary.liveChannels
integeryes
summary.liveViewers
numberyes
channels
arrayyes
channels[]
objectno
channels[].id
integeryes
channels[].youtubeId
stringyes
channels[].title
stringyes
channels[].thumbnail
string | nullyes
channels[].description
string | nullyes
channels[].publishedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
channels[].youtubeUrl
stringyes
channels[].views
number | nullyes
channels[].subscribers
number | nullyes
channels[].videoCount
number | nullyes
channels[].weeklyViews
number | nullyes
channels[].monthlyViews
number | nullyes
channels[].weeklySubscribers
number | nullyes
channels[].weeklyVideos
number | nullyes
channels[].monthlySubscribers
number | nullyes
channels[].monthlyVideos
number | nullyes
channels[].estimatedWeeklyViews
number | nullyes
channels[].estimatedMonthlyViews
number | nullyes
channels[].monthlyEstimateGap
number | nullyes
channels[].legacyGrowthPercent
number | nullyes
channels[].averageWeeklyViewsPerVideo
number | nullyes
channels[].updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
channels[].tags
arrayyes
tags
arrayyes
tags[]
objectno
tags[].id
integeryes
tags[].name
stringyes
tags[].kind
stringyes
tags[].channels
integeryes
tags[].weeklyViews
numberyes
tags[].average
numberyes
tags[].median
numberyes
live
arrayyes
live[]
objectno
live[].id
stringyes
live[].channelId
integeryes
live[].youtubeChannelId
stringyes
live[].channelTitle
stringyes
live[].title
stringyes
live[].description
stringyes
live[].thumbnail
string | nullyes
live[].publishedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
live[].views
number | nullyes
live[].likes
number | nullyes
live[].comments
number | nullyes
live[].updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
live[].youtubeUrl
stringyes
live[].currentViewers
numberyes
live[].todayPeak
numberyes
live[].allTimePeak
number | nullyes
live[].startedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
live[].trend
arrayyes
live[].tags
arrayyes
events
arrayyes
events[]
objectnoAI topic presentation; inspect evidence and unresolvedReferences.
aiDate
string | nullyes
exploration
objectyes
exploration.keywords
objectyes
exploration.keywords.sourceQuality
objectno
exploration.keywords.vocabularyCoverage
stringyes
exploration.keywords.vocabularyWindow
unionyes
exploration.keywords.source
stringyes
exploration.keywords.version
string | nullyes
exploration.keywords.status
stringyes
exploration.keywords.reason
string | nullno
exploration.keywords.from
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywords.to
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywords.updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywords.rows
arrayyes
exploration.keywords.sourceVideos
number | nullyes
exploration.keywords.freshVideos
number | nullyes
exploration.keywords.staleVideos
number | nullyes
exploration.keywords.unprocessedVideos
number | nullyes
exploration.keywords.metric
stringyes
exploration.keywords.rankingPool
objectnoExact publication-window tag news pool, early gate (two media each two articles). Available includes immutable provenance/checksum; unavailable includes reason/windows. Short window is rolling 24h, week is seven Taipei calendar dates. Rise/history reuse current qualified cohort.
exploration.keywords.rankingMethod
stringnoTitle weight 3, description-only weight 1; per-channel geometric decay 1, 0.5, 0.25…, with title matches first.
exploration.keywords.riseMethod
stringno
exploration.keywords.ruleVersion
stringno
exploration.keywords.comparison
unionno
exploration.keywords.exclusions
unionno
exploration.keywordToday
objectyes
exploration.keywordToday.sourceQuality
objectno
exploration.keywordToday.vocabularyCoverage
stringyes
exploration.keywordToday.vocabularyWindow
unionyes
exploration.keywordToday.source
stringyes
exploration.keywordToday.version
string | nullyes
exploration.keywordToday.status
stringyes
exploration.keywordToday.reason
string | nullno
exploration.keywordToday.from
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywordToday.to
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywordToday.updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.keywordToday.rows
arrayyes
exploration.keywordToday.sourceVideos
number | nullyes
exploration.keywordToday.freshVideos
number | nullyes
exploration.keywordToday.staleVideos
number | nullyes
exploration.keywordToday.unprocessedVideos
number | nullyes
exploration.keywordToday.metric
stringyes
exploration.keywordToday.rankingPool
objectnoExact publication-window tag news pool, early gate (two media each two articles). Available includes immutable provenance/checksum; unavailable includes reason/windows. Short window is rolling 24h, week is seven Taipei calendar dates. Rise/history reuse current qualified cohort.
exploration.keywordToday.rankingMethod
stringnoTitle weight 3, description-only weight 1; per-channel geometric decay 1, 0.5, 0.25…, with title matches first.
exploration.keywordToday.riseMethod
stringno
exploration.keywordToday.ruleVersion
stringno
exploration.keywordToday.comparison
unionno
exploration.keywordToday.exclusions
unionno
exploration.categories
objectyes
exploration.categories.status
stringyes
exploration.categories.reason
string | nullyes
exploration.categories.rows
arrayyes
exploration.categories.summary
objectyes
exploration.categories.updatedAt
string | nullyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
exploration.categories.minimumWeeklyViews
numberyes
ApiAvailability
FieldTypeRequired in parentDescription
status
stringyes
scope
stringyes
checkedAt
stringyesUTC ISO 8601 instant ending in Z, e.g. 2026-10-11T16:00:00.000Z.
services
arrayyes
services[]
objectno
services[].id
stringyes
services[].status
stringyes
endpoints
arrayyes
endpoints[]
objectno
endpoints[].method
stringyes
endpoints[].path
stringyes

舊版 PHP API 對照

These are related reports, not redirects or wire-compatible replacements. The 36 legacy routes keep their existing status codes, body shapes, MIME types and compatibility headers.

Legacy pathRelated v1 reportWireNotes
/api/api_live_day.php
/api/v1/live/videos/{id}/trendjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_live_date.php
/api/v1/live/days/{date}jsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_live_hour.php
/api/v1/live/hoursjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_live_tag_date.php
/api/v1/live/tagsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/live_date.php
/api/v1/live/days/{date}jsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/live_tvbs.php
NonejsonBroadcaster-specific legacy cache; no one-to-one v1 replacement.
/api/video_live.php
/api/v1/live/currenthtmlHTML fragment; replacement is structured JSON.
/api/csv_live_line.php
/api/v1/live/videos/{id}/trendcsvCSV download; replacement is structured JSON.
/api/tags_list.php
/api/v1/tagsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/tags_index.php
/api/v1/keywordsjsonMaintained vocabulary replaces the legacy keyword cache; counts and provenance differ.
/api/tags_all.php
/api/v1/keywordsjsonMaintained vocabulary replaces a legacy keyword cache; not channel taxonomy.
/api/video_tags.php
/api/v1/videos/{id}/tagsjsonVocabulary evidence is distinct from legacy tag extraction.
/api/video_tags_title.php
/api/v1/videos/{id}/tagsjsonVocabulary evidence is distinct from legacy title extraction.
/api/channels_list.php
/api/v1/channelsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/channel_videos.php
/api/v1/channels/{id}/videosjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/channels_videos.php
/api/v1/videosjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_tag.php
/api/v1/tagsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_tag_log.php
/api/v1/tags/trendsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/tags_day.php
/api/v1/tags/cloudjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/tags_video.php
/api/v1/tags/cloudjsonLegacy response contains weighted terms, not a video listing.
/api/tags_relation_date.php
/api/v1/keywords/{keyword}/daysjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/tag_month.php
/api/v1/keywords/{keyword}/daysjsonLegacy monthly buckets are not identical to daily report buckets.
/api/tag_period.php
/api/v1/keywords/{keyword}/daysjsonLegacy monthly period cache is not identical to daily report buckets.
/api/tag_tags_days.php
/api/v1/keywords/{keyword}/cloudjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/cloud.php
/api/v1/tags/cloudjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/cloud_tag_date.php
/api/v1/tags/cloudjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/cloud_tag_date_noapi.php
/api/v1/tags/cloudjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/group_view.php
/api/v1/groups/{name}/trendsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_channel_log.php
/api/v1/channels/{id}/trendsjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/channel_pred.php
/api/v1/channels/{id}/trendsjsonInspect estimated versus observed metrics.
/api/ai_day.php
/api/v1/ai/daysjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_topic.php
/api/v1/ai/daysjsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_event.php
/api/v1/ai/events/{id}jsonRelated v1 report; query names and response shape differ. This is not a redirect or wire-compatible replacement.
/api/api_comment.php
/api/v1/videos/{id}/analyticsjsonLegacy stored-comment payload has no identical v1 analytics wire payload.
/api/api_duration.php
/api/v1/videos/{id}textPlain-text seconds; see data.durationSeconds in v1.
/api/api_get_photo.php
NonetextLegacy photo lookup; no matching v1 endpoint.

產生與驗證

From platform/:

bash

node --import tsx tools/gen-api-docs.ts
node --import tsx tools/gen-api-docs.ts --check
node --import tsx tools/check-openapi.ts

The checker validates all documented examples with JSON Schema 2020-12, including every array element. It performs no network request unless an explicit --base-url is supplied. API tests additionally compare the catalog with actual Fastify onRoute registrations and exercise legacy wire fixtures.

來源與授權

The catalog-driven OpenAPI, documentation generation and API/status conventions follow tag-visuals at commit 748978854035050c4de56e365ab94c178f4ddbe0 (MIT, Sky Hong). This implementation documents YouTube Board contracts; it does not assert wire compatibility with tag.observe.tw. The maintained vocabulary is separately attributed in every relevant response.

text

MIT License

Copyright (c) 2026 Sky Hong

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.