SDKs
Reference for the official TypeScript and Python clients.
The SDKs are thin, typed clients over the HTTP API. They add retries, timeouts and typed errors, and read your key from the environment.
Install
TypeScript / JavaScript:
npm install getmuxPython:
pip install getmuxThe TypeScript package works in Node 18+ and any runtime with a global fetch. The Python package requires Python 3.9+ and uses httpx.
Create a client
import { Mux } from "getmux";
const mux = new Mux(); // reads MUX_API_KEY
const custom = new Mux({
apiKey: "mux-...",
baseUrl: "https://api.getmux.io/v1",
timeoutMs: 30_000,
maxRetries: 2,
});| Option (TypeScript / Python) | Default | Description |
|---|---|---|
apiKey / api_key |
MUX_API_KEY env var |
Your key. The constructor throws if neither is set. |
baseUrl / base_url |
MUX_BASE_URL env var, else https://api.getmux.io/v1 |
API base URL. |
timeoutMs / timeout |
30,000 ms / 30.0 s | Per-request timeout. |
maxRetries / max_retries |
2 |
Retries for 429 and 5xx (except 502). |
fetch (TypeScript only) |
global fetch |
A custom fetch implementation. |
Use an API key (mux-...) for searching and a management key (mux-mgmt-...) for the keys and provider-key methods. See Authentication.
Search
const res = await mux.search({
query: "latest on fusion energy",
model: "exa/auto", // or models: ["parallel/fast", "exa/auto"]
maxResults: 10,
includeDomains: ["nature.com"],
excludeDomains: ["example.com"],
publishedAfter: "2026-01-01",
publishedBefore: "2026-12-31",
content: "snippet", // or "full"
providerOptions: {},
});Only query is required. The parameters are described in the Search API reference.
The response
TypeScript returns a SearchResponse:
| Field | Type |
|---|---|
id, model, provider, query |
string |
results |
{ title, url, snippet, content?, publishedDate }[] |
usage |
{ costUsd, results, latencyMs, byok } |
attempts |
{ model, source?, status, error? }[] (source is "byok" or "platform") |
Python returns a SearchResponse dataclass:
| Field | Type |
|---|---|
id, model, provider, query |
str |
results |
list[SearchResult] with title, url, snippet, content, published_date |
cost_usd, latency_ms |
float, int |
byok |
bool, true if the request ran on your own provider key |
attempts |
list[dict], each {model, source, status, error?} |
cost_usd is what this request cost you: the list price on Mux's keys, or the small BYOK fee (often $0) on your own. See Bring your own keys.
Other methods
| Purpose | TypeScript | Python |
|---|---|---|
| List models and prices | await mux.models() |
mux.models() |
| Credit balance (USD) | await mux.credits() |
mux.credits() |
| Stripe Checkout link | await mux.checkout(50) |
mux.checkout(50) |
| Info on the calling key | await mux.key() |
mux.key() |
| Spend by day, model and key | await mux.usage(30) |
mux.usage(30) |
| Recent requests | await mux.activity({ limit: 50 }) |
mux.activity(limit=50) |
| Credit history | await mux.ledger() |
mux.ledger() |
const models = await mux.models(); // array of model objects
const balance = await mux.credits(); // number, USD
const { url, credits_usd, fee_usd } = await mux.checkout(50);
const me = await mux.key(); // ApiKey: limit, limitRemaining, usage, ...
const usage = await mux.usage(30); // { daily, byModel, byKey } with costUsd per row
const recent = await mux.activity({ limit: 20 });
const history = await mux.ledger(); // purchases, grants and BYOK feesusage, activity and ledger work with an API key or a management key. The raw endpoints are described in Credits and usage. Pass kind: "usage" (TS) or kind="usage" (Python) to ledger to list per-request charges instead.
Key management
Requires a management key. Details and the key object are on Managing keys.
const admin = new Mux({ apiKey: process.env.MUX_MGMT_KEY });
const { key, data } = await admin.keys.create({
name: "agent-7",
limit: 25,
limitReset: "monthly", // "daily" | "weekly" | "monthly"
expiresAt: "2027-01-01T00:00:00Z",
});
const keys = await admin.keys.list({ offset: 0, limit: 100 });
const one = await admin.keys.get(data.id);
await admin.keys.update(data.id, { limit: 50 });
await admin.keys.update(data.id, { limit: null }); // remove the limit
await admin.keys.update(data.id, { disabled: true });
await admin.keys.delete(data.id);keys.create returns the secret exactly once: { key, data } in TypeScript, (secret, ApiKey) in Python.
Updating: omitted vs. null
keys.update only changes what you pass. In TypeScript, a property that is missing from the object is left alone and null clears it. In Python, an argument you don't pass is left alone, and passing None clears it (limit=None removes the limit, name=None removes the name, limit_reset=None makes the limit non-resetting).
await admin.keys.update(id, { name: "renamed" }); // only the name changes
await admin.keys.update(id, { limit: null, limitReset: null }); // clear bothProvider keys (BYOK)
Requires a management key. See Bring your own keys.
await admin.providerKeys.set("exa", "your-exa-key");
await admin.providerKeys.set("parallel", "your-key", { alwaysUse: true });
const list = await admin.providerKeys.list(); // { provider, hint, alwaysUse, createdAt }[]
await admin.providerKeys.delete("exa");Errors
Any non-2xx response raises MuxError, with the HTTP status, the error code and the message. See Errors for the list of codes.
import { Mux, MuxError } from "getmux";
try {
await mux.search({ query: "hello" });
} catch (e) {
if (e instanceof MuxError && e.code === "insufficient_credits") {
console.log("Add credits:", (await mux.checkout(20)).url);
} else {
throw e;
}
}MuxError has status, code and message, plus the raw error body (body) for extra fields like attempts or needed_usd.
Retries and timeouts
Both SDKs retry 429 and 5xx responses except 502, up to maxRetries / max_retries times (default 2), waiting 300 ms, then 600 ms. 4xx errors, including 402, are never retried. A request that exceeds the timeout fails with the underlying network error.
Async (Python)
AsyncMux has the same methods as Mux, as coroutines. Close it when you're done with aclose().
import asyncio
from getmux import AsyncMux
async def main():
mux = AsyncMux()
try:
res = await mux.search("latest on fusion energy", model="parallel/fast")
print(res.results[0].url)
keys = await mux.keys.list() # with a management key
await mux.provider_keys.list()
finally:
await mux.aclose()
asyncio.run(main())The sync client has close().