getmux
Python client for Mux: one API, one key and one bill for Exa, Parallel, Keenable and DeepSeek web search, with automatic fallbacks, per-key spend limits and bring-your-own-key support.
uv add getmux
Requires Python 3.9+. The only dependency is httpx.
Quickstart
Create an API key in the dashboard, add credits, and put the key in your environment:
export MUX_API_KEY="mux-..."
from getmux import Mux
mux = Mux() # reads MUX_API_KEY
res = mux.search("latest developments in fusion energy", max_results=5)
for r in res.results:
print(r.title, r.url)
print(f"served by {res.model} for ${res.cost_usd}")
You can also pass the key explicitly. An explicit key always wins over the environment variable, so one process can hold several clients:
mux = Mux(api_key="mux-...")
Choosing models and fallbacks
With no model, Mux uses auto. Pin a model, or give an ordered list to fall back through:
mux.search("solid-state batteries", model="exa/auto")
res = mux.search(
"solid-state batteries",
models=["parallel/fast", "exa/auto", "keenable/pro"], # tried in order
include_domains=["nature.com"],
published_after="2026-01-01",
content="full",
)
print(res.attempts) # every model tried and how it went
Failed provider calls are refunded automatically, so you only pay for the answer you got. See the model list.
Async
import asyncio
from getmux import AsyncMux
async def main():
mux = AsyncMux()
res = await mux.search("open source vector databases")
print(res.results[0].url)
await mux.aclose()
asyncio.run(main())
AsyncMux has the same methods as Mux, as coroutines. Close the sync client with mux.close().
Errors and retries
Every non-2xx response raises MuxError with status, code, message and the parsed body:
from getmux import Mux, MuxError
try:
Mux().search("hello")
except MuxError as e:
if e.code == "insufficient_credits":
print("Add credits:", e.body["needed_usd"])
else:
raise
429 and 5xx responses (except 502) are retried automatically, up to max_retries times (default 2) with exponential backoff starting at 300 ms. If the response has a Retry-After header, the client waits at least that long (up to 10 seconds). 4xx errors, including 402, are not retried. See Errors for every code.
Other calls
mux.credits() # balance in USD
mux.checkout(50) # Stripe checkout URL for a $50 top-up
mux.usage(days=7) # spend and request counts
mux.activity(limit=20) # recent requests
mux.ledger(kind="usage") # credit history
mux.key() # limit, remaining and usage of the key in use
Managing API keys
Key management needs a management key (mux-mgmt-...), which can administer keys but can never search:
import os
admin = Mux(api_key=os.environ["MUX_MGMT_KEY"])
secret, key = admin.keys.create("agent-7", limit=25, limit_reset="monthly") # the secret is shown once
admin.keys.update(key.id, limit=50) # change a limit
admin.keys.update(key.id, limit=None) # remove it (omit an argument to leave it unchanged)
admin.keys.update(key.id, disabled=True) # kill switch
admin.keys.list()
admin.keys.delete(key.id)
Bring your own provider keys
admin.provider_keys.set("exa", "my-exa-key")
admin.provider_keys.set("parallel", "my-key", always_use=True) # never fall back to Mux's shared key
admin.provider_keys.list() # only a hint of the last 4 characters is returned
admin.provider_keys.delete("exa")
Your keys are encrypted at rest. See Bring your own key for pricing.
Client options
| Option | Default | Description |
|---|---|---|
api_key |
MUX_API_KEY |
Your key. The constructor raises ValueError if neither is set. |
base_url |
MUX_BASE_URL, else https://api.getmux.io/v1 |
API base URL. |
timeout |
30.0 |
Per-request timeout in seconds. |
max_retries |
2 |
Retries for 429 and 5xx (except 502). |
Links
- Documentation: https://getmux.io/docs/sdks
- Status: https://status.getmux.io
- Support: support@getmux.io
MIT licensed.
Metadata
Release files for getmux 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| getmux-0.1.1.tar.gz | 11.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| getmux-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.0 kB
Release files / getmux-0.1.1.tar.gz
| Download URL | getmux-0.1.1.tar.gz |
|---|---|
| Size | 11.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
24bce33288aa9e5010e9a95269904574be3e54aad4efbd1eeb06850669febce8
|
|
BLAKE2b-256 checksum How to use checksums |
4d8b72bbfd2056fe5548e0d8388349e9af411a70e38ba3fd7e567b46a08b1c94
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.4.28
|
Release files / getmux-0.1.1-py3-none-any.whl
| Download URL | getmux-0.1.1-py3-none-any.whl |
|---|---|
| Size | 7.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
72176c07980f7605309a02fbeeb65b5d3ac90d8f0e7203d08602d0463c2be9ca
|
|
BLAKE2b-256 checksum How to use checksums |
a751e7edadd57fd53bd96d9469d3eb7b91afce19816128ad932e348f224be336
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.4.28
|
Security for getmux 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.