Quickstart
Install
pnpm add @lookloot/capture-sdkThe SDK is ESM-only, targets Node.js 22 or newer, and should be installed in the Electron main-process package. The host app must already provide Electron. The SDK package bundles the Windows input helper, loopback audio helper, and FFmpeg fallback dependency.
Windows game capture also requires the official OBS Studio portable runtime to be bundled with your desktop app. The SDK does not depend on a user-installed OBS copy.
Prepare the runtime during your app build:
npx lookloot-capture-prepare-obs --out vendor/obsBackend Token Route
Keep your LookLoot partner key on your backend. Your desktop app should request a short-lived device token from your own API. LookLoot will provide each partner app with a registered app slug; pass that slug as appId from the desktop app to your backend and from your backend to LookLoot.
app.post("/api/lookloot/device-token", requireUser, async (req, res) => {
const upstream = await fetch("https://www.lookloot.gg/api/partner/auth/token", {
method: "POST",
headers: {
authorization: `Bearer ${process.env.LOOKLOOT_PARTNER_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
externalUserId: req.user.id,
appId: req.body?.appId,
appVersion: req.body?.appVersion,
deviceName: req.body?.deviceName,
}),
});
if (!upstream.ok) {
res.status(502).json({ error: "Could not create LookLoot device token" });
return;
}
const data = await upstream.json();
res.json({
token: data.token,
deviceId: data.deviceId,
partnerEndUserId: data.partnerEndUserId,
externalUserId: data.externalUserId,
app: data.app,
});
});Only token is required by the SDK. The other response fields are useful for your own logs and device-management UI.
appId is not freeform metadata. It must match an active LookLoot-registered app slug for your partner account. Use appVersion for the desktop build or release version you want stored with capture sessions.
App Initialization
Initialize the SDK from your desktop app's main process.
import { app } from "electron";
import { join } from "node:path";
import { LookLootCapture } from "@lookloot/capture-sdk";
const capture = new LookLootCapture({
appId: "your-registered-app-slug",
appVersion: app.getVersion(),
dataDir: join(app.getPath("userData"), "lookloot"),
deviceName: app.getName(),
obsPath: process.env.LOOKLOOT_OBS_PATH,
getDeviceToken: async ({ appId, appVersion, deviceName }) => {
const res = await fetch("https://your-api.example.com/api/lookloot/device-token", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ appId, appVersion, deviceName }),
});
if (!res.ok) throw new Error("LookLoot token request failed");
const data = await res.json();
return data.token;
},
});
capture.on("state-change", (state) => {
console.log("LookLoot capture state:", state);
});
await capture.init();init() is safe to call again when your backend needs to rotate a device token. Most integrations do not need to call start() or stop() manually after initialization.
After init() succeeds, the SDK starts watching for game processes. Recording begins automatically when a game is detected and stops when that game exits. The SDK also installs an Electron before-quit cleanup handler by default so closing the host app gives any active recording a chance to finalize and upload.
Windows OBS Runtime Packaging
Prepare the portable runtime during your app build:
npx lookloot-capture-prepare-obs --out vendor/obsFor packaged Windows builds, include the portable OBS root as an Electron resource named obs:
{
"build": {
"extraResources": [
{
"from": "vendor/obs",
"to": "obs",
"filter": ["**/*"]
}
],
"asarUnpack": [
"**/node_modules/ffmpeg-static/**",
"**/node_modules/@lookloot/capture-sdk/dist/input-helper/**/*",
"**/node_modules/@lookloot/capture-sdk/dist/audio-helper/**/*"
]
}
}vendor/obs must contain bin/64bit/obs64.exe, data, and obs-plugins. After packaging, verify this file exists in the unpacked app:
resources/obs/bin/64bit/obs64.exeFor local development, CI smoke tests, or nonstandard packagers, pass obsPath or set LOOKLOOT_OBS_PATH to the exact obs64.exe path.
Apps that already run their own privileged helper can pass elevatedCapturePipeName so protected/admin games route through that helper. Omit it unless you own that helper lifecycle; the SDK still refuses desktop capture fallbacks.
Before shipping, call capture.getRuntimeDiagnostics() in your installer smoke test. It reports whether OBS, FFmpeg, and the SDK helper assets resolve from the packaged app.
