Skip to content

Models

The models endpoints provide catalogs of available LLM and embedding models from OpenRouter, OpenAI, and Ollama. These are used by the frontend for model selection dropdowns.

Base path: /api/models


GET /api/models/openrouter

Fetch available LLM models from the OpenRouter API. Falls back to a curated list of 23 popular models when the API is unavailable or no API key is configured.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "models": [
      {
        "id": "openai/gpt-4o-mini",
        "name": "GPT-4o Mini",
        "provider": "OpenAI",
        "context": 128000,
        "pricing": {
          "prompt": "0.00000015",
          "completion": "0.0000006"
        }
      },
      {
        "id": "anthropic/claude-sonnet-4",
        "name": "Claude Sonnet 4",
        "provider": "Anthropic",
        "context": 200000
      }
    ],
    "source": "api",
    "total": 150
  }
}
Field Type Description
source string "api" (live OpenRouter), "curated" (no API key), or "curated_fallback" (API error)
total integer Number of models (present when source is "api")
Code Cause
401 Invalid or missing token
curl http://localhost:8000/api/models/openrouter \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.get(
    "http://localhost:8000/api/models/openrouter",
    headers={"Authorization": f"Bearer {token}"},
)
data = response.json()["data"]
print(f"Source: {data['source']}, Models: {len(data['models'])}")
for m in data["models"][:5]:
    print(f"  {m['id']} ({m['provider']}, {m['context']} ctx)")

GET /api/models/openrouter/embeddings

Fetch available embedding models from the OpenRouter API. Falls back to a curated list of 21 models from 8 providers.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "models": [
      {
        "id": "openai/text-embedding-3-small",
        "name": "OpenAI Text Embedding 3 Small",
        "provider": "OpenAI",
        "dimensions": 1536,
        "context": 8192,
        "cost_per_million": "$0.02"
      },
      {
        "id": "baai/bge-m3",
        "name": "BGE-M3 (Multilingual)",
        "provider": "BAAI",
        "dimensions": 1024,
        "context": 8192,
        "cost_per_million": "$0.01"
      }
    ],
    "source": "curated"
  }
}
Field Type Description
source string "api", "curated", or "curated_fallback"

Embedding Model Immutability

The embedding model is selected when creating a notebook and cannot be changed. This endpoint is used to populate the model dropdown in the Create Notebook dialog.

Code Cause
401 Invalid or missing token
curl http://localhost:8000/api/models/openrouter/embeddings \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.get(
    "http://localhost:8000/api/models/openrouter/embeddings",
    headers={"Authorization": f"Bearer {token}"},
)
data = response.json()["data"]
for m in data["models"]:
    print(f"  {m['id']}: {m['dimensions']}d, {m['cost_per_million']}/M tokens")

GET /api/models/ollama

Fetch locally-pulled models from the Ollama instance. Filters out embedding-only models (nomic-embed-text, mxbai-embed, etc.) and returns only inference models.

Auth: User

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "models": [
      {
        "id": "qwen2.5:1.5b",
        "name": "qwen2.5:1.5b",
        "parameter_size": "1.5B",
        "quantization": "Q4_K_M",
        "family": "qwen2",
        "size_mb": 986
      }
    ],
    "source": "ollama",
    "total": 1
  }
}
Field Type Description
source string "ollama" (connected) or "ollama_unreachable" (cannot connect)
error string Error message when Ollama is unreachable (only present on error)
Code Cause
401 Invalid or missing token
curl http://localhost:8000/api/models/ollama \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.get(
    "http://localhost:8000/api/models/ollama",
    headers={"Authorization": f"Bearer {token}"},
)
data = response.json()["data"]
if data["source"] == "ollama_unreachable":
    print(f"Ollama not running: {data.get('error')}")
else:
    for m in data["models"]:
        print(f"  {m['name']} ({m['parameter_size']}, {m['size_mb']}MB)")