Jev /v1/systemone
POST /v1/systemone is cc-router’s entry point for Jev (System One) decision models. Jev is a family of structured decision models: the request carries a state and a set of questions, and the response returns a structured answer for each question in answers — no chat text is generated.
cc-router pools the keys of several upstreams under a dedicated virtual model, model-jev. The protocol is passed through as-is with no translation, but you still get the same multi-subscription dispatch, failover, cooldowns, quotas, and request logs as on the chat endpoints.
Applies to cc-router v6.3.0 and later. For a comparison of all four entry points, see API Overview.
Jev can’t be used by chat tools such as Claude Code or Codex. It’s meant for your own code, agent frameworks, or anything that can send HTTP requests.
Quick setup
| Setting | Value |
|---|---|
| Endpoint URL | http://127.0.0.1:23456/v1/systemone (use the full path) |
| Auth | Authorization: Bearer <token>; x-api-key: <token> also works |
| Model name | model-jev (the anthropic/ / openai/ prefixes are accepted), or the upstream’s real model name |
Verify from the command line:
curl http://127.0.0.1:23456/v1/systemone \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <cc-router token>" \
-d '{
"model": "model-jev",
"state": "Hello World",
"questions": {
"says_hello": {
"type": "noul",
"instructions": "Does the state text contain a greeting?"
}
}
}'
The Virtual models page in cc-router has a model-jev card where you can copy a curl example with the address and token already filled in; Setup guide → Generic Integration also has a Jev integration card.
Python (httpx):
import httpx
resp = httpx.post(
"http://127.0.0.1:23456/v1/systemone",
headers={"Authorization": "Bearer <cc-router token>"},
json={
"model": "model-jev",
"state": "User says: the headphones I bought last week are broken, I want a refund.",
"questions": {
"refund": {"type": "noul", "instructions": "Is the user asking for a refund?"},
},
},
timeout=60,
)
print(resp.json()["answers"])
Protocol position
Client (System One) cc-router Upstream
─────────────────── ────────────────────────────────────── ──────────────
POST /v1/systemone ───────►│ Validate: JSON object + string model │
│ ↓ │
│ Dispatch among model-jev subs only │──► pick sub / rewrite model
│ ↓ │◄── upstream response
│ Return as-is (only model restored) │
◄────────── HTTP response ─│ │
Unlike the three chat endpoints, /v1/systemone does not go through the Anthropic Messages dispatch pipeline and does no protocol translation at all:
- The request body is forwarded to the upstream byte for byte, except that the
modelfield may be rewritten. - The response body is returned to the client as-is, except that the
modelfield may be restored. - Routing is decided by the path: anything that comes in through this endpoint always goes to
model-jev, whatever model name the request body uses.
Request
Fields
cc-router does only minimal validation and leaves the rest to the upstream (each upstream has its own validation rules anyway):
| Field | Validated by cc-router | Notes |
|---|---|---|
| Request body as a whole | Yes | Must be a JSON object, otherwise 400 |
model | Yes | Must be a string, otherwise 400 缺少 model 字段 (“missing model field”) |
state | No | The state to evaluate; forwarded as-is |
questions | No | The set of questions; keys are question IDs, values contain type, instructions, etc.; forwarded as-is |
| Other fields | No | Forwarded as-is |
Non-streaming only. Upstreams handle
stream: trueinconsistently (some return 400, some ignore it), so don’t rely on it.
model rewrite rules
Each System One subscription has a single optional Jev model slot. The model actually sent upstream depends on the subscription that gets picked:
model sent by the client | Subscription has a Jev model set | Subscription has no Jev model set |
|---|---|---|
model-jev (or anthropic/model-jev / openai/model-jev) | Rewritten to the configured model | Rewritten to the endpoint’s example model (e.g. clef-flash, jev-latest) |
The upstream’s real model name (e.g. jev-preview) | Rewritten to the configured model | Passed through as-is |
When model was rewritten, the model in the response is restored to the name the client sent (e.g. it still echoes model-jev); when it wasn’t, the specific version name returned by the upstream is passed through (e.g. the upstream resolves jev-latest to jev-1.13.0).
For endpoints whose upstream URL contains a
{model}placeholder (such as Cloudflare’s/run/@cf/.../{model}), the model name may only contain letters, digits, and._:-, and must start with a letter or digit; otherwise cc-router returns 400. This prevents a model name spliced into the URL path from reaching other upstream endpoints.
Response
On success, the upstream’s standard System One response body is returned, shaped like this:
{
"model": "model-jev",
"answers": {
"says_hello": { "type": "noul", "noul": 0.98 }
},
"usage": { "input_tokens": 160, "output_tokens": 0 }
}
- The exact structure of each answer depends on the question’s
type; see the upstream’s documentation. - Cloudflare Clef wraps its raw response in a
{result, success, errors, messages}envelope; cc-router strips the envelope and normalizes it to the standard shape above.success: falseis treated as a failure even with a 2xx status. usagecounts toward the Statistics and Receipts pages (model-jev only appears on a receipt once it has usage).
Errors
Errors generated by cc-router itself use TypeSafe’s official error body shape:
{ "detail": { "error_type": "invalid_request_error", "message": "缺少 model 字段" } }
| Status | error_type | When |
|---|---|---|
400 | invalid_request_error | The request body isn’t a JSON object, model is missing, or the model name contains illegal characters |
401 | — | cc-router token authentication failed (same as the other endpoints, Anthropic-shaped error body) |
4xx | Upstream’s, as-is | Every candidate subscription failed and the last failure was a problem with the request itself: the last upstream’s error is returned as-is |
502 | api_error | Cloudflare returned 2xx but the envelope has success: false or no result |
503 | overloaded_error | model-jev has no bound subscriptions, or every candidate is unavailable due to network errors, 5xx, auth failures, rate limits, or quotas (message includes a status summary for each subscription) |
Dispatch
- Only System One subscriptions are dispatched:
model-jevcan only be bound to subscriptions whose endpoint is System One; chat subscriptions are never used here, and System One subscriptions never join the other virtual models. - Dispatch modes work as usual: sequential / round-robin / session affinity are all available, and cooldowns and token quotas work the same as on the chat endpoints.
- A 4xx also moves on to the next upstream: in practice, upstreams accept slightly different things for the same request (an unknown model returns 400 on some and 404 on others), so when one upstream returns a 4xx, cc-router keeps trying the next one and does not put that subscription into cooldown.
401/403/429are treated as problems with the subscription itself:401/403mark the subscription as an auth failure, and429puts it into rate-limit cooldown. - Session affinity only uses the
x-session-idheader: without it, requests are assigned round-robin. cc-router doesn’t derive a session from the request body (identicalstatevalues are still independent decisions).
Isolation from the chat endpoints
Chat endpoints (/v1/messages, etc.) | /v1/systemone | |
|---|---|---|
| Available virtual models | model-fable / opus / sonnet / haiku / fallback | model-jev only |
| Receiving the other side’s model name | A chat endpoint returns 400 for model-jev | Whatever is sent, it always goes to model-jev |
| Bindable subscriptions | Chat subscriptions | System One subscriptions |
| Protocol translation | Yes (except /v1/messages) | None |
GET /v1/models | Listed | model-jev is not listed |
Built-in upstreams
In cc-router’s Add subscription page, pick the System One endpoint of any provider below. Providers with a Jev tag in the provider dropdown are the ones that support decision models.
| Provider | Notes |
|---|---|
| TypeSafe | The provider of the Jev models. Enter the model name by hand: jev-latest (stable) or jev-preview (preview). Auth only accepts Authorization: Bearer |
| Cloudflare Clef | Cloudflare’s decision model; example model clef-flash. Connect directly or through AI Gateway: enter your account ID when adding the subscription, plus the gateway ID when going through AI Gateway. The API token needs Workers AI permissions (and AI Gateway permissions when going through AI Gateway) |
| OpenRouter | Pick its System One endpoint |
| Ollama | Local System One endpoint; requires Ollama 0.35 or later |
A subscription’s protocol is fixed once created and can’t be switched between a chat endpoint and a System One endpoint; create a new subscription instead.
Request logs and privacy
Each attempt (including retries that move on to the next upstream) is logged as one request log row, with Entry endpoint showing /v1/systemone. The log does not record state, questions, answers, confidence scores, or costs; the full request echoed back in an upstream 422 error body is also stripped before it’s stored.