Projects and configs
Projects
Section titled “Projects”A project is a calibration namespace. Feedback and calibrators are kept per project, so the same question can be calibrated separately for different data, customers or teams.
d = client.decide(state, questions, project="support")client.feedback(d.id, "team", "billing")client.calibration("team", project="support")Requests without project use "default". The audit log is filtered by project too, and a
project can carry its own provider key, so its model calls are billed to it (see
Self-hosting).
Pinned configs
Section titled “Pinned configs”A config freezes how a decision is made, so answers never change under you when Curva is upgraded. A pin fixes the prompt template and the default mode, debias setting and model.
| Config | Default model |
|---|---|
curva-1.0.0 |
Ling 3.0 Flash (logprobs) |
curva-1.1.0 |
Nemotron 3 Super (verbal) |
curva-1.2.0 |
Nemotron 3 Super, questions before the state: the repeating part of the prompt comes first, so provider prompt caches and local prefix caches can reuse it. Becomes curva-latest once benchmarked |
curva-latest |
The pin the operator chose with serve --latest-config (currently curva-1.1.0) |
client.decide(state, questions, config="curva-1.0.0")Fields set on the request (such as model or mode) still win over the pin. Every response and
audit entry names the config it ran under, and GET /v1/models lists the available pins.
Unknown config names get a 422.
Models
Section titled “Models”model can be:
- a model id, such as
"nvidia/nemotron-3-super-120b-a12b:free"; - a list tried in order until one answers (a fallback chain): if a model returns 429 or a server error, the next one takes over;
- a multi-model plan: council, cascade or race.
Without one, the server’s --model (or the pinned config’s model) is used.
Privacy
Section titled “Privacy”privacy: "strict" routes the model call only to providers that neither store nor train on your
prompts (provider.data_collection: "deny" on OpenRouter). The default is "standard".

