ドキュメントのメニュー
API
Webhook
EdgeWorks で起きたことを、あなたのサーバーへ POST でお知らせします。Discord への転送や、自前の記録づくりに使えます。
受け取る URL を決める
- ダッシュボードの「設定」→「通知」で、受け取る URL を 1 つ登録します。 個人と、組織ごとに 1 つずつ持てます(組織を選んでから登録すると、その組織の URL になります)。
- URL は
https://だけです。社内向けのアドレス(localhost や 192.168.x.x など)は登録できません。 - 同じ画面で署名鍵を発行すると、届く通知に署名が付きます。鍵は発行したときに一度だけ表示されます。 なくした場合は再発行できます(前の鍵はその時点で使えなくなります)。
- 同じ画面の「最近の通知」で、届いたか・失敗したかを確かめられます。
届く出来事
届くのは次の 4 種類だけです。種類は頭書きの X-EdgeWorks-Event と本文の event に入ります。
guard.detection
FiveM サーバー(SDK)や API から、EdgeGuard に検知が報告されたとき。
data.detection_id数値- 検知の ID
data.player_id文字列- プレイヤーの識別子
data.player_name文字列- プレイヤーの名前
data.type文字列- 検知の種類
data.severity文字列- 重大度
data.detected_at日時- 検知した日時
data.server_name文字列- 報告したサーバーの名前
data.score数値 / null- そのプレイヤーのいまのスコア。計算できなかったときは null
data.stage文字列 / null- スコアから決まった段。計算できなかったときは null
data.watch_level数値 / null- 監視の強さ(0〜3)
data.shadow真偽 / null- true のときは、点は出ているが処分には使っていない(試しに数えているだけ)
data.auto_actions文字列の配列- この報告をきっかけに自動で出した指示(warn・screenshot・stream・kick・ban)。何も出していなければ空
data.ban_expires_at日時 / null- この報告で自動の一時 BAN を張ったときの期限。張っていなければ null
- 自動の処分(退出・一時 BAN)と証拠の自動撮影は、ダッシュボードの EdgeGuard の「規則」で選んだときだけ行います(既定は切)。
vault.upload
EdgeVault へのアップロードが終わったとき。直接のアップロードと、一時 URL(presigned URL)で置いたときの両方で届きます。
data.file_id数値- ファイルの ID
data.original_name文字列- 元のファイル名
data.mime_type文字列- ファイルの種類
data.file_size数値- 大きさ(バイト)
data.folder文字列- 置いたフォルダ
data.created_at日時- 置いた日時
- ファイルの公開 URL は送りません。中身が要るときは、file_id を使って API から取り出してください。
stream.started
配信を始めたとき。
data.stream_id数値- 配信の ID
data.status文字列- 配信の状態
data.max_duration数値- 1 本の長さの上限(秒)
data.player_id文字列- 配信しているプレイヤーの識別子
data.player_name文字列- 配信しているプレイヤーの名前
- 映像を流し込むための URL は送りません(持っていれば誰でも流し込めるため)。
stream.stopped
配信が止まったとき。停止の API で止めたときのほか、1 本の長さや今月の配信時間の上限・生存の通知の途切れ・運営による停止で自動で止まったときも届きます。1 回の停止につき 1 回だけです(もう止まっていた配信をもう一度止めても、二度は届きません)。
data.stream_id数値- 配信の ID
data.stop_reason文字列- 止まった理由。manual(停止の API)・max_duration(1 本の長さの上限)・monthly_quota(今月の配信時間の上限)・heartbeat_timeout(生存の通知が途切れた)・no_heartbeat(生存の通知が一度も届かなかった)・admin_force_stop(運営による停止)
data.auto_stopped真偽- 自動で止まったときは true。停止の API で止めたときだけ false
data.duration数値- 配信していた長さ(秒)。始めた時刻が無ければ 0
本文と頭書き
本文は JSON です。どの出来事も同じ包みで、出来事ごとの中身は data に入ります。org_id は、個人のものなら 0、組織のものならその組織の ID です。
本文の例(vault.upload)
{
"event": "vault.upload",
"delivery_id": 1234,
"occurred_at": "2026-10-25T12:00:00.000Z",
"org_id": 0,
"data": {
"file_id": 42,
"original_name": "screenshot.png",
"mime_type": "image/png",
"file_size": 183204,
"folder": "/screenshots",
"created_at": "2026-10-25T12:00:00.000Z"
}
}- Content-Type
- application/json
- X-EdgeWorks-Event
- 出来事の名前(guard.detection など)。振り分けに使えます
- X-EdgeWorks-Delivery
- 送信の ID。再送でも同じ値なので、二重に届いたかをこれで見分けられます
- X-EdgeWorks-Timestamp
- 送った時刻(Unix 秒)。署名鍵を発行しているときだけ付きます
- X-EdgeWorks-Signature
- v1=<署名>。署名鍵を発行しているときだけ付きます
- User-Agent
- EdgeWorks-Webhook/1.0
署名を確かめる
署名鍵を発行していると、X-EdgeWorks-Signature: v1=… が付きます。 中身は、HMAC-SHA256(鍵, X-EdgeWorks-Timestamp の値 +「.」+ 受け取った本文そのまま)の 16 進です。次の 2 つを確かめてから受け取ってください。
- 計算した署名と、届いた署名が一致すること(比べるときは時間が一定の比較を使う)
- 時刻が、いまから前後 5 分以内であること(古い通知の使い回しを防ぐ)
本文を JSON として読み直してから署名を計算すると、空白や並びが変わって一致しません。受け取ったバイト列のまま計算してください。 署名鍵を発行していない宛先には、署名なしで届きます。
検証の例(Node.js)
import crypto from "node:crypto";
// rawBody は、受け取った本文をそのまま(JSON として読み直す前の文字列)
function verifyEdgeWorks(secret, timestamp, rawBody, signature) {
// 5 分(300 秒)より古い・新しいものは受け取らない
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected =
"v1=" + crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signature);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}届けかたと再送
- 5 秒以内に 2xx を返してください。重い処理は、受け取ったあとに別に行ってください。 転送(3xx)はたどらず、失敗として扱います。
- つながらない・時間切れ・408・429・5xx のときは、1 秒・5 秒・25 秒あとに送り直します (最初の 1 回を含めて最大 4 回)。それ以外の 4xx は送り直しません。
- 送り直しでは、本文・時刻・署名・
X-EdgeWorks-Deliveryが最初と同じです。同じ ID が 2 回届いたら、2 回目は捨ててください。 - 届く順番は、出来事が起きた順と同じとは限りません(送り直しが挟まるため)。順番が要るときは、本文の occurred_at(通知を作った時刻)を見てください。