TypeScript SDK
Zero-dependency TypeScript client with typed methods, auto-retry on rate limits, and error handling.
Installation
npm install @liquichart/sdk
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 (self-updating)
const { data: block } = await lc.livingContent.getUnified('my-block');
// block.mode is 'proactive' | 'reactive'
// block.content auto-updates when underlying data changes
// 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');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 Visionary 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
}