跳至主要內容
D1 Arena

D1 Arena

Loading...

D1 Arena

開發者API

社群

開發者API

建構機器人、疊加層、流工具以及與 D1Arena 數據的整合。

認證

所有 API 請求都需要在 X-API-Key / Authorization: Bearer 標頭中傳遞 API 金鑰。

# Example request curl -H "X-API-Key: d1_your_api_key_here" \ https://d1arena.com/api/v1/streams

若要建立 API 金鑰,請前往儀表板中的 開發者設定。您最多可以擁有 5 支鑰匙。

每個 API 金鑰的 API 請求受到速率限制。當超出限制時,請求將傳回 429 Too Many Requests 和 Retry-After 標頭。

基本網址

https://d1arena.com/api/v1

所有端點都傳回 JSON。分頁端點包括帶有 current_page、last_page 和 total 的 meta 物件。

流

GET /streams
列出目前直播。支援分頁和類別過濾。
參數種類描述
category_idinteger按遊戲/類別 ID 過濾
limitinteger每頁結果(預設:20)
pageinteger頁碼
回應
{ "data": [ { "id": 42, "name": "ProGamer99", "user_slug": "progamer99", "profile_img": "profile/abc123.jpg", "stream_title": "Ranked Grind - Road to Champion", "stream_category_id": 5, "is_vertical_stream": false, "platform_tier": "pro" } ], "meta": { "current_page": 1, "last_page": 1, "total": 3 } }
GET /streams/{slug}
透過使用者名稱或 slug 取得單一串流媒體的即時狀態和串流詳細資訊。
回應
{ "data": { "user_id": 42, "name": "ProGamer99", "slug": "progamer99", "is_live": true, "stream_title": "Ranked Grind", "category_id": 5, "is_vertical": false, "platform_tier": "pro", "profile_img": "profile/abc123.jpg" } }

類別

GET /categories
列出所有遊戲類別。支援搜尋和分頁。
參數種類描述
searchstring按名稱過濾類別
limitinteger每頁結果(預設:50)
回應
{ "data": [ { "id": 5, "name": "Call of Duty", "slug": "call-of-duty", "image": "categories/cod.png" } ], "meta": { "total": 24 } }

使用者

GET /users/{slug}
透過使用者名稱或別名取得玩家的公開資料和競技統計資料。
回應
{ "data": { "user": { "id": 42, "name": "ProGamer99", "user_slug": "progamer99", "profile_img": "profile/abc.jpg", "bio": "Competitive FPS player", "platform_tier": "pro", "is_live": "1", "stream_title": "Ranked", "gold": 3, "silver": 1, "bronze": 0 }, "stats": { "elo_rating": 1842, "total_tournaments": 27, "win_rate": 64.5, "total_earnings": 1250.00 } } }

剪輯

GET /clips
列出公共剪輯。支援按主播和類別過濾。
參數種類描述
streamer_idinteger按主播使用者 ID 過濾剪輯
category_idinteger按遊戲/類別 ID 過濾
limitinteger每頁結果(預設:20)
回應
{ "data": [ { "id": 99, "streamer_id": 42, "stream_category_id": 5, "title": "Insane 1v4 clutch", "slug": "insane-1v4-clutch-abc", "duration": 28, "view_count": 412, "is_auto_clip": false, "created_at": "2026-03-15T18:30:00.000000Z", "streamer": { "id": 42, "name": "ProGamer99", "user_slug": "progamer99" } } ], "meta": { "total": 156 } }
GET /clips/{slug}
透過 slug 取得單一剪輯的詳細資訊。
回應
{ "data": { "id": 99, "title": "Insane 1v4 clutch", "slug": "insane-1v4-clutch-abc", "description": "Final round comeback", "duration": 28, "view_count": 412, "streamer": { "id": 42, "name": "ProGamer99" }, "creator": { "id": 55, "name": "ClipMaster" }, "stream_category": { "id": 5, "name": "Call of Duty" } } }

錦標賽

GET /tournaments
列出錦標賽。支援按狀態和聯賽過濾。
參數種類描述
statusstring依狀態過濾(例如 open、in_progress、completed)
league_idinteger按聯賽 ID 過濾
limitinteger每頁結果(預設:20)
回應
{ "data": [ { "id": 15, "title": "Friday Night Frenzy", "tournament_type": "single_elimination", "status": "open", "registration_fee": "5.00", "no_player": 32, "team": 0, "category": { "id": 5, "name": "Call of Duty" }, "start_date": "2026-03-28T20:00:00.000000Z" } ], "meta": { "current_page": 1, "last_page": 2, "total": 24 } }
GET /tournaments/{id}
獲取錦標賽詳細資訊和參與者人數。
回應
{ "data": { "id": 15, "title": "Friday Night Frenzy", "tournament_type": "single_elimination", "status": "open", "registration_fee": "5.00", "no_player": 32, "team": 0 }, "meta": { "participant_count": 18 } }

ELO排名

GET /elo/leaderboard
取得 ELO 排名排行榜。可選擇按遊戲類別進行篩選。
參數種類描述
category_idinteger按遊戲/類別 ID 過濾
limitinteger結果數(預設:50)
回應
{ "data": [ { "rank": 1, "user_id": 42, "name": "ProGamer99", "user_slug": "progamer99", "elo_rating": 2150, "wins": 45, "losses": 12, "win_rate": 78.9, "profile_img": "profile/abc123.jpg" } ], "meta": { "total": 312 } }

聯賽

GET /leagues
列出具有可選狀態和類別過濾器的聯賽。
參數種類描述
statusstring按聯賽狀態過濾
category_idinteger按遊戲/類別 ID 過濾
limitinteger每頁結果(預設:20)
回應
{ "data": [ { "id": 3, "name": "Spring 2026 Pro League", "status": "active", "category": { "id": 5, "name": "Call of Duty" }, "total_participants": 48, "start_date": "2026-03-01", "end_date": "2026-05-31" } ], "meta": { "current_page": 1, "last_page": 1, "total": 6 } }
GET /leagues/{id}/standings
取得聯賽排名(按積分排名的球員排名)。
回應
{ "data": [ { "id": 1, "points": 2400, "wins": 12, "losses": 3, "user": { "id": 42, "name": "ProGamer99", "user_slug": "progamer99" } } ], "meta": { "total": 48 } }

錯誤回應

所有錯誤都會傳回一致的 JSON 信封。 error 物件總是包含機器可讀的 code 和人類可讀的 message。

錯誤回應格式
{ "success": false, "error": { "code": "not_found", "message": "The requested resource could not be found." } }
驗證錯誤格式 (422)
{ "success": false, "error": { "code": "validation_error", "message": "The given data was invalid.", "errors": { "category_id": ["The category id must be an integer."], "limit": ["The limit must not be greater than 100."] } } }

狀態代碼

200
好的 — 請求成功。回應包含請求的資料。
400
錯誤的請求 — 請求格式錯誤或缺少所需參數。檢查 error.message 了解詳細資訊。
401
未授權 — Missing or invalid API key. Ensure you're passing a valid key in the X-API-Key header.
403
拒絕存取 — 您的 API 金鑰已停用或缺少此資源的權限。檢查你的 開發者設定.
404
找不到內容 — 請求的資源不存在。驗證 slug、ID 或端點路徑。
422
驗證錯誤 — 請求參數驗證失敗。 error.errors 物件將欄位名稱對應到其特定問題。
429
價格有限 — 請求太多。 Retry-After 標頭指示重試前要等待多少秒。
500
伺服器錯誤 — 我們這邊發生了意外錯誤。如果這種情況持續下去, 聯繫支援人員.

錯誤代碼參考

驗證碼HTTP 狀態描述
invalid_api_key401API 金鑰遺失、格式錯誤或不存在
api_key_disabled403API金鑰已被撤銷或停用
not_found404找不到所要求的資源
validation_error422一個或多個請求參數無效
rate_limited429超出此 API 金鑰的請求速率限制
server_error500內部伺服器錯誤 - 請重試或聯絡支援人員

速率限制

每個 API 金鑰的 API 請求受到速率限制。當超出限制時,請求將傳回 429 Too Many Requests 和 Retry-After 標頭。

按等級限制

等級請求/分鐘 (預設)最大按鍵數
起動機 (免費)605
專業版605
終極版605
夥伴605

速率限制標頭

每個 API 金鑰的 API 請求受到速率限制。當超出限制時,請求將傳回 429 Too Many Requests 和 Retry-After 標頭。

標頭描述
Retry-After重試前等待的秒數(僅出現在 429 反應中)

最佳實踐

保持在限制範圍內的提示:
  • Cache responses locally — stream and tournament data doesn't change every second.
  • 訂閱 webhooks 來取得即時事件,而不是輪詢端點。
  • 盡可能批量請求 - 使用過濾器參數以更少的呼叫次數準確地獲取您需要的內容。

Webhook(EventSub)

訂閱即時推播通知而不是輪詢。當事件發生時,D1Arena 會向您的回呼 URL 發送一個 HTTP POST,其中包含使用 HMAC-SHA256 簽署的 JSON 負載。

設定

在 開發者設定 中建立 webhook 訂閱。每個訂閱都需要:

  • 回呼地址 — 伺服器上可公開存取的 HTTPS 端點。
  • 活動 — 要訂閱的一種或多種事件類型。

You'll receive a whsec_ signing secret upon creation. Store it securely — it's shown only once.

有效負載格式

每個 Webhook 傳遞都會傳送一個具有以下結構的 JSON 正文:

{ "id": "evt_a1b2c3d4e5f6", "event": "stream.online", "created_at": "2026-03-23T14:30:00Z", "data": { // Event-specific fields (see examples below) } }

標頭

每個交付都包含以下用於路由和驗證的標頭:

標頭描述
Content-Typeapplication/json
X-D1Arena-Event事件類型(例如 stream.online)
X-D1Arena-Signature原始請求正文的 HMAC-SHA256 十六進位摘要
X-D1Arena-Signature-Version簽章金鑰格式:目前訂閱為 v2,舊訂閱為 v1-hashed-secret
X-D1Arena-Delivery-Id唯一的交付 UUID — 用於重複資料刪除
X-D1Arena-Timestamp發送事件時的 Unix 時間戳

驗證簽名

在處理 Webhook 之前,請務必驗證 X-D1Arena-Signature 標頭。簽章計算為 HMAC-SHA256(raw_body, webhook_secret)。

對於 v2 交付,請使用建立訂閱時顯示的 whsec_ 金鑰。對於升級前 v1-hashed-secret 交付,首先根據原始密鑰計算 SHA256(whsec_secret) 並使用生成的小寫十六進位摘要作為 HMAC 密鑰。在可行時重新建立訂閱以移動到 v2。

PHP
// Get the raw body and signature header $payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_D1ARENA_SIGNATURE'] ?? ''; // Compute expected signature $expected = hash_hmac('sha256', $payload, $webhookSecret); // Constant-time comparison to prevent timing attacks if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Invalid signature'); } $event = json_decode($payload, true);
Node.js
const crypto = require('crypto'); app.post('/webhook', (req, res) => { const payload = req.rawBody; // Ensure raw body is available const signature = req.headers['x-d1arena-signature']; const expected = crypto .createHmac('sha256', WEBHOOK_SECRET) .update(payload) .digest('hex'); if (!crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) )) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(payload); // Process event... res.status(200).send('OK'); });
蟒蛇
import hmac, hashlib, json def handle_webhook(request): payload = request.body signature = request.headers.get('X-D1Arena-Signature', '') expected = hmac.new( WEBHOOK_SECRET.encode(), payload, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(expected, signature): return HttpResponse(status=401) event = json.loads(payload) # Process event... return HttpResponse(status=200)

可用的活動

活動描述
stream.online主播上線了
stream.offline一名主播下線了
channel.follow用戶關注頻道
channel.subscribe頻道上有新的支持者訂閱
channel.tip一則提示已發送至主播
tournament.started錦標賽比洞賽已經開始
tournament.ended一場錦標賽已經結束
tournament.match.completed記錄了比賽結果
clip.created從直播中創建了一個新剪輯
overdrive.startedD1 頻道開始瘋狂
overdrive.level_upD1 瘋狂晉級到下一個級別
overdrive.endedD1 瘋狂已完成或過期

事件負載範例

stream.online

{ "id": "evt_a1b2c3d4e5f6", "event": "stream.online", "created_at": "2026-03-23T14:30:00Z", "data": { "user_id": 42, "user_slug": "progamer99", "name": "ProGamer99", "stream_title": "Ranked Grind - Road to Champion", "category_id": 5, "category_name": "Call of Duty", "protocol": "RTMP", "started_at": "2026-03-23T14:30:00Z" } }

stream.offline

{ "id": "evt_f6e5d4c3b2a1", "event": "stream.offline", "created_at": "2026-03-23T17:45:00Z", "data": { "user_id": 42, "user_slug": "progamer99", "duration_seconds": 11700, "vod_id": 281 } }

channel.follow

{ "id": "evt_c1d2e3f4a5b6", "event": "channel.follow", "created_at": "2026-03-23T15:10:00Z", "data": { "follower_id": 88, "follower_slug": "newplayer", "followed_id": 42, "followed_slug": "progamer99" } }

channel.tip

{ "id": "evt_d1e2f3a4b5c6", "event": "channel.tip", "created_at": "2026-03-23T16:20:00Z", "data": { "streamer_id": 42, "streamer_slug": "progamer99", "tipper_id": 55, "tipper_slug": "clipmaster", "amount": "5.00", "currency": "USD", "message": "Great stream!" } }

tournament.match.completed

{ "id": "evt_e1f2a3b4c5d6", "event": "tournament.match.completed", "created_at": "2026-03-23T21:15:00Z", "data": { "tournament_id": 15, "tournament_title": "Friday Night Frenzy", "match_id": 204, "round": 2, "winner": { "id": 42, "slug": "progamer99", "name": "ProGamer99" }, "loser": { "id": 77, "slug": "rival_x", "name": "Rival_X" }, "score": "3-1" } }

clip.created

{ "id": "evt_b1c2d3e4f5a6", "event": "clip.created", "created_at": "2026-03-23T15:45:00Z", "data": { "clip_id": 99, "slug": "insane-1v4-clutch-abc", "title": "Insane 1v4 clutch", "duration": 28, "streamer_id": 42, "streamer_slug": "progamer99", "creator_id": 55, "creator_slug": "clipmaster", "category_id": 5 } }

交付和重試政策

嘗試延遲註解
第一名(初始)立即事件發生後幾秒內發送
第二次(重試)30秒如果第一次嘗試失敗或逾時
第三次(重試)2分鐘指數退避
第四名(決賽)10分鐘標記為失敗之前的最後一次嘗試
Important: Your endpoint must respond with a 2xx status within 10秒. Non-2xx responses or timeouts trigger a retry. After 連續10次失敗, the subscription is automatically disabled. You'll receive an email notification and can re-enable it in 開發者設定.

最佳實踐

  • 始終驗證簽名 在處理有效負載之前以防止欺騙事件。
  • 使用 Delivery-Id 進行重複資料刪除 — 重試發送相同的 ID,因此儲存已處理的 ID 以避免重複處理。
  • 快速響應,非同步處理 — 立即返回 200 OK 並在背景作業中處理業務邏輯。
  • 僅使用 HTTPS 端點 — Webhook URL 必須使用 TLS。 HTTP 回呼被拒絕。
  • 優雅地處理未知事件 — 可能會新增新的事件類型。傳回 200 表示無法辨識的事件而不是錯誤。

D1 瘋狂

D1 瘋狂是由主播直播時的快速提示和訂閱觸發的。它分為 5 個級別,目標不斷增加。

GET /api/overdrive/{streamerId}

為主播取得活躍的 D1 Frenzy。如果沒有則回傳 {"active": false}。

{ "active": true, "level": 2, "progress": 150, "target": 250, "progress_pct": 60.0, "total_contributions": 8, "total_contributors": 5, "expires_at": "2026-03-22T15:30:00+00:00" }

水平目標

等級積分
1100
2250
3500
41,000
52,000

D1 瘋狂 — 積分: 提示 $1 → 100; 訂閱 500 × 等級. 持續時間: 5 分分鐘; 冷卻時間: 30 分分鐘.

擴充SDK

建立自訂面板和覆蓋擴展,主播可以將其安裝在其頻道頁面上。擴充功能在沙盒 iframe 中運行,並透過 postMessage 與主機頁面通訊。

開始使用

  1. 在 開發者設定 中建立 API 金鑰。
  2. 將您的擴充功能建置為託管在您的網域上的獨立 HTML 頁面(需要 HTTPS)。
  3. 在 我的擴展 部分提交以供審核。
  4. 一旦獲得批准,主播就可以從擴展市場安裝它。

擴充類型

種類地點行為
panel串流媒體播放器下方直播時可見。全寬卡片,預設高度 300 像素。
overlay在影片播放器上直播時可見。位置/大小由流光透過疊加定位工具控制。

發布訊息API

您的擴充功能在載入時會自動接收上下文資料。實施這些事件:

為每個訊息使用確切的 D1Arena 父源。官方 SDK 自動從嵌入頁面衍生並驗證此來源。

由於擴展 iframe 有意使用不透明的沙箱來源,因此 D1Arena 主機會驗證確切註冊的 iframe 視窗。在接受上下文之前,擴充程式碼仍然必須驗證父視窗和確切的 D1Arena 來源。

1. 訊號準備狀況

var d1ParentOrigin = 'https://d1arena.com'; // Tell the host page your extension is ready for context window.parent.postMessage({ type: 'D1_EXT_READY' }, d1ParentOrigin);

2. 接收上下文

window.addEventListener('message', function(e) { if (e.source === window.parent && e.origin === d1ParentOrigin && e.data && e.data.type === 'D1_CONTEXT') { var ctx = e.data.payload; // ctx.channelId - Streamer's user ID // ctx.channelName - Streamer's display name // ctx.channelSlug - Streamer's URL slug // ctx.viewerId - Current viewer's ID (null if not logged in) // ctx.isLive - Whether the stream is currently live } });

3. 發送操作(可選)

// Redirect the host page (e.g. for a "Storm" button) window.parent.postMessage({ type: 'D1_EXT_ACTION', action: 'storm', target: 'username-slug' }, d1ParentOrigin);

權限範圍

聲明您的擴充功能需要哪些資料。審閱者會驗證您的程式碼是否符合您聲明的權限。

範圍授予存取權限
read:stream流狀態、標題、類別
read:viewers觀看人數和列表
read:chat聊天訊息(透過 Pusher 頻道)
read:clips透過 /api/clips/{slug} 頻道剪輯
read:tournaments透過 /api/active-match/{id} 取得有效匹配訊息
read:channel頻道簡介、追蹤者、時間表

安全要求

擴展在帶有 sandbox="allow-scripts" 的 沙盒 iframe 中運行。您的擴充功能 不能 存取 cookie、localStorage,或向 d1arena.com 發出經過驗證的請求。
  • 需要公共 HTTPS — 您的 iframe URL 必須使用 TLS 並僅解析為公共網路位址。
  • 人類可讀的源代碼 — 沒有混淆或縮小的 JavaScript。審閱者必須能夠閱讀您的程式碼。
  • 無需加載外部腳本 除非您在提交的資料中聲明。 CDN 函式庫(jQuery、Chart.js 等)都很好。
  • 無資料外洩 — 擴充功能不得將查看者資料傳送至第三方分析或追蹤服務。
  • 內容政策 — 沒有廣告、NSFW 內容、加密貨幣挖礦或惡意行為。

審核流程

狀態意義
pending已提交,等待管理員審核(通常 1-3 個工作天)。
approved已批准並在擴展市場中可見。
rejected有理由拒絕。修復問題並重新提交。
suspended因違反政策而暫時刪除。聯繫支援人員。

版本更新

若要更新已核准的擴展,請刪除目前版本並提交版本號遞增的新版本。新版本再次審核。

變更日誌

追蹤 API 更改和新功能。我們遵循語義版本控制,並至少提前 30 天宣布重大變更。

v1.02026 年 3 月
  • 具有 API 金鑰身份驗證的初始公共 API 版本。
  • 串流:列出直播串流,透過slug取得串流詳細資訊。
  • 類別:搜尋並列出所有遊戲類別。
  • 用戶:包含競技統計數據、ELO 評級和獎牌數的公開個人資料。
  • 剪輯:瀏覽並檢索帶有主播/創作者資訊的剪輯詳細資訊。
  • 錦標賽:列出,按狀態/聯賽過濾,取得參與者計數。
  • ELO 排行榜:全球和按類別排名的排行榜。
  • 聯賽:列出聯賽的排名和積分明細。
  • D1 瘋狂:任何主播的即時瘋狂狀態。
  • Webhooks (EventSub): 12 種事件類型,包括串流、頻道、錦標賽、剪輯和 Frenzy 事件。
  • 速率限制

需要幫助嗎?

關於 API 有疑問嗎? 聯絡我們。