Contents
Ollama REST API Tutorial: Call /api/chat and /api/generate with curl
Ollama provides an HTTP API in the background at http://localhost:11434 by default. The CLI, Open WebUI, and various libraries communicate with models through this API.
/api/chat: chat
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [
{ "role": "system", "content": "Please answer in Traditional Chinese." },
{ "role": "user", "content": "Why is the sky blue? Explain in two sentences." }
],
"stream": false
}'
The response has the following format. This is an actual response to sending hi to qwen3:0.6b (Ollama 0.40):
{
"model": "qwen3:0.6b",
"created_at": "2026-10-12T14:04:31.457272357Z",
"message": {
"role": "assistant",
"content": "Hello! How can I assist you today? 😊 If you have any questions or need help, feel free to ask!",
"thinking": "Okay, the user just said \"hi\" and I need to respond. ..."
},
"done": true,
"done_reason": "stop",
"total_duration": 10507470186,
"load_duration": 26072287,
"prompt_eval_count": 11,
"prompt_eval_duration": 274566000,
"eval_count": 112,
"eval_duration": 10179865000
}
message.content: the model's answer.message.thinking: the reasoning process of a reasoning model. Qwen3 thinks by default; add"think": falseto the request if you don't need it.done_reason:stopmeans the response ended normally;lengthmeans it was truncated after reaching the length limit.- All time fields are in nanoseconds (10507470186 ≈ 10.5 seconds).
eval_count ÷ eval_durationgives the number of tokens generated per second.
Multi-turn conversations
The API itself doesn't remember previous messages. To continue a conversation, include the full message history:
{
"model": "qwen3:8b",
"messages": [
{ "role": "user", "content": "My name is Alex." },
{ "role": "assistant", "content": "Hello, Alex!" },
{ "role": "user", "content": "What is my name?" }
]
}
role can be system, user, assistant, or tool (a tool result; see Tool calling).
/api/generate: one-shot text generation
When you don't need a conversation structure, you can use /api/generate:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:8b",
"prompt": "Translate this sentence into English: The weather is beautiful today.",
"stream": false
}'
The answer is in the response field. In general, /api/chat is the recommended choice.
Streaming responses
stream defaults to true: each time the model generates a short piece of text, it returns a JSON line. The done value in the final line is true.
curl http://localhost:11434/api/chat -d '{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "Count from 1 to 5" }]
}'
{"message":{"role":"assistant","content":"1"},"done":false}
{"message":{"role":"assistant","content":"、2"},"done":false}
...
{"message":{"role":"assistant","content":""},"done":true,"eval_count":12}
Streaming lets users see the response right away, so nearly all chat interfaces use it.
options: adjust parameters
{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "Write a slogan" }],
"options": {
"temperature": 0.9,
"num_ctx": 8192,
"num_predict": 100,
"seed": 42
},
"stream": false
}
The available parameters are the same as Modelfile's PARAMETER values; see the Modelfile tutorial.
keep_alive: control how long a model stays loaded
{ "model": "qwen3:8b", "keep_alive": "1h" }
- Send only
model, without a message, to preload a model. "keep_alive": 0unloads the model immediately after it responds."keep_alive": -1keeps the model loaded indefinitely.
Image input
Vision models can accept base64-encoded images in a message:
IMG=$(base64 -w0 photo.jpg) # macOS: base64 -i photo.jpg
curl http://localhost:11434/api/chat -d "{
\"model\": \"gemma3\",
\"messages\": [{
\"role\": \"user\",
\"content\": \"Describe this image\",
\"images\": [\"$IMG\"]
}],
\"stream\": false
}"
Thinking mode
For models that support thinking, you can control it with think:
{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "How many r's are in strawberry?" }],
"think": true,
"stream": false
}
The thinking content is in message.thinking, and the final answer is in message.content. think can also be false; some models support levels such as "low", "medium", and "high".
Other commonly used endpoints
| Method and path | Purpose |
|---|---|
GET /api/tags | List downloaded models (equivalent to ollama list) |
GET /api/ps | List loaded models |
POST /api/show | Model information |
POST /api/pull | Download a model |
DELETE /api/delete | Delete a model |
POST /api/embed | Generate text embeddings; see Text embeddings and RAG |
GET /api/version | Ollama version |
curl http://localhost:11434/api/tags
curl http://localhost:11434/api/show -d '{"model": "qwen3:8b"}'
OpenAI-compatible API
Ollama also provides endpoints compatible with the OpenAI API under /v1:
| Endpoint | Description |
|---|---|
/v1/chat/completions | Chat |
/v1/completions | Text completion |
/v1/embeddings | Embeddings |
/v1/models | Model list |
/v1/responses | Responses API |
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3:8b",
"messages": [{ "role": "user", "content": "Hello" }]
}'
Many programs and tools originally written for OpenAI can use local models by changing the base URL to http://localhost:11434/v1 and setting the API key to any value. See the next section for a Python example.
Updated October 12, 2026