Docs
Connect once and receive every event from your Twitch, YouTube and X channels in one format.
Quick start
- Sign in with Twitch, YouTube or X, and connect your channels under Connections.
- Create a key under API keys.
- Install the SDK with
npm install @signal-kit/clientand connect. It works in browsers, Bun, Deno and Node 22+.
import { SignalKit } from "@signal-kit/client";
const kit = new SignalKit({ token: process.env.SIGNAL_KIT_KEY });
kit.on("tip", (e) => console.log(`${e.actor?.name} sent ${e.amount?.display}`));
kit.on("chat.message", (e) => console.log(e.actor?.name, e.message));
kit.connect();kit.on() takes a kind like "tip", a raw platform type like "channel.cheer", or "*" for everything, and returns an unsubscribe function. Keep keys on a server or in overlays you run yourself: anyone with a key receives your events.
Event format
Every event has the same shape, whatever the platform. A Twitch cheer and a YouTube Super Chat are both a tip with an amount, so one handler covers both.
{
"v": 2,
"id": "01M4V160WEEDSY6AG1YG3PZRPQ",
"kind": "tip",
"platform": "youtube",
"channel": { "connectionId": "…", "id": "UCSaecrr1v6dBCDJg5YD6FiA", "name": "vogel" },
"actor": { "id": "UC…", "name": "mira.codes", "badges": ["member"] },
"message": "Take my money.",
"amount": { "value": 20, "currency": "USD", "display": "$20.00" },
"data": { "source": "super_chat", "tier": 2 },
"occurredAt": "2026-10-13T20:41:07.000Z",
"receivedAt": "2026-10-13T20:41:07.412Z",
"raw": { "type": "youtube.live_chat.superChatEvent", "event": { … } }
}Types ship with the SDK: import type { SignalKitEvent, EventKind } from "@signal-kit/client".
Event kinds
Reconnects and replay
Events are kept for 24 hours. The SDK remembers the last event id and, after a dropped connection, asks for everything it missed before live events resume. Each event is delivered once. To resume across restarts, store kit.lastEventId and pass it back as since:
const kit = new SignalKit({ token, since: await load("lastEventId") });
kit.on("*", async (e) => { await handle(e); await save("lastEventId", e.id); });Plain WebSocket
Without the SDK, connect to wss://signal.ryan.ceo/ws and send your key as the first message, so it stays out of URLs and logs. The server answers signal_kit.ready, replays anything after since, then sends events as they happen.
const ws = new WebSocket("wss://signal.ryan.ceo/ws");
ws.onopen = () => {
// Within 5 seconds. "since" is optional: the last event id you processed.
ws.send(JSON.stringify({ type: "auth", token: "sk_live_…", since: lastId }));
};
ws.onmessage = ({ data }) => {
const message = JSON.parse(data);
if (message.type === "signal_kit.ready") return; // authenticated
if (message.type === "signal_kit.replayed") return; // { count, truncated, lastId }
lastId = message.id; // a SignalKitEvent
handle(message);
};CLI
Watch your events in a terminal while you build.
npm install -g @signal-kit/cli
SIGNALKIT_TOKEN=sk_live_… signal-kit
signal-kit --types tip,chat.message # filter by kind or raw platform type
signal-kit --json # one event per line