TypeScript SDK
npm install @wordcab/sdk. Node 18+, Bun, and Deno. Tree-shakeable ESM with TypeScript types included.
Install
bash
npm install @wordcab/sdk
# or: pnpm add @wordcab/sdk / bun add @wordcab/sdk / yarn add @wordcab/sdkRequires Node 18+, Bun 1+, or Deno 1.40+. TypeScript types ship in the package.
Create a client
typescript
import { Wordcab } from "@wordcab/sdk";
const client = new Wordcab(); // reads WORDCAB_API_KEY
const c2 = new Wordcab({ apiKey: "wc_live_..." });
const c3 = new Wordcab({ baseURL: "https://wc.internal.example.com" });
const c4 = new Wordcab({ timeout: 30_000, maxRetries: 5 });Resources
typescript
await client.transcripts.create({ audioUrl: "...", model: "qwen3-asr" });
await client.transcripts.get(transcriptId);
await client.transcripts.list({ limit: 50 });
await client.transcripts.wait(jobId, { pollInterval: 2_000, timeout: 600_000 });
await client.audio.speech.create({ ... });
const stt = client.audio.transcriptions.stream({ model: "voxtral-realtime" });
await client.agents.create({ ... });
await client.agents.calls.create(agentId, { phoneNumber: "+1..." });
await client.calls.get(callId);
await client.calls.end(callId);
await client.testSuites.create({ ... });
await client.testSuites.runs.create(suiteId, { agentId });
await client.deployments.list();
await client.apiKeys.create({ name: "...", scopes: [...] });
await client.webhooks.create({ url: "...", events: [...] });Streaming
typescript
// Chat streaming — async iterator
const stream = await client.chat.completions.stream({
model: "qwen3.5-4b",
messages: [...],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0].delta.content ?? "");
}
// TTS streaming — ReadableStream of audio chunks
const audio = await client.audio.speech.stream({
input: "...", model: "qwen3-tts", voice: "ember", format: "pcm16",
});
const reader = audio.body!.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
sink.write(value);
}
// STT — WebSocket
const stt = await client.audio.transcriptions.stream({
model: "voxtral-realtime",
sampleRate: 16000,
});
stt.sendAudio(pcmBytes);
for await (const evt of stt) {
console.log(evt.type, evt.text);
}Pagination
typescript
// Walk all pages
for await (const agent of client.agents.iterate()) {
console.log(agent.id);
}
// Page-at-a-time
let page = await client.agents.list({ limit: 50 });
while (page.hasMore) page = await page.next();Errors
typescript
import {
APIError,
AuthenticationError,
NotFoundError,
PermissionError,
RateLimitError,
ValidationError,
} from "@wordcab/sdk";
try {
await client.agents.get("missing");
} catch (e) {
if (e instanceof NotFoundError) console.log(e.message, e.requestId);
else throw e;
}Browser use
Import the browser-safe subset if you need Wordcab in a frontend — it excludes the CLI-only endpoints and disables streaming against cross-origin hosts without a proxy.
typescript
import { Wordcab } from "@wordcab/sdk/web";
// Intended for authenticated same-origin or proxied use. Never ship a production API key to a public browser.Browser keys
Never ship a wc_live_* key to a public browser. Use short-lived tokens minted server-side with narrow scopes, or proxy requests through your own backend.