TypeScript SDK

Zero-dependency TypeScript client with typed methods, auto-retry on rate limits, and error handling.

Installation

The TypeScript SDK is not on npm yet. It is coming soon. Until then, call the REST API directly with fetch and an x-api-key header, as in the quick start. The methods below show the SDK surface it will ship with.

Usage

import { LiquiChart } from '@liquichart/sdk';

const lc = new LiquiChart({
  apiKey: process.env.LIQUICHART_API_KEY!,
  // baseUrl: 'https://www.liquichart.com' (default)
});

// Charts
const { data: chart } = await lc.charts.get('abc12345');
const { data: chartList } = await lc.charts.list({ limit: 20, status: 'published' });
await lc.charts.create({ title: 'Revenue', chartType: 'line', manualData: [...] });
await lc.charts.publish('abc12345');

// Batch fetch multiple charts in one request
const { data: batch } = await lc.charts.batch(['abc12345', 'def67890']);

// Polls
const { data: poll } = await lc.polls.get('xyz98765');
await lc.polls.create({ title: 'Survey', questions: [{ text: '...', options: ['A', 'B'] }] });
await lc.polls.close('xyz98765');

// Living Content
const { data: block } = await lc.livingContent.getUnified('my-block');
// block.mode is 'proactive' | 'reactive'
// proactive: swaps to your authored variant when a linked poll or chart crosses a threshold
// reactive: proposes a fix when a source changes; it goes live after you approve it

// Workspace
const { data: ws } = await lc.workspace.get();
const { data: usage } = await lc.workspace.getUsage({ days: 30 });

// Experiments (read publicly-running experiments, follow for updates)
const { data: experiments } = await lc.experiments.list({ status: 'running' });
const { data: exp } = await lc.experiments.get('exp12345');

// Claims (tracked statistics and their freshness)
const { data: claims } = await lc.claims.list({ status: 'stale', limit: 50 });
const { data: claimStats } = await lc.claims.stats();

// Monitored pages (external URLs watched for change)
const { data: pages } = await lc.monitoredPages.list({ status: 'active' });
await lc.monitoredPages.create({ url: 'https://example.org/report' });
const { data: fixes } = await lc.monitoredPages.corrections('remote-work-report-mp123456');

// Widgets — living constants already resolved, ready to render
const { data: widget } = await lc.widgets.get('wid45678');
// widget.constantScope feeds the formula, widget.claimConstants carries
// each constant's value, source claim, and last verification date

Webhook Verification

Verify incoming webhook payloads using HMAC-SHA256. Configure endpoints in Settings → Webhooks.

import { verifyWebhookSignature } from '@liquichart/sdk/webhooks';

// In your webhook handler (Next.js App Router example):
export async function POST(req: Request) {
  const rawBody = await req.text();
  const signature = req.headers.get('x-liquichart-signature') ?? '';

  const isValid = verifyWebhookSignature(
    rawBody,
    signature,
    process.env.LIQUICHART_WEBHOOK_SECRET!,
  );

  if (!isValid) return new Response('Unauthorized', { status: 401 });

  const event = JSON.parse(rawBody);
  // event.event_type, event.data, event.timestamp
}

Error Handling

import {
  LiquiChartNotFoundError,
  LiquiChartRateLimitError,
  LiquiChartAuthError,
  LiquiChartPlanRequiredError,
  LiquiChartScopeError,
} from '@liquichart/sdk';

try {
  const { data } = await lc.charts.get('nonexistent');
} catch (err) {
  if (err instanceof LiquiChartNotFoundError) {
    // Chart doesn't exist
  }
  if (err instanceof LiquiChartRateLimitError) {
    // Auto-retried twice already; err.retryAfter has seconds to wait
  }
  if (err instanceof LiquiChartAuthError) {
    // Invalid or expired API key
  }
  if (err instanceof LiquiChartPlanRequiredError) {
    // This endpoint requires a Pro or Team plan
  }
  if (err instanceof LiquiChartScopeError) {
    // API key is missing a required scope (e.g. charts:write)
  }
}

The SDK automatically retries on 429 (rate limit) up to 2 times with Retry-After backoff.

TypeScript Support

Full type definitions included. Every method returns typed responses:

import type { Chart, Poll, ChartDataPoint, LivingUnified, Experiment } from '@liquichart/sdk';

const { data: chart } = await lc.charts.get('abc12345');
// chart is typed as Chart — autocomplete works for:
// chart.title, chart.data, chart.config, chart.insight, chart._links, etc.

const { data: block } = await lc.livingContent.getUnified('my-slug');
// Narrow by mode for full type safety:
if (block.mode === 'proactive') {
  block.activeVariantName; // string | null
  block.evaluationCount;   // number
}