@lumorig/sdk: a typed, zero-dependency client for Node 18+, Bun, Deno and browsers.
@lumorig/sdk is a thin, typed client for the REST API. It has no dependencies and uses the platform fetch, so it runs in Node 18+, Bun, Deno and browsers. The MCP server and the lumorig CLI are built on it.
jobs.wait(id, options) long-polls GET /jobs/{id}?wait=60 until the job reaches succeeded, failed or canceled, and returns the job. It does not throw on a failed job: check job.status. The *AndWait and createAndDownload helpers do throw, with code job_failed.
WaitOptions
Name
Type
Description
timeoutMs
number
Give up after this long (default 15 minutes). Throws LumorigError with status 408 and code timeout; the job keeps running.
signal
AbortSignal
Stop waiting early. Aborting the wait does not cancel the job; call jobs.cancel for that.
Every job has an event log: queued, started, progress (human-readable notes), tool_call, tool_input_delta, tool_result, draft (an intermediate spec while it draws), draft_clip (an intermediate motion), usage (running cost) and finished (with the final status and error). Each event has seq, at and type. jobs.events replays the history after after, then follows live until finished.
events.ts
forawait (const e of lumorig.jobs.events(job.id)) {
if (e.type === "progress") process.stdout.write(String(e.text));
if (e.type === "usage") console.log("spent so far $", e.cost_usd);
}
// or, while waiting:await lumorig.jobs.wait(job.id, { onEvent: (e) => console.log(e.type) });
Every non-2xx response throws a LumorigError carrying the API's error body. status is the HTTP status, code the stable machine-readable code, details extra data (validation messages, or the credit shortfall).
Codes the SDK adds itself: http_error (a non-JSON error body, or a failed event stream), job_failed (a helper's job didn't succeed) and timeout (status 408 from jobs.wait). The full list is in Errors.
verifyWebhook(body, header, secret, toleranceSec = 300) checks a delivery's Lumorig-Signature header: an HMAC-SHA256 of `${t}.${body}` with your endpoint secret, and a timestamp within the tolerance. Pass the raw request body, not re-serialised JSON. It uses Web Crypto, so it works in Node, Deno, Bun and edge runtimes.