SDKs
Call AudioLab from TypeScript or Python with typed requests, streaming, typed errors, and safe retries.
Install
The TypeScript SDK runs on Node 18+, Deno, Bun, and edge runtimes with no dependencies. The Python SDK supports Python 3.9+ with sync and async clients. Both cover text with routing, speech, transcription, speech-to-speech, images, video, OCR, reranking, moderation, embeddings, batches, and the model catalog. Their request and response types are generated from the OpenAPI spec behind the API Reference.
npm install @audiolab/sdk@audiolab/sdk and audiolab-sdk are not on npm or PyPI yet. Until they are, use the OpenAI or Anthropic SDK.
Make a Request
Both clients read AUDIOLAB_API_KEY, and AUDIOLAB_BASE_URL when it is set. The base URL includes /v1 and defaults to https://api.tryaudiolab.ai/v1.
export AUDIOLAB_API_KEY="YOUR_WORKSPACE_KEY"import AudioLab from "@audiolab/sdk";
const client = new AudioLab();
const completion = await client.chat.completions.create({
model: "openai/gpt-5.5",
messages: [{ role: "user", content: "Explain API routing in one sentence." }],
max_tokens: 256,
});
console.log(completion.choices[0].message.content);
console.log(completion.usage?.cost, completion.routing?.model);usage.cost is the settled charge in USD, and routing explains which model and provider answered. Routing fields such as models, provider, plugins, and service_tier are typed parameters; see Model Routing. In Python, results are plain dicts, and AsyncAudioLab has the same methods.
Stream a Response
const stream = await client.chat.completions.create({
model: "openai/gpt-5.5",
messages: [{ role: "user", content: "Write a haiku about routers." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta.content ?? "");
}
console.log(stream.usage?.cost, stream.routing?.attempts);The final event carries the usage with its cost and the routing explanation. The stream collects them in usage and routing, and the answer in text. Responses and Messages stream the same way with their own event types. An error after output began is raised from the loop with duringStream (during_stream in Python) set. See Streaming.
Handle Errors
An error response raises a subclass of APIError chosen by its status, carrying the API's error code, the requestId (request_id) when the API sent one, and, on language endpoints, type and metadata.
import { APIError, PaymentRequiredError, RateLimitError } from "@audiolab/sdk";
try {
await client.chat.completions.create(params);
} catch (error) {
if (error instanceof PaymentRequiredError) console.log("Add credits:", error.code);
else if (error instanceof RateLimitError) console.log("Retry after", error.retryAfter);
else if (error instanceof APIError) console.log(error.status, error.code, error.requestId);
else throw error;
}| Status | Class |
|---|---|
400 | BadRequestError |
401 | AuthenticationError |
402 | PaymentRequiredError |
403 | PermissionDeniedError |
404 | NotFoundError |
408 | RequestTimeoutError |
409 | ConflictError |
422 | UnprocessableEntityError |
429 | RateLimitError |
5xx | InternalServerError, with ProviderError for 502 and ServiceUnavailableError for 503 |
| None | APIConnectionError and its timeout subclass |
A language request that fails after the 30-second keep-alive is raised the same way, with the status its code stands for. See Errors and Debugging for each code.
Retries and Timeouts
Both clients retry a failed request twice by default, after 0.5 and 1 second with jitter, or after the Retry-After the API sends, up to 60 seconds:
- A
429is retried on every endpoint, because nothing ran. - A
408, a5xx, a timeout, or a dropped connection is retried on reads, and on endpoints that take anIdempotency-Key: Chat Completions, Responses, Messages, embeddings, images, video, OCR, reranking, native inference, and speech-to-speech. - A
409withidempotency_in_flightis retried, and the retry returns the first attempt's result.
For those endpoints the SDK sends a generated Idempotency-Key and reuses it on every retry, so a retry never runs or bills a request twice. Speech, transcription, moderation, file uploads, and batch creation take no key, so the SDK does not retry their failures after the request is sent.
The default timeout is 11 minutes, longer than the API's own 10-minute limit. For streams and audio it bounds the silence between chunks. Every method takes per-request options:
await client.chat.completions.create(params, {
timeout: 30_000,
maxRetries: 0,
idempotencyKey: "order-1234",
signal: controller.signal,
});Audio and Other Endpoints
import { openAsBlob } from "node:fs";
import { writeFile } from "node:fs/promises";
const speech = await client.audio.speech.create({ model: "openai/gpt-4o-mini-tts", input: "Hello!", voice: "alloy" });
await writeFile("hello.mp3", await speech.bytes());
const transcript = await client.audio.transcriptions.create({ file: await openAsBlob("call.wav"), model: "deepgram/nova-3" });
await client.models.endpoints("openai/gpt-5.5");
await client.generations.retrieve(completion.id);Speech returns the audio as it streams from the provider. Live transcription, streamed speech input, and voice sessions open WebSockets with connect(). Any operation in the spec without a dedicated method can be called by its operation ID with client.operation().