Install Curva with pip, npm or Docker and check it runs

Three ways to install Curva, what each gives you, which to pick, and three checks that prove it runs: curva --version, GET /health and a first decision.

To install Curva, pick one of three paths. pip install curva-ai gives you the Python SDK and the curva server binary in one package. npm install curva-ai gives you a zero-dependency TypeScript client that needs a running server. The Docker image ghcr.io/itsmohitrohilla/curva gives you the server alone, for production. Then three checks prove it runs: curva --version prints curva 0.1.0, GET /health returns {"status": "ok", "version": "0.1.0"}, and a first decision comes back typed. This guide covers what each path contains, the gotchas, and which one to pick.

Curva is free to use under the Curva Free License. It calls the LLM you configure, so you also need a provider key, or a local model. Any OpenRouter key works, and free models are fine for trying it out.

pip install curva-ai: SDK and server binary in one wheel

bash
pip install curva-ai
curva --version        # curva 0.1.0

One package holds both halves. The Python SDK is what your code imports. The curva binary is the CLI and the HTTP server, and it comes inside the wheel, so there is nothing else to install and no Rust toolchain to set up.

That bundling is what makes the zero-setup path work. The first curva.decide call starts a private server for your Python process on a free localhost port, reuses it for every later call, and stops it when Python exits. curva.local() does the same and keeps its database at ~/.curva/curva.db, so calibration learned in one run is still there in the next.

The binary also gives you every command-line tool: curva serve, curva map for batch files, curva shadow, curva bench, curva recipe and the rest.

Platform wheels: Linux x86_64 and aarch64, macOS, Windows, Python 3.9+

Platform wheels exist for:

PlatformWheels
Linuxx86_64, aarch64
macOSApple Silicon, Intel
Windowsincluded

The SDK itself uses only the Python standard library and needs Python 3.9 or newer. Nothing else is pulled in, which keeps it easy to add to an existing environment.

Set a provider key before your first call:

bash
export OPENROUTER_API_KEY=sk-or-v1-...

Without OPENROUTER_API_KEY, the first key set among OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY (or GOOGLE_API_KEY), GROQ_API_KEY and a few others picks a small, fast model of that provider. CURVA_MODEL chooses one yourself, for example CURVA_MODEL=@ollama/qwen3:4b for a local model. With no key at all, curva.decide raises an error that names the variables to set.

npm install curva-ai: a zero-dependency client that needs a server

bash
npm install curva-ai

The npm package has the same name and a different job. It is a TypeScript and JavaScript client with zero runtime dependencies. It uses the global fetch, so it runs on Node 18+, Deno, Bun and in browsers, and it ships as ESM with type declarations.

The gotcha: the TypeScript SDK does not start a server. Unlike the Python package, it contains no binary. Run a server first, with curva serve from the pip package or with Docker:

bash
docker run --rm -p 127.0.0.1:7777:7777 -e OPENROUTER_API_KEY ghcr.io/itsmohitrohilla/curva \
  serve --addr 0.0.0.0:7777 --no-auth

The client reads CURVA_BASE_URL, which defaults to http://localhost:7777, and CURVA_API_KEY. That docker command uses --no-auth for a quick local test only; it publishes the port on 127.0.0.1, so nothing outside your machine can reach it.

Docker: ghcr.io/itsmohitrohilla/curva with data in /data

For production, the release publishes ghcr.io/itsmohitrohilla/curva for amd64 and arm64: a distroless, non-root image of about 62 MB. Its data lives in the /data volume: decisions, feedback, calibrators, audit log and keys, all in one SQLite file. Back that volume up.

Create an API key first. Without one, Curva refuses to listen on a public address.

bash
docker run --rm -v curva-data:/data ghcr.io/itsmohitrohilla/curva keys create --name prod
bash
docker run -d --restart unless-stopped --name curva \
  -p 127.0.0.1:7777:7777 -v curva-data:/data \
  -e OPENROUTER_API_KEY=sk-or-v1-... \
  ghcr.io/itsmohitrohilla/curva

The key (curva_…) is printed once and stored only as a SHA-256 hash, so save it. Once any key exists, every route except /health needs Authorization: Bearer curva_…. Curva speaks plain HTTP, so on the public internet put it behind a reverse proxy for TLS.

Check the Curva install: curva --version, GET /health and a first decide call

Three checks, from the inside out.

**1. The binary.** curva --version should print curva 0.1.0.

**2. The server.** With a server running, GET /health should return {"status": "ok", "version": "0.1.0"}. It never needs an API key, which makes it the right target for a load balancer or container health check. From Python, against a server with keys:

bash
export CURVA_BASE_URL=https://api.example.com CURVA_API_KEY=curva_...
python -c "from curva import Curva; print(Curva().health())"

**3. A first decision.** The three-line version, with no server of your own:

python
import curva
d = curva.decide("I was charged twice, please refund me",
                 {"team": ["billing", "technical"], "refund": "Asks for a refund?", "total": float})
print(d.team, d.refund, d.total)           # billing True None

You get one of your labels, True or False for the yes/no question, and a number or None for the extraction. If this works, the binary, the provider key and the model are all in place.

Which path to pick for a script, a service or a TypeScript app

You are buildingInstallWhy
A script or notebook in Pythonpip install curva-aiNothing to run: the first call starts a private server
A Python servicepip install curva-ai, plus one shared curva serve or the Docker imageOne audit log, one set of calibrators, one decision cache for every client
A TypeScript or JavaScript appnpm install curva-ai, plus a serverThe client needs a running server
A production serverthe Docker imageDistroless, non-root, data in one volume
A batch job over filespip install curva-aicurva map calls the provider directly, no server needed

The pip and Docker paths run the same binary, so you can start with pip on a laptop and move to Docker without changing your questions.

Next steps

The docs cover this in getting started and self-hosting. For what you just installed, read what is Curva and what is a typed decision. Then build something: the Python LLM classification tutorial, TypeScript LLM classification, or the local Python server.