input and a list of questions; you get back one typed answer per question, in order.
Endpoints
Bifrost serves decisions on three routes. Each one reaches every decision provider below; they differ only in the request and response shape, so pick the one that matches your client.Providers
Write models asprovider/model to pick the provider explicitly. Switching providers only changes model.
Every provider also answers on
/openai/v1/decisions and /typesafe/v1/systemone when you send a provider/model name, so an OpenAI or TypeSafe SDK can reach any of them. Each provider page covers its setup.
Chat models (for example openai/gpt-4o) have no decisions endpoint. By default they return 400 with code unsupported_operation; with the compat setting convert_decision_to_responses on, Bifrost emulates the answer through the model’s Responses API. See Decision-to-Responses Emulation.
Basic Request
Input
input is what the questions are about. It takes one of four forms:
Text: a string.
{ "role", "content" }. content is a string, or a list of parts. Use parts to send images:
image_urlis a base64 data URL or anhttpsURL. Ollama reads base64 only.detailis optional:low,high,auto, ororiginal.- Parts are
input_text,input_image, andinput_json({ "type": "input_json", "data": { ... } }, an object or an array) in user messages, andoutput_textandrefusalin assistant messages. A provider that reads text only (Azure, Databricks’ai_decide, Laya, Nimble) rejects an image with a400, which lets a fallback that reads images take the request. TypeSafe and Databricks’ System One models read images by reference only, as below, and reject an inline image the same way. vLLM and SGLang v0.5.22 or later forward images to the model, which answers or returns its own400. SGLang v0.5.21 ignores images, so it can answer without them instead of returning a400. - An
input_textpart’stextis a string, or structured data (object or array) that System One models read as is and OpenAI receives as JSON text.
Conversation History
To judge a conversation, send its messages together with the function calls, custom tool calls, and their outputs, in order. Each output names the call it answers bycall_id:
input_text and input_image parts. OpenAI’s decision models read every item as sent. Other models read the conversation as JSON text, so an image in a tool output is rejected by a provider that reads text only, as an image in a message is.
Images by Reference
TypeSafe places an image wherever its ID is written: in the input, inside a question’s instructions, or in choice, score, and predicate criteria. Send each image as aninput_image part with an id and the file base64-encoded in data, and write the id where the image belongs. The format is read from the bytes. A single message with one input_text part plus such parts sends that text as TypeSafe’s state, so structured data stays structured:
r-cam is the evidence, and r-thumb can define a choice option ({ "value": "thumbs_up", "description": "r-thumb" }) without becoming part of the evidence. Bifrost adds the header TypeSafe requires for images. Images sent by reference work only with TypeSafe and Databricks’ System One models; other providers reject them, including vLLM and SGLang, which would otherwise ignore the image and answer without it. See TypeSafe: Images and Box.
To send the files as they are instead of base64, use a multipart request: the JSON goes in a part named request, each image in its own file part, and the image part names its file part with name instead of carrying data:
name in a JSON request, a name with no matching file part, and a file part no image part names are each rejected with 400.
Structured data: an object, sent to System One models (TypeSafe, Clef, Perplexity, Ollama, Azure, Databricks, vLLM, SGLang, Laya, Nimble) as is, and to OpenAI as JSON text.
null: no input. OpenAI rejects it with a 400, Clef rejects it with a 422, and Bifrost rejects it with a 400 for vLLM and SGLang, which would otherwise answer without evidence.
Questions
safety_identifier (optional) is a stable end-user ID. It is sent to OpenAI, and to OpenRouter as user; other providers do not take one.
Provider-only fields, such as Laya’s min_confidence, go at the top level of the body with the header x-bf-passthrough-extra-params: true.
Response
type. A box answer carries box: its top, bottom, left, and right edges, each a fraction from 0 to 1 of the image measured from its top-left. confidence, probabilities, and legend appear when the model supplies them. A model that declines a question answers it with "type": "refusal".
Provider-Specific Fields
Some providers return extra fields. They appear only when that provider supplies them.Fallbacks
Addfallbacks to try other models in order when one fails, including when it rejects an input it cannot read (an image sent to TypeSafe, for example). Fallbacks can cross providers:
Validation
Bifrost rejects these with a400 before calling any provider:
- An unknown question
type - A
choicequestion with nochoices - Two questions with the same
name
Map Form (Deprecated)
Requests in the earlier map form are still served, and answered in the same form:kind and a value:
questions is an object keyed by name instead of a list. A state sent alongside input is ignored.
