Use with OpenAI and OpenRouter clients
Olaverse speaks the two formats most AI clients already use, so you can switch by changing the base URL and model name:
| Format | Endpoint | Models | Works with |
|---|---|---|---|
| OpenAI chat completions | POST /v1/chat/completions |
mist-qg-1.5b, mist-extract-1.0 |
OpenAI SDKs, OpenRouter-style clients, anything that takes an OpenAI base URL |
| System One decisions | POST /v1/systemone |
purplemist-mini-2.0 |
TypeSafe SDK, OpenRouter’s System One API, Ollama, LiteLLM |
Model ids can be given as olaverse/<name> too, in any case: olaverse/MIST-Extract-1.0 and mist-extract-1.0 are the same model.
OpenAI chat completions
Section titled “OpenAI chat completions”Use your Olaverse key as the API key and https://api.olaverselab.com/v1 as the base URL.
Question generation
Section titled “Question generation”Send the passage as the user message. You always get back {"questions": [...]} as the message content, in the passage’s own language.
from openai import OpenAI
client = OpenAI(api_key=os.environ["OLAVERSE_KEY"], base_url="https://api.olaverselab.com/v1")
r = client.chat.completions.create( model="mist-qg-1.5b", messages=[{"role": "user", "content": "The Nile is the longest river in Africa. It flows north through " "eleven countries before emptying into the Mediterranean Sea."}], extra_body={"n": 3}, # optional: number of questions (1-10, default 3) and "language")questions = json.loads(r.choices[0].message.content)["questions"]curl "$OLAVERSE_URL/v1/chat/completions" \ -H "Authorization: Bearer $OLAVERSE_KEY" -H "Content-Type: application/json" \ -d '{"model": "mist-qg-1.5b", "n": 2, "messages": [{"role": "user", "content": "Water boils at 100 degrees Celsius at sea level."}]}'n(1 to 10, default 3) andlanguageare optional extra fields. Withoutlanguage, the passage’s language is detected, and the response’s top-levellanguagefield says which was used. If it can’t be told with confidence, questions are in English andwarningssays so.- The trained form
Write 3 questions that the passage directly answers, in English. ... Passage: <text>works too; the count and the passage are read from it. - The model’s output is constrained to the
{"questions": [...]}schema, so it is always valid JSON with exactlynquestions. - If you send your own system message, the request goes to the model as written, with no schema, for custom prompting.
Document extraction
Section titled “Document extraction”Send the JSON template as the system message (anything after the template is read as instructions), and the document as the user message: text, one image as a data URL, or both.
r = client.chat.completions.create( model="mist-extract-1.0", messages=[ {"role": "system", "content": '{"recipient": "verbatim-string", "amount": "number", "date": "date"}\n' "Dates are day/month/year."}, {"role": "user", "content": "Your MTN MoMo transfer of GHS 250.00 to KOFI MENSAH was successful. 14/10/2025"}, ],)data = json.loads(r.choices[0].message.content)confidence = r.model_extra["confidence"] # per-field confidence, same shape as dataFor a photo or screenshot, put the image in the user message:
{"role": "user", "content": [ {"type": "text", "text": "Receipt attached."}, {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64," + img_b64}},]}You can also pass template and instructions as top-level fields (extra_body={"template": {...}} in the OpenAI SDK) instead of using the system message.
The extracted JSON comes back as message.content. The per-field confidence comes back as an extra top-level confidence field, which the OpenAI SDK exposes on model_extra. See Document extraction for template types.
Streaming and usage
Section titled “Streaming and usage”Every model on /v1/chat/completions supports "stream": true. The last chunk before data: [DONE] carries usage, as OpenAI’s stream_options.include_usage does. Non-streaming responses report usage as prompt_tokens, completion_tokens and total_tokens.
System One decisions
Section titled “System One decisions”/v1/systemone takes the same request as OpenRouter’s, TypeSafe’s and Ollama’s System One endpoints (model, state, questions) and returns model, answers and usage with input_tokens and output_tokens.
# Only the client settings and the model name change; your calls stay the same.client = TypeSafeClient(api_key=os.environ["OLAVERSE_KEY"], base_url="https://api.olaverselab.com") # was https://openrouter.ai/apiMODEL = "olaverse/purplemist-mini-2.0" # was typesafe/jev-1.14curl "$OLAVERSE_URL/v1/systemone" \ -H "Authorization: Bearer $OLAVERSE_KEY" -H "Content-Type: application/json" \ -d '{"model": "olaverse/purplemist-mini-2.0", "state": "I was charged twice, please refund me", "questions": {"refund": {"type": "noul", "instructions": "The customer asks for money back."}}}'Errors
Section titled “Errors”Errors use the shape these clients expect, {"error": {"code": 400, "message": "..."}}. See Errors.