メインコンテンツにスキップ
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 キーごとにレート制限されています。制限を超えると、リクエストは Retry-After ヘッダー付きの 429 Too Many Requests を返します。

ベースURL

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}
単一のストリーマーのライブ ステータスを取得し、ユーザー名またはスラッグごとにストリームの詳細を取得します。
応答
{ "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 によって 1 つのクリップの詳細を取得します。
応答
{ "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
OK — リクエストは成功しました。応答には要求されたデータが含まれます。
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
見つかりません — 要求されたリソースは存在しません。スラグ、ID、またはエンドポイントのパスを確認します。
422
検証エラー — リクエストパラメータの検証に失敗しました。 error.errors オブジェクトは、フィールド名をその特定の問題にマップします。
429
レート制限あり — リクエストが多すぎます。 Retry-After ヘッダーは、再試行するまでに待機する秒数を示します。
500
サーバーエラー — 弊社側で予期しないエラーが発生しました。この状態が続くと、 サポートに連絡する.

エラーコードのリファレンス

コードHTTPステータス説明
invalid_api_key401API キーが見つからないか、形式が間違っているか、存在しません。
api_key_disabled403API キーが取り消されているか無効になっています
not_found404要求されたリソースが見つかりませんでした
validation_error4221 つ以上のリクエスト パラメータが無効です
rate_limited429この API キーのリクエスト レート制限を超えました
server_error500内部サーバー エラー - 再試行するか、サポートにお問い合わせください

レート制限

API リクエストは API キーごとにレート制限されています。制限を超えると、リクエストは Retry-After ヘッダー付きの 429 Too Many Requests を返します。

ティアごとの制限

階層リクエスト/分 (デフォルト)最大キー数
スターター (無料)605
プロ605
究極の605
パートナー605

レート制限ヘッダー

API リクエストは API キーごとにレート制限されています。制限を超えると、リクエストは Retry-After ヘッダー付きの 429 Too Many Requests を返します。

ヘッダー説明
Retry-After再試行するまでに待機する秒数 (429 応答でのみ存在)

ベストプラクティス

制限内にとどまるためのヒント:
  • Cache responses locally — stream and tournament data doesn't change every second.
  • エンドポイントをポーリングする代わりに、リアルタイム イベントを取得するには webhooks をサブスクライブします。
  • 可能な場合はリクエストをバッチ処理します。フィルター パラメーターを使用すると、より少ない呼び出しで必要なものを正確に取得できます。

Webhook (EventSub)

ポーリングの代わりにリアルタイムのプッシュ通知を購読します。イベントが発生すると、D1Arena は HMAC-SHA256 で署名された JSON ペイロードを含む HTTP POST をコールバック URL に送信します。

セットアップ

Webhook サブスクリプションを 開発者設定 に作成します。各サブスクリプションには以下が必要です。

  • コールバック URL — サーバー上のパブリックにアクセス可能な HTTPS エンドポイント。
  • イベント — サブスクライブする 1 つ以上のイベント タイプ。

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 16 進ダイジェスト
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) を計算し、結果として得られる小文字の 16 進ダイジェストを 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 Frenzy がチャンネルで始まりました
overdrive.level_upD1 Frenzy が次のレベルに進みました
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 } }

配信と再試行ポリシー

試みる遅延注意事項
1位(初期)即時イベントから数秒以内に送信される
2回目(リトライ)30秒最初の試行が失敗するかタイムアウトになった場合
3回目(リトライ)2分指数バックオフ
4位(決勝)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 を保存します。
  • 迅速に応答し、非同期で処理します — return 200 OK をすぐに返し、バックグラウンド ジョブでビジネス ロジックを処理します。
  • HTTPS エンドポイントのみを使用する — Webhook URL は TLS を使用する必要があります。 HTTP コールバックは拒否されます。
  • 未知のイベントを適切に処理する — 新しいイベント タイプが追加される可能性があります。エラーではなく、認識されないイベントの場合は 200 を返します。

D1 フレンジー

D1 Frenzy は、ストリーマーのライブ中に急速なヒントやサブスクリプションによってトリガーされます。ターゲットが増加しながら 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ビデオプレーヤー上でライブ中に表示されます。位置/サイズは、オーバーレイ位置決めツールを介してストリーマーによって制御されます。

postMessage 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チャット メッセージ (プッシャー チャネル経由)
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 リリース。
  • ストリーム: ライブ ストリームをリストし、スラッグごとにストリーマーの詳細を取得します。
  • カテゴリ: すべてのゲーム カテゴリを検索してリストします。
  • ユーザー: 競技統計、ELO レーティング、メダル数を含む公開プロフィール。
  • クリップ: ストリーマー/クリエイター情報を含むクリップの詳細を参照して取得します。
  • トーナメント: リスト、ステータス/リーグでフィルタリングし、参加者数を取得します。
  • ELO リーダーボード: グローバルおよびカテゴリごとにランク付けされたリーダーボード。
  • リーグ: 順位とポイントの内訳を含むリーグをリストします。
  • D1 Frenzy: ストリーマーのリアルタイム Frenzy ステータス。
  • Webhook (EventSub): ストリーム、チャンネル、トーナメント、クリップ、Frenzy イベントを含む 12 のイベント タイプ。
  • レート制限

助けが必要ですか?

API について質問がありますか? お問い合わせ。