Package Exports
- @pyai/sdk
Readme
@pyai/sdk
Official TypeScript/JavaScript SDK for PyAI — the voice-AI platform for speech-to-text, text-to-speech, realtime voice agents, and automated call compliance. Zero dependencies; runs in the browser and Node 18+.
PyAI products
- Hear — Speech-to-text tuned for telephony (8 kHz), with streaming partials and a half-price async batch tier; OpenAI-compatible.
POST /v1/audio/transcriptions - Speak — Low-latency streaming text-to-speech (~32–98 ms to first byte) with 36 stock voices and free instant voice cloning.
POST /v1/audio/speech - Omni (flagship) — End-to-end realtime voice agents over a single WebSocket: listens, thinks, and speaks — grounded in your knowledge bases and tools, with natural turn-taking and barge-in.
wss://api.pyai.com/v1/omni - Trace (flagship) — Automated compliance & QA on every call: scores each call against rule packs (TCPA, HIPAA, PII, brand-voice), with findings that cite the rule, auto-redaction, and a tamper-evident audit hash.
GET /v1/trace/interactions - Cue — Turn detection + retrieved knowledge-base context for bring-your-own-LLM/voice pipelines, billed as one per-minute meter.
wss://api.pyai.com/v1/audio/transcriptions/stream - Telephony — Managed US phone numbers routed straight to your Omni agents, no separate carrier contract.
POST /v1/telephony/numbers
The contract is https://api.pyai.com/openapi.json. This SDK wraps it
ergonomically with typed errors, automatic retries, and a realtime helper.
Install
npm install @pyai/sdkQuickstart
import PyAI from "@pyai/sdk";
const pyai = new PyAI({ apiKey: process.env.PYAI_API_KEY! });
// Text-to-speech
const audio = await pyai.audio.speech({ input: "Hello from PyAI.", voice: "stock_sarah_style2" });
await Bun.write?.("hello.wav", audio); // or fs.writeFile in Node
// Text-to-speech, streamed — start playing/forwarding at the first chunk
// (tens of ms) instead of waiting for the whole clip. Use mp3 for smooth
// progressive playback.
const stream = await pyai.audio.speechStream({ input: "Hello from PyAI.", voice: "stock_sarah_style2", response_format: "mp3" });
for await (const chunk of stream) writeToSpeakerOrResponse(chunk);
// Voices
const { data: voices } = await pyai.voices.list({ gender: "female" });
// Async transcription (safe retry with an idempotency key)
const job = await pyai.transcriptionJobs.create(
{ audio_url: "https://example.com/call.wav", diarize: true },
{ idempotencyKey: crypto.randomUUID() },
);
const done = await pyai.transcriptionJobs.get(job.job_id);Realtime (Omni)
Keys travel as a WebSocket subprotocol so this works in the browser:
const ws = pyai.connectRealtime({ product: "omni", agentId: "agent_123" });
ws.addEventListener("message", (e) => console.log(e.data));
// Or build the pieces yourself for a custom WS library:
const url = pyai.realtimeURL({ product: "omni", agentId: "agent_123" });
const proto = pyai.realtimeSubprotocol();Omni uses the native
wss://api.pyai.com/v1/omnisurface.connectRealtimetargets it by default (product: "omni");product: "flow"uses/v1/realtime. The older/v2/omni/chatURL is deprecated but still works.
Errors
Failures throw PyAIError with a stable code (branch on it, not the message):
import { PyAIError } from "@pyai/sdk";
try {
await pyai.audio.speech({ input: "hi" });
} catch (err) {
if (err instanceof PyAIError && err.code === "credit_exhausted") {
// out of prepaid credit — add credit or use a sandbox key
}
}Common codes: unauthorized, forbidden, credit_exhausted,
rate_limit_exceeded, concurrency_limit_exceeded, idempotency_conflict.
429/5xx are retried automatically (honoring Retry-After); tune with
new PyAI({ apiKey, maxRetries }).
CLI (pyai)
Installing the package also provides a pyai command — a smoke tester that
proves your key, the endpoint, and audio synthesis in one shot:
export PYAI_API_KEY=pyai_test_...
npx pyai smoke
# PASS models.list — 12 models
# PASS voices.list — 38 voices
# PASS audio.speech — 45210 bytes of audio
# All checks passed. Your key, the endpoint, and audio synthesis work.Other commands:
pyai models
pyai voices --gender female --region en_us
pyai speak --text "Hello" --voice stock_sarah_style2 --out hello.wav
pyai transcribe --url https://example.com/call.wav --diarize --pollAuth comes from PYAI_API_KEY / PYAI_BASE_URL (or --api-key / --base-url).
Develop
npm install
npm test # node --test, fetch injected (no network)
npm run build # emits dist/ (incl. the pyai CLI bin)