Skip to content

TypeScript SDK

@hlix/sdk is the first-party TypeScript client. Its request and response types come from the published OpenAPI contract, while the SDK adds credentials, explicit workspace selection, typed errors, bounded retry, bundle transfer, and Server-Sent Events.

  • Node.js 20 or later
  • An hlix API key
  • A workspace ID
  • TypeScript is recommended, but the package also exposes ESM JavaScript

Install

Terminal window
npm install @hlix/sdk

Pin the version in CI so a build never picks up a client you have not tested against:

Terminal window
npm install @hlix/sdk@0.2.0

Current versions reports the same state for all three hlix packages, and names the gate each one still has to pass.

Until the package ships, generate a typed client from the public OpenAPI contract — it is the same document this SDK is built from, and it downloads without authentication. The shapes below describe the client hlix will publish; the generated client exposes the same operations with generated names.

import { createHlix, apiKeyCredential } from '@hlix/sdk'
const hlix = createHlix({
baseUrl: 'https://server.hlix.ai',
credential: apiKeyCredential(process.env.HLIX_API_KEY!),
organizationId: process.env.HLIX_WORKSPACE_ID!,
})

An API key authenticates a user; it does not imply a workspace. Always pass organizationId in server-side automation so a prior browser session cannot select the tenant implicitly.

List projects and inspect a task:

import {
createHlix,
apiKeyCredential,
HlixNotFoundError,
} from '@hlix/sdk'
const hlix = createHlix({
baseUrl: process.env.HLIX_BASE_URL ?? 'https://server.hlix.ai',
credential: apiKeyCredential(process.env.HLIX_API_KEY!),
organizationId: process.env.HLIX_WORKSPACE_ID!,
})
const projects = await hlix.projects.list()
console.log(projects)
try {
const task = await hlix.tasks.get(process.env.HLIX_TASK_ID!)
console.log(task)
} catch (error) {
if (error instanceof HlixNotFoundError) {
console.error('Task is absent or not visible to this caller')
} else {
throw error
}
}

Expected result: the project list is scoped to the selected workspace. A hidden resource and an absent resource both produce HlixNotFoundError; the API does not reveal cross-tenant existence.

const controller = new AbortController()
for await (const event of hlix.tasks.stream(taskId, {
signal: controller.signal,
})) {
console.log(event.event, JSON.parse(event.data))
}

Streaming does not retry automatically. A reconnected stream could replay events the consumer has already acted on, so reconnection belongs in application logic with its own checkpoint policy.

Class Meaning
HlixValidationError 400 schema failure; exposes decoded issues
HlixBadRequestError other 400 response
HlixAuthenticationError 401
HlixPermissionError 403
HlixNotFoundError 404, including not visible
HlixConflictError 409 compare-and-swap or state conflict
HlixRateLimitError 429; exposes retryAfter
HlixNotImplementedError 501 permanent refusal
HlixServerError other 5xx
HlixTransportError no HTTP response

Every HTTP error also carries the status, parsed body, and request ID when the server provides one.

The default uses bounded exponential backoff with jitter and honors Retry-After. Only idempotent verbs are eligible. POST and PATCH are never retried automatically because the client may not know whether the server already performed the mutation.

Disable retry:

const hlix = createHlix({
baseUrl,
credential,
organizationId,
retry: { attempts: 1 },
})

The SDK exposes the same low-level import and revision primitives used by the CLI:

  • hlix.imports.create, get, uploadBundle, and finalize
  • hlix.revisions.head, createUpload, uploadBundle, finalize, downloadBundle, and protectedFiles

These are multi-step protocols. Preserve the server-issued upload identity, declare exact hashes and sizes, and finalize only with protected data that exactly matches the manifest. For ordinary local-to-cloud use, prefer the CLI—it owns scanning, snapshot construction, integrity verification, and local revision state.

hlix.raw exposes the generated openapi-fetch client for published operations not wrapped by the opinionated facade:

const { data, error } = await hlix.raw.GET('/v1/api/projects')

The raw client returns { data, error }; it does not apply the SDK’s throwing error model.

Terminal window
HLIX_API_KEY='' \
HLIX_WORKSPACE_ID='<workspace-id>' \
node dist/example.js

Use a secret manager in CI and avoid printing environment variables. Confirm the result against hlix projects list --json or the web app in the same workspace.

  • Cannot find module '@hlix/sdk' — the workspace package is not built. Run bun install --frozen-lockfile then bun run --cwd packages/sdk build. There is no registry install yet; see Current versions.
  • HlixAuthenticationError — the key is missing or rejected. It authenticates a user, so a valid key with no organizationId can still fail the next check.
  • HlixPermissionError — the user cannot act in the selected workspace. Confirm organizationId is the one you meant.
  • HlixNotFoundError on a resource you can see in the dashboard — you are pointed at a different workspace. Absent and not-visible are deliberately the same answer; do not infer cross-tenant existence from it.
  • HlixConflictError on a revision call — the expected revision or generation is stale. Read the head again before retrying.
  • HlixTransportError — no HTTP response at all. Check baseUrl, DNS, and TLS before suspecting credentials.
  • A POST that seems to have run twice — it did not retry. POST and PATCH are never retried automatically, precisely because the client cannot know whether the server already applied the mutation.
  • A stream that stops silently — streaming does not retry. Reconnection belongs in your code, with its own checkpoint policy, because a replayed event can be acted on twice.