Local API Protocol
September 18, 2026 ยท View on GitHub
This is OpenJev's own versioned interface, inspired by the public Jev concepts. It does not claim wire compatibility with TypeSafe's API.
Routes
GET /health: status and active model ID.GET /v1/models: available model metadata, includingmock: true.POST /v1/system_one: JSON request to typed JSON response.
Requests must use Content-Type: application/json and Content-Length.
The body limit is 1 MiB; body reads time out after 10 seconds of inactivity.
Chunked uploads are not supported. The request contains 1-128 questions;
choice and score criteria contain 2-256 options. State is a string, object,
or array. JSON numbers must be finite. Unknown fields are rejected at the
request and question level. Arbitrary fields inside state are allowed.
Schemas live in specs/system-one.schema.json and
specs/system-one-response.schema.json. The runtime additionally checks
relationships that JSON Schema cannot express: answer IDs and types, criterion
keys, distribution sums, selected options, expected scores, and legends.
Answer Semantics
- Choice probabilities cover exactly the provided option keys and sum to one. The chosen option has maximum probability. Mock ties use lexical key order.
- Score criteria are indexed from zero in their original order.
scoreis the expectation over these indices, not a rounded class.legendpreserves all rubric descriptions. - Choice and score
confidenceis the highest probability minus the second highest probability. It is a margin, not a calibrated likelihood of correctness. noulis a probability in[0, 1]for the supplied statement.- Mock usage counters are zero because no model tokens are consumed.
The mock hashes canonical state and question JSON with SHA-256 to generate positive weights, then normalizes them. Reordering object keys, changing a question ID, or adding independent questions does not affect an answer. Changing score criterion order does affect the rubric. Synthetic probabilities have no semantic meaning and must not drive real workflow decisions.
Errors
Errors have the shape:
{"error": {"code": "invalid_request", "message": "Invalid request at questions"}}
400 invalid_jsonorinvalid_request: malformed JSON or transport headers.404 model_not_foundornot_found: unsupported model or route.408 request_timeout: request body read timed out.411 length_required: missing body length.413 request_too_large: body exceeds limit.415 unsupported_media_type: content type is not JSON.422 invalid_request: request fails the schema.500 internal_error: backend failed or returned an invalid answer.
SDKs raise OpenJevError for HTTP failures with status and code.
Connection failures and timeouts remain native transport exceptions.
Clients do not retry automatically. JavaScript timeout units are milliseconds;
Python timeout units are seconds. Python async calls use a worker thread;
cancelling the coroutine does not terminate the in-flight HTTP request, which
remains bounded by its transport timeout.