The local REST API

Ollama · Practical · 12 min

Every app, library and integration talks to Ollama through this API, so knowing it makes debugging easy.

The Ollama server answers HTTP requests at http://localhost:11434. Any language that can send HTTP requests can use it. The main endpoints:

  • POST /api/chat: send a list of messages (each with a role of system, user, assistant or tool, and content), get the next assistant message. Used for conversations and most apps.
  • POST /api/generate: send a single prompt string, get a completion. Simpler; good for one-off tasks.
  • POST /api/embed: turn text into embedding vectors.
  • GET /api/tags: list downloaded models. GET /api/ps: list loaded models.
  • POST /api/pull, POST /api/show, DELETE /api/delete: manage models.

Streaming is on by default. The reply arrives as many small JSON objects, one per line (a format called NDJSON). Each contains a piece of text in message.content; the last one has "done": true plus statistics such as eval_count (tokens generated) and durations in nanoseconds. Set "stream": false to receive a single JSON object instead.

Other common request fields:

  • options: model settings such as temperature, num_ctx, seed, num_predict (a later lesson).
  • format: "json" or a JSON schema for structured output.
  • tools: functions the model may call.
  • keep_alive: how long to keep the model loaded afterwards.

The API is stateless: it doesn't remember earlier requests. To continue a conversation, send the whole message history each time.

Errors come back as an HTTP error status with an error message, for example when a model name isn't downloaded.

Example

# Single JSON reply
curl http://localhost:11434/api/chat -d '{
  "model": "gemma4:e2b",
  "messages": [
    {"role": "system", "content": "Answer in one sentence."},
    {"role": "user", "content": "What is a port number?"}
  ],
  "stream": false
}'
# {"model":"gemma4:e2b","message":{"role":"assistant","content":"A port number ..."},
#  "done":true,"eval_count":24,"total_duration":812345678,...}

# Streaming (default): one JSON object per line
curl http://localhost:11434/api/generate -d '{"model": "gemma4:e2b", "prompt": "Count to 3"}'
# {"response":"1","done":false}
# {"response":",","done":false} ...
# {"response":"","done":true,"eval_count":6,...}

curl http://localhost:11434/api/tags      # downloaded models as JSON

Remember

  • /api/chat takes messages; /api/generate takes a prompt
  • Streaming NDJSON is the default; "stream": false returns one object
  • Stateless: resend the conversation history on every call

Watch out for

  • Parsing a streaming response as a single JSON document, which fails because it is many JSON lines.

Check yourself

  1. Your code calls /api/chat without setting stream and json.loads(response_text) fails. Why?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ollama.com/api/introduction