REST and OpenAI-compatible API

After install, Ollama serves two HTTP surfaces on the machine:

BaseUse
http://localhost:11434/apiNative API: /generate, /chat, /embed, /tags, /ps, …
http://localhost:11434/v1OpenAI compatibility (examples often use /v1/)
https://ollama.com/apiSame native shape in the cloud (auth required)

The API is not strictly versioned but is meant to stay backward compatible; rare deprecations land in release notes.


Native generate: /api/generate

Official example:

curl http://localhost:11434/api/generate -d '{"model": "gemma4", "prompt": "Why is the sky blue?"}'

One-shot JSON (disable streaming):

curl http://localhost:11434/api/generate -d '{
  "model": "gemma4",
  "prompt": "Why is the sky blue?",
  "stream": false
}'

Useful fields: system, options (temperature, num_ctx, …), keep_alive (0 unloads immediately). Default streaming is NDJSON—one JSON object per line, last line done: true.

Windows PowerShell (the Windows doc uses Invoke-WebRequest; this parses more cleanly):

Invoke-RestMethod -Method Post -Uri "http://localhost:11434/api/generate" `
  -ContentType "application/json" `
  -Body '{"model":"gemma4","prompt":"Why is the sky blue?","stream":false}'

If you want curl, call curl.exe so PowerShell does not rewrite it to Invoke-WebRequest.


Native chat: /api/chat

Send the full history in messages:

curl http://localhost:11434/api/chat -d "{
  \"model\": \"gemma4\",
  \"messages\": [
    {\"role\": \"system\", \"content\": \"Answer in concise English.\"},
    {\"role\": \"user\", \"content\": \"Why is the sky blue?\"}
  ],
  \"stream\": false
}"

PowerShell is easier with a single-quoted body:

Invoke-RestMethod -Method Post -Uri "http://localhost:11434/api/chat" `
  -ContentType "application/json" `
  -Body '{"model":"gemma4","stream":false,"messages":[{"role":"user","content":"Why is the sky blue?"}]}'

The assistant text is message.content. Vision models accept images (Base64)—see generate and chat.


Native embeddings: /api/embed

curl http://localhost:11434/api/embed -d '{
  "model": "embeddinggemma",
  "input": "Why is the sky blue?"
}'

input is a string or an array of strings. ollama pull an embedding model first (Embeddings).


Management endpoints

MethodPathRole
GET/api/tagsInstalled models (ollama ls)
GET/api/psRunning models (ollama ps)
POST/api/pullPull
DELETE/api/deleteDelete

OpenAI compatibility: /v1/chat/completions

Point an existing OpenAI SDK at a new base URL. Official examples use http://localhost:11434/v1/. api_key is required by the client but ignored locallyollama is the usual placeholder.

curl -X POST http://localhost:11434/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"gemma4\",\"messages\":[{\"role\":\"user\",\"content\":\"Say this is a test\"}]}"
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1/", api_key="ollama")
print(client.chat.completions.create(
    model="gemma4",
    messages=[{"role": "user", "content": "Say this is a test"}],
).choices[0].message.content)

The layer also implements /v1/completions, /v1/embeddings, /v1/models, and newer /v1/responses (needs a recent Ollama). Streaming, JSON mode, Base64 vision, tools, and reasoning effort are supported; not logprobs, remote image URLs, tool_choice, and several other fields. See the checklist on OpenAI compatibility.

OpenAI requests have no num_ctx. To change context, write a Modelfile with PARAMETER num_ctx and ollama create a new name.


Cloud API

Two patterns:

  1. Signed in locally: ollama run gemma4:cloud or send a :cloud model to localhost:11434; the daemon forwards.
  2. Direct cloud: https://ollama.com/api with OLLAMA_API_KEY and Authorization: Bearer ....
curl https://ollama.com/api/chat \
  -H "Authorization: Bearer $OLLAMA_API_KEY" \
  -d '{"model":"gemma4","messages":[{"role":"user","content":"Why is the sky blue?"}],"stream":false}'

List models the cloud will serve: curl https://ollama.com/api/tags (auth rules follow the current docs).


Safety notes

  • Default bind is localhost. Before 0.0.0.0, add network isolation or an authenticating proxy.
  • Compatibility api_key is not local access control.
  • Keep cloud keys in the environment, not the repo.

Next steps

评论