Skip to content
Guides/Getting Started

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

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.

Terminal
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;
}
StatusClass
400BadRequestError
401AuthenticationError
402PaymentRequiredError
403PermissionDeniedError
404NotFoundError
408RequestTimeoutError
409ConflictError
422UnprocessableEntityError
429RateLimitError
5xxInternalServerError, with ProviderError for 502 and ServiceUnavailableError for 503
NoneAPIConnectionError 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 429 is retried on every endpoint, because nothing ran.
  • A 408, a 5xx, a timeout, or a dropped connection is retried on reads, and on endpoints that take an Idempotency-Key: Chat Completions, Responses, Messages, embeddings, images, video, OCR, reranking, native inference, and speech-to-speech.
  • A 409 with idempotency_in_flight is 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().