Skip to content

Switch to Curva in 5 minutes

This guide is for teams that already get structured answers from a model: another typed-decision or classification API, or a prompt that asks an LLM to “reply with one of: billing, technical, sales” and parses the text. Curva does the same job and adds the parts that make the answers safe to automate.

What you have today In Curva
Pick one label from a list (single choice, classification) Choice: option key → description; answer is choice + probabilities + confidence
A rating or ordered scale (1–5, low/medium/high) Score: levels, lowest first; answer is the expected level + a probability per level
Yes/no, true/false, a flag Noul: answer is noul = P(yes)
Tags, any subset of labels Multi: each option gets its own probability; selected are those over the threshold
“Parse the model’s text and hope it’s valid” Never needed: every answer is typed and validated
A confidence the model wrote in its reply Probabilities read from the model’s token probabilities, then calibrated on your feedback

See Questions and answers for every field.

Many typed-decision clients send questions in a criteria shape. Curva accepts it as is at POST /v1/systemone, an alias of /v1/decide:

{
"state": {"ticket": "I was charged twice for order A-104"},
"model": "curva-latest",
"questions": {
"team": {"type": "choice", "instructions": "Which team?",
"criteria": {"billing": "payments, refunds", "technical": "bugs", "sales": null}},
"anger": {"type": "score", "instructions": "How frustrated?",
"criteria": ["calm", "annoyed", "angry"]},
"refund": {"type": "noul", "instructions": "Asks for a refund",
"criteria": {"true": "explicitly asks for money back", "false": "anything else"}}
}
}
  • Choice criteria: key → description (text, null or JSON). There is no escape option unless the question sets "escape": true, so answers match what your client expects.
  • Score criteria: level descriptions, lowest first. Noul criteria is optional.
  • model: curva-latest or a pinned curva-x.y.z config; a name without a provider prefix means the server’s default model; anything else is a model id or a plan.
  • The response is the /v1/decide response plus usage and a type on every answer.
  • GET /v1/models lists the config names model accepts.

The Python SDK has the same shape: client.system_one(...) with Choice(..., criteria={...}), Score(..., criteria=[...]) and Noul(..., criteria={...}) (reference).

Run Curva (Getting started or Self-hosting), create a key, and point your client at it:

Terminal window
curva serve # http://127.0.0.1:7777
curva keys create --name my-app # prints curva_… once
Terminal window
# before: https://<your current provider>/…
export BASE_URL=http://127.0.0.1:7777
curl -s $BASE_URL/v1/systemone -H "authorization: Bearer $CURVA_API_KEY" \
-H 'content-type: application/json' -d @request.json

That’s the whole switch for a criteria client. For a prompt you parse yourself, replace the prompt with a /v1/decide call: the question list is your label list.

  • Calibration on your data. Send the true answer as feedback; from 30 labels per question, Curva calibrates when that helps, so a 0.9 means right about 90% of the time on your traffic.
  • Debiasing. Options are asked in both orders and averaged, so an answer doesn’t depend on which label came first (details).
  • Abstain. Set min_confidence and unsure answers come back abstain: true, for a person or a stronger model.
  • Audit. Every decision is logged with model, config, answers, cost and a salted hash of the state (never the state itself).
  • Self-host. One binary and a SQLite file; your data stays on your machines.
  • Any model. Any OpenRouter or OpenAI-compatible model, free ones included, blended with council, cascade or race, or your own fine-tuned model.

Replay a day of logged traffic with shadow mode to see how often Curva agrees with your current system, and at what confidence it can take over.

  • Each question mapped to Choice, Score, Noul or Multi
  • Curva running, API key created
  • Base URL changed (/v1/systemone for criteria clients, /v1/decide otherwise)
  • model set (a pinned config for reproducible answers, or a model id)
  • Shadow run on logged traffic, agreement checked
  • Decision ids stored, feedback flowing
  • min_confidence set where a wrong answer is expensive

© 2026 Tarkova Private Limited.