Prerequisites
- Docker with Compose 2.24.4 or newer
- Python 3.13 or newer and uv
- An API key for at least one provider in the shipped catalog
1
Clone the repository and set a provider key
Pick a release and clone its tag so the CLI and deployment files come from the same version:Open
.env and set one provider key, such as OPENAI_API_KEY or ANTHROPIC_API_KEY. The CLI reads this file to
import credentials. Run CLI commands with uv run airmux ...; the application container never receives these
variables.If port 8080 is already in use on your machine, set AIRMUX_PORT and AIRMUX_PUBLIC_URL to a free port in .env
and use that port everywhere below.2
Start the stack
docker compose ps reports the airmux service as healthy, and
curl http://localhost:8080/healthz returns {"status":"ok"}./readyz returns {"status":"no bundle"} until the next step creates an organization. That is expected.3
Claim the instance
default workspace; imports provider keys from .env; creates an inference key; and
sends one real model request to prove the installation.You should see: Ready. Verified <model> through the gateway. followed by your inference key and a copyable
curl command.4
Send a request from your own application
Use a model served by the provider you configured. You should see: HTTP 200 and a
uv run airmux models list shows the catalog.choices[0].message.content value, plus a usage object and a gateway object
holding any parameter airmux adjusted.An existing application needs two changes: point its base URL at http://localhost:8080/inf/v1 and replace its
provider key with the inference key. See Use an SDK.5
Find the request in the webapp
Open localhost:8080 and sign in with the account you just created.The organization Overview page opens on usage for the last 30 days. Attribution breaks the same spending
down by workspace, key owner, inference key, model, provider, or credential.Select Requests to list individual requests.You should see: your requests with spend, request count, and token counts on Overview, and one row per request
on Requests showing time, status, cost, total tokens, workspace, inference key, and model. Select a row to open its
detail panel.
Costs are
airmux estimates calculated from catalog prices at request time. They are not provider invoice amounts.
Events arrive asynchronously, so a request can take a few seconds to appear.6
Add a workspace policy and prove it works
Policies decide which requests a workspace accepts. Save this as Now repeat the request from step 5 with You should see:
output-limit-policy.json:"max_completion_tokens": 2048:403 with code policy_denied and a message naming the policy that blocked the request. The
same request with "max_completion_tokens": 512 still returns 200.In the webapp, the workspace Policies page lists the rule as Output ≤ 1,024 tokens, and the workspace
Requests page records the blocked call with status DENIED, zero tokens, and no cost.A policy reaches the gateway when the next configuration bundle is adopted, normally within seconds. See
bundles and consistency if a saved policy is not yet visible.Next steps
Move an existing application
Change a base URL and an API key, then keep your request shapes.
Control cost and routing
Restrict models, providers, prices, output length, and spending, and add bounded failover.
Understand your spending
Read usage reports, attribution, and request detail.
Deploy for real traffic
Plan TLS, persistence, backups, and separately scaled gateways.