~/tools / Run a local LLM on your server / Ollama OpenAI Converter
Ollama OpenAI Converter — Convert chat requests and responses between Ollama /api/chat and /v1/chat/completions
Convert a chat request between Ollama's native /api/chat and its OpenAI-compatible /v1/chat/completions, in either direction, and turn an /api/chat response into the response that /v1/chat/completions returns. The conversion follows Ollama's own source code, and the tool lists every field that is renamed, dropped or has no counterpart. Nothing leaves your browser.
Read as an OpenAI-compatible request (/v1/chat/completions).
- Ollama does not read these fields and drops them: tool_choice
curl
Sends to Ollama on localhost:11434. Change the address if Ollama runs elsewhere.
curl http://localhost:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"system","content":"Answer in one sentence."},{"role":"user","content":"What is the weather in Toronto?"},{"role":"assistant","content":"","tool_calls":[{"id":"call_1","function":{"name":"get_weather","arguments":{"city":"Toronto"}}}]},{"role":"tool","content":"11 degrees, cloudy","tool_name":"get_weather","tool_call_id":"call_1"}],"stream":false,"options":{"stop":["END"],"num_predict":200,"temperature":0.2},"tools":[{"type":"function","function":{"name":"get_weather","description":"Weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}]}'Ollama /api/chat request
{
"model": "qwen2.5:7b",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "What is the weather in Toronto?"
},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_1",
"function": {
"name": "get_weather",
"arguments": {
"city": "Toronto"
}
}
}
]
},
{
"role": "tool",
"content": "11 degrees, cloudy",
"tool_name": "get_weather",
"tool_call_id": "call_1"
}
],
"stream": false,
"options": {
"stop": [
"END"
],
"num_predict": 200,
"temperature": 0.2
},
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
}
]
}Converted fields
| From | To |
|---|---|
| tool_choice | not carried over |
| stop | options.stop |
| max_tokens | options.num_predict |
| temperature | options.temperature |
| stream | stream(not set, so the default of the original endpoint) |
/api/chat streams by default and /v1/chat/completions does not. The converted request always sets stream, so that it behaves like the original.
The OpenAI-compatible API has no field for the context length (num_ctx). Ollama's documentation suggests creating a model with PARAMETER num_ctx in a Modelfile and calling it by that name.
The conversion follows Ollama v0.40.14. In earlier versions, the OpenAI-compatible endpoint set temperature and top_p to 1.0 when a request did not send them, and the tool calls of an assistant message with an empty content array were attached to the previous message.
Conversion from Ollama's source code (v0.40.14, openai/openai.go) and the OpenAI compatibility page, checked against Ollama 0.40.11 on 2026-11-06. Ollama: OpenAI compatibility
Everything is done in your browser. The tool connects to nothing.
Ollama answers chat requests on two endpoints: its native /api/chat and the OpenAI-compatible /v1/chat/completions. The second one does not run requests on its own. In Ollama's source code (openai/openai.go), each request is first converted into an /api/chat request, and the answer is converted back. This tool does the same conversion in your browser. Paste a request body or a response, and it detects which one it is. From the OpenAI form to Ollama: max_tokens becomes options.num_predict, a single stop string becomes a list, temperature, top_p, seed and the penalties move into options, response_format becomes format ("json", or the schema from json_schema.schema), reasoning_effort becomes think (none becomes false, minimal becomes low, xhigh and ultra become max), the arguments of tool calls change from a JSON string to an object, and a tool message gets the function name looked up from its tool_call_id. Each part of a content array becomes its own message, and images must be base64 data URLs of JPEG, PNG or WebP images; image URLs are rejected. Fields that are not in Ollama's code, such as tool_choice, n, user, logit_bias and max_completion_tokens, are dropped without an error. In our test on Ollama 0.40.11, a request with max_completion_tokens 3 still returned a long answer, because Ollama reads only max_tokens. In the other direction, options without an OpenAI counterpart, such as num_ctx, top_k and min_p, are listed instead of written. For a response, done_reason becomes finish_reason (stop becomes tool_calls when the model called a tool), prompt_eval_count and eval_count become usage, thinking becomes reasoning, and the durations are dropped. Ollama writes the id as chatcmpl- followed by a random number; the tool writes chatcmpl-0. We checked the conversion by sending both forms of each request to Ollama 0.40.11 with the debugging field _debug_render_only, which returns the prompt the model would see, and comparing the two prompts, and by comparing converted responses with the real answers of /v1/chat/completions.
The core logic of this tool is open source under the MIT License. github.com/seigo5555/toolkitbox-lib/src/ollama-openai.ts
Use Cases
- Move code written for the OpenAI SDK to Ollama's native API, or the other way round, without guessing the field names
- Find out why a field you send to /v1/chat/completions has no effect
- See what a client that expects OpenAI responses will receive from Ollama
Usage
- Paste a /v1/chat/completions or /api/chat request body, or an /api/chat response sent with stream set to false.
- Leave the direction on automatic, or choose it if the tool cannot tell which form you pasted.
- Copy the converted JSON or the curl command, and read the warnings and the table of converted fields.
FAQ
Why does the converted request always set stream?
/api/chat streams by default and /v1/chat/completions does not. If the original request did not set stream, the converted one gets the default of the original endpoint, so that both behave the same.
How do I set the context length through the OpenAI-compatible API?
There is no field for it. Ollama's documentation suggests creating a model with PARAMETER num_ctx in a Modelfile and calling the API with that model name. The tool lists options.num_ctx as having no counterpart.
A field is marked as not carried over. Does Ollama reject the request?
No. Ollama does not read fields that are not in its code and drops them. In our test on Ollama 0.40.11, a request with tool_choice, n, user, logit_bias and max_completion_tokens was accepted without an error, and max_completion_tokens did not limit the length of the answer.
What changed in Ollama v0.40.14?
Before v0.40.14, the OpenAI-compatible endpoint set temperature and top_p to 1.0 when a request did not send them. From v0.40.14 the model's own defaults apply, as with /api/chat. An assistant message with an empty content array and tool calls was also handled differently: in our test on 0.40.11, its tool calls were attached to the previous message. The tool follows v0.40.14.
Why can I not paste an OpenAI response?
Ollama converts native responses into the OpenAI form, never the other way round, so there is no conversion to copy. Paste the /api/chat response instead.
Is my data sent anywhere?
No. The conversion runs in your browser. The curl command is only text for you to run.
Related articles
- Calling a local model from your code: structured outputs and the OpenAI-compatible API in OllamaConstrain a local model's output with a JSON Schema and call Ollama from OpenAI-style clients: what the official docs say, and what is not supported.
- Watch the memory of Ollama on a small VPSSee what Ollama holds in memory, how long it stays there and which settings change it: ollama ps, keep_alive and the limits, from the official FAQ.
- Connect Dify to Ollama on your own VPSRun Dify on your own VPS and use Ollama as its model: install, the plugin fields, the Docker address problem and embeddings, from the official documentation.