Skip to content

SDK Overview

WarmHub has two typed SDKs — @warmhub/sdk-ts for TypeScript and warmhub for Python. Both provide methods for managing organizations and repositories, reading and writing repository data, and accessing the rest of the WarmHub surface — auth, access checks, commits, components, subscriptions, actions, tokens, credentials, diagnostics, live feeds, and homepage.

The two SDKs are versioned independently — the package version numbers are not expected to match.

WarmHub data is modeled as things (versioned named entities), assertions (claims about things), and shapes (schemas that define the structure of both). If those terms are new, skim Core Concepts before continuing.

In short:

Terminal window
npm install @warmhub/sdk-ts

Runtime requirement: Node.js 22.2 or later is required. Streaming submissions reject older runtimes with the message “Streaming submissions require Bun or Node.js 22.2 or newer.”

Install the WarmHub CLI, then create a personal access token and export it as WH_TOKEN:

Terminal window
wh auth login
wh token create --name my-app
export WH_TOKEN=eyJhbGciOi...

Then create a client:

import { WarmHubClient } from '@warmhub/sdk-ts'
const client = new WarmHubClient({
auth: { getToken: async () => process.env.WH_TOKEN },
})

The SDK does not read environment variables itself — read WH_TOKEN in your own code and pass it to getToken.

See Environment Variables for the variables the CLI honors.

OptionTypeDescription
auth.getToken() => Promise<string | undefined>Token acquisition hook — required for authenticated endpoints
accessTokenstring | () => string | undefined | Promise<string | undefined>Static token or sync/async provider (alternative to auth.getToken)
apiUrlstringOverride the API URL (defaults to https://api.warmhub.ai)
fetchtypeof fetchCustom fetch implementation
functionLogs'raw' | 'off'Server function log forwarding (defaults to 'off')
client.namestringIdentify requests from your SDK wrapper by name (useful when building a higher-level client on top of @warmhub/sdk-ts)
client.versionstringIdentify requests from your SDK wrapper by version (useful when building a higher-level client on top of @warmhub/sdk-ts)
clientFlagsreadonly string[]Declare client capability flags as an array of strings. Flag names are deployment-defined; the SDK validates their format client-side and sends them with requests so the server can tailor its behavior to the declared capabilities.

For a comparison of when to use the SDK vs the CLI or MCP, see the interface comparison on the Get Started page.

The SDK groups calls into typed client surfaces such as client.repo, client.thing, and client.commit. The generated WarmHubClient API reference (TypeScript) is the reference for method signatures and per-method descriptions.

The TypeScript SDK reference landing page covers all exports in @warmhub/sdk-ts, including standalone utilities and types such as normalizeWref, SDK_VERSION, RetryPolicyOptions, and PartialStreamSubmissionError that are not part of the WarmHubClient class itself.

TypeScript: Use Client Surfaces for a narrative map of the surfaces and the SDK concept pages for behavior shared across methods, such as read semantics, repo statistics, commit retries, and component identity.

The client.access surface exposes resolve(input), which returns an AccessResolveResult describing the resolved permissions for the given input. AccessResolveInput accepts optional repos and orgs arrays — repos entries are keyed by orgName and repoName, orgs entries by orgName. The result contains repos[] and orgs[] entries, each with a visible boolean and a scopes array listing the granted permission scopes.

The practical rule: new scope strings may appear in the scopes array as the backend evolves, so treat it as extensible rather than a closed set. Use the isKnownRepoAuthScope and isKnownOrgAuthScope narrowing helpers exported from @warmhub/sdk-ts when you need to branch on specific known members — this keeps your code safe when an unfamiliar scope string appears alongside the ones you know. Technically, scopes is typed as an open-vocabulary string[], which is why exhaustive literal handling against it will not behave as expected. Known repository scopes include repo:read, repo:checkpoint-read, repo:checkpoint-generate, repo:write, repo:configure, repo:admin, and repo:action-callback.

For example, to check whether the current token has write access to a specific repo:

import { isKnownRepoAuthScope } from '@warmhub/sdk-ts'
const result = await client.access.resolve({
repos: [{ orgName: 'acme', repoName: 'world' }],
})
const repoAccess = result.repos?.[0]
if (repoAccess?.visible) {
const canWrite = repoAccess.scopes.includes('repo:write')
// proceed based on canWrite
// To branch safely on known scopes without breaking on future additions:
const knownScopes = repoAccess.scopes.filter(isKnownRepoAuthScope)
}

Like all SDK methods, resolve throws WarmHubError on network, backend, or auth failures. These checks use the same credentials as the rest of the client; auth and network errors surface the same way as other SDK methods.

Most SDK methods throw WarmHubError on failure (raise WarmHubError in Python). Streamed writes may instead throw PartialStreamSubmissionError for ambiguous append outcomes or AllStreamOperationsFailedError when every submitted operation is rejected with per-op failure data — both exceptions exist in both SDKs. See Streaming Write Failures (TypeScript) for the full field contract. Both SDKs expose error-classification helpers:

import { isRetryable, isWarmHubError } from '@warmhub/sdk-ts'
try {
await client.repo.get('acme', 'world')
} catch (err) {
if (isWarmHubError(err) && err.kind === 'NOT_FOUND') {
// handle missing repo
}
if (isRetryable(err)) {
// safe to retry (NETWORK, CANCELLED, BACKEND, RATE_LIMITED)
}
throw err
}

See the ErrorKind reference (TypeScript) for the full per-kind cause, retryability, and corrective action. Common error kinds: NOT_FOUND, VALIDATION_ERROR, CONFLICT, UNAUTHENTICATED, FORBIDDEN, RATE_LIMITED, CANCELLED, NETWORK, BACKEND. Backend domain codes can also pass through unchanged in err.code and err.kind, including ARCHIVED, SHAPE_MISMATCH, and WREF_UNRESOLVABLE.

When a non-streaming write fails with a CONFLICT kind, the error may carry a structured details payload that describes the conflict:

import { isWarmHubError } from '@warmhub/sdk-ts'
try {
await client.commit.apply(/* ... */)
} catch (err) {
if (isWarmHubError(err) && err.kind === 'CONFLICT') {
const details = err.details
// details contains structured backend conflict metadata;
// use it to re-read HEAD and build a retry write
}
throw err
}

err.details carries structured conflict metadata when the backend provides it — undefined in TypeScript, None in Python. Not all CONFLICT errors include details; always guard before reading fields.

For streamed writes via client.commit.apply(), the all-failed conflict path surfaces differently: the SDK throws AllStreamOperationsFailedError, which exposes per-operation failure data for every rejected operation. The Transient Retry page documents the full field contract for this error, including receipts, result, operations, statusCounts, and cause.

If you need…Go to…
Install steps and your first query (TypeScript)SDK Quickstart
A narrative map of the main client surfaces (TypeScript)Client Surfaces
Full package-wide reference for all @warmhub/sdk-ts exports (TypeScript)SDK reference landing page
Auto-generated TypeDoc for the main client class (TypeScript)WarmHubClient API reference
Choosing the write API that fits the call siteWrite Methods
Retry and partial-submission behavior (TypeScript)Transient Retry
Filters, glob match, search modes, batch reads, anonymous pagination (TypeScript)Read Semantics
Exact counts vs dashboard metadata vs per-shape breakdowns (TypeScript)Repo Statistics
How componentRef attribution works for component-installed records (TypeScript)Component Identity
Terminal-first approachCLI Quickstart
Agent integration via Model Context ProtocolMCP Server