Skip to main content
The TypeScript/Node SDK is the v2 API with the retries, the pagination, the SSE reconnection and the id encoding already written. Node 18 or newer; zero dependencies — it uses the built-in fetch and Web Crypto.
new Splox(apiKey?, { baseURL, fetch, maxRetries, timeoutMs }). baseURL is the server API root and paths are appended already versioned (/v1/..., /v2/...), so nothing is rewritten. Resources are client.runs, client.interactions, client.harnesses, client.harnessVersions, client.llmEndpoints, client.toolServers and client.mcp.

The first call

Everything is camelCase in TypeScript and snake_case on the wire. The original wire payload is always on .raw, so a field the SDK does not map yet is still reachable.

Reading a run

messageText joins a message’s text parts — the two empty lines are the tool call and its result, which live in content as json parts. RunUsage maps inputTokens, outputTokens, toolCalls, durationMs, amount, currency, final and updatedAt; the token totals and the cache counters are on usage.raw. A Run is a handle: run.wait(), run.cancel(), run.reload(), run.events(), run.messages(), run.outputs(), run.tree(), run.usage(), run.pendingInteractions().

Creating a run

runs.create in 0.5.4 does not send machineId, which the API now requires, so it throws ValidationError 422 validation_failed with /machine_id: machine_id is required. Until the SDK ships the field, create runs over HTTP — see Runs — and use the SDK for everything after that.

Streaming

The stream reconnects with Last-Event-ID, deduplicates by event id, and finishes after the terminal run.status_changed. Pass stream: false to walk the durable journal instead — same events, page by page, ending when you are caught up.

Paging

A page is async-iterable and pages itself:
page.data is the first page if you would rather hold the cursor yourself.

Errors

Every API error carries statusCode, code, detail, traceId, problem and responseBody. GETs retry up to three times (network, 408, 429, 5xx); POSTs retry only when they carry an Idempotency-Key, always the same one.

Ids

harnessId parameters accept a raw UUID directly.

Harnesses

A harness is { id, name, versions } and nothing else — the prose lives in the files and the age is the commit. See Harnesses.