Decision API documentation
One endpoint. Send a state and a schema of typed questions, receive a probability for every allowed option. This page is the complete reference.
The endpoint
POST https://clef-flash.com/api/decide with a JSON body. Optionally authenticate with an API key to raise the daily quota. The free tier works without a key and is counted per browser session.
curl -X POST https://clef-flash.com/api/decide \
-H 'content-type: application/json' \
-H 'authorization: Bearer cfl_live_xxx' \
-d '{
"state": "Customer wrote: I was charged twice for the October invoice.",
"questions": [
{
"id": "intent",
"prompt": "What does the customer want?",
"options": ["billing", "technical", "cancellation", "other"]
},
{
"id": "urgency",
"prompt": "How urgent is this?",
"options": ["low", "normal", "high"]
}
]
}'
The response
The response mirrors your question ids. For each one you get the winning option, its confidence, and the full probability distribution keyed by option. `degraded` is true when the live model was unavailable and the deterministic fallback answered.
{
"ok": true,
"model": "cloudflare/clef-flash",
"degraded": false,
"latencyMs": 412,
"answers": [
{
"id": "intent",
"option": "billing",
"confidence": 0.91,
"probabilities": { "billing": 0.91, "technical": 0.04, "cancellation": 0.03, "other": 0.02 }
},
{
"id": "urgency",
"option": "high",
"confidence": 0.72,
"probabilities": { "low": 0.06, "normal": 0.22, "high": 0.72 }
}
]
}
Request fields
Every field is validated at the boundary; an invalid request is refused with a message that names the offending value.
- state — string, 3 to 6,000 characters. Free text or a JSON string.
- questions — array of 1 to 8 objects.
- questions[].id — lowercase slug, up to 32 characters, unique within the request.
- questions[].prompt — the question, up to 300 characters.
- questions[].options — 2 to 12 allowed answers, each up to 80 characters, no duplicates.
Errors
Errors return a JSON body with `ok: false` and a human-readable `error` string.
- 400 — the request was malformed; the message names the field and the value.
- 401 — an API key was supplied but is unknown or revoked.
- 429 — the daily quota is exhausted.
- 500 — something failed on our side; the request is safe to retry.
Quotas
The free tier allows a fixed number of decisions per browser session per day. Paid tiers raise that limit for API keys. The current usage of a request is not returned in the answer; ask support if you need a usage report.
Client examples
The same call in JavaScript and Python, both posting the JSON body above.
const response = await fetch('https://clef-flash.com/api/decide', {
method: 'POST',
headers: {
'content-type': 'application/json',
authorization: `Bearer ${process.env.CLEF_FLASH_KEY}`,
},
body: JSON.stringify({
state: ticketBody,
questions: [{ id: 'queue', prompt: 'Which queue?', options: ['billing', 'technical', 'abuse'] }],
}),
});
const { answers } = await response.json();
if (answers[0].confidence < 0.8) routeToHuman(ticketBody);
else routeTo(answers[0].option);
When to prefer self-hosting
If the state contains data that cannot leave your infrastructure, run the model yourself — the weights are Apache 2.0. The run-locally guide covers the hardware and the Ollama command. The request shape is the same, so the code you write against this API ports directly.
Community-hosted demo of the 9B model. Runs live in your browser session.
Frequently asked questions
Do I need an API key?
No. The free tier works without one, counted per browser session. A key raises the daily quota and is issued with a paid plan.
Is the response cached?
No. Every request runs the model. Identical requests are not de-duplicated, so avoid polling the same state in a loop.
Which model answers?
Clef-Flash by default. The response names the model actually used, and reports `degraded: true` if the deterministic fallback answered instead.
Need a higher quota?
Paid plans raise the daily limit and issue an API key. See the pricing page, or write to us for volume.