Melious
Integrations

Open WebUI

Self-hosted chat UI with Melious as an OpenAI connection — Docker, auto-discovered models, RAG embeddings

Open WebUI
by Open WebUI Inc.openwebui.com

Open WebUI is a self-hosted, ChatGPT-shaped chat interface for teams: Docker-deployed, with user accounts, role-based access, RAG over uploaded documents, and a workspace for custom models and tools. It grew up as an Ollama front-end, but its OpenAI connection type takes any base URL, which is the door we walk through. Two environment variables on docker run and a fresh instance comes up already pointed at us, model picker populated from GET /v1/models. One thing to know before you start: Open WebUI treats everything that endpoint returns as a chat model, so a few minutes of curation saves your users a confusing error.

Setup

Run Open WebUI

docker run -d -p 3000:8080 \
  -e OPENAI_API_BASE_URL=https://api.melious.ai/v1 \
  -e OPENAI_API_KEY=sk-mel-<YOUR_API_KEY> \
  -e ENABLE_OLLAMA_API=False \
  -v open-webui:/app/backend/data \
  --name open-webui ghcr.io/open-webui/open-webui:main

Open http://localhost:3000 and create the first account — it becomes the admin. ENABLE_OLLAMA_API=False stops Open WebUI from probing for a local Ollama you don't have.

Already running docker compose? The same two variables, with MELIOUS_API_KEY=sk-mel-<YOUR_API_KEY> in the .env beside your compose file:

docker-compose.yaml
services:
  open-webui:
    environment:
      - OPENAI_API_BASE_URL=https://api.melious.ai/v1
      - OPENAI_API_KEY=${MELIOUS_API_KEY}

Or add the connection by hand

On an instance that's already been started, those variables do nothing — they seed the config database once, on first boot, and the admin UI owns it after that.

Go to Admin Panel → Settings → Connections, click + on the OpenAI API row, and fill in:

  • URL: https://api.melious.ai/v1
  • Key: sk-mel-<YOUR_API_KEY>

The button beside the URL field — Verify Connection — calls GET /v1/models against what you typed. A Server connection verified toast means we're wired.

Pick a model

Save, and the model picker fills from GET /v1/models — everything your key can reach, no restart needed. Type glm-5.1 into the picker to start; it's our general-purpose default and handles tool calls well.

Then curate the list, because the raw one is long. Open the connection's settings, expand Advanced, and list the models you want under Model IDs. Leave it empty and you get all of them.

Curating the model list

We serve chat, embedding, image, audio, and guardrail models from one /v1/models endpoint, and nothing in the OpenAI response shape tells Open WebUI which is which. So all of them show up in the chat picker, and choosing bge-m3 for a conversation fails with The server had an error while processing your request. Sorry about that! — our error message, and not one we're proud of. Setting Model IDs is the fix; it also stops your users scrolling past seventy-odd entries to find the three they use.

A shared instance wants a short list: one general model, one for code, one cheap one for bulk work. The models hub carries the capability flags for browsing.

To build the list programmatically, filter GET /v1/models?include_meta=true on _meta.type. Today that's 48 chat, 7 embeddings, 6 image, 4 audio, and 2 guardrail.

Prefix ID, in the same Advanced section, namespaces every model from this connection — set it to melious and glm-5.1 becomes melious.glm-5.1. Open WebUI strips the prefix before the request reaches us, so nothing changes upstream, but the prefixed form is now the only one that resolves. Worth setting when you run us beside another OpenAI-compatible endpoint; worth knowing about if anything of yours refers to model IDs by name.

Documents, images, and speech

Chat isn't the only surface that talks to us, and here's the thing that catches people: Documents, Images, and Audio each keep their own URL and key, and none of them inherit your chat connection. All three ship pointed at https://api.openai.com/v1 with an empty key, so each needs the Melious base URL and your key pasted in again.

  • Embeddings — Settings → Documents, Embedding Model Engine OpenAI, model bge-m3. Worth doing even if you don't care who embeds your documents: the default engine downloads sentence-transformers/all-MiniLM-L6-v2 into the container and runs it on the host CPU, which is slower and weaker on anything that isn't English.
  • Image generation — Settings → Images, engine OpenAI, model flux-1-dev. Images come back into the chat at whatever Image Size you set.
  • Speech-to-text — Settings → Audio, STT engine OpenAI, model whisper-large-v3.

Text-to-speech is the gap: we don't serve TTS models, so leave that engine on whatever you use today.

The task model

Titles, tags, follow-up suggestions, and retrieval queries are generated on a side channel, and by default they run on whatever model the chat is using. Point Admin Panel → Settings → Interface → External Task Model at something small instead — qwen3.5-9b is a reasonable pick — and background traffic stops being billed at chat-model rates.

Fair warning: reasoning models think before they answer here too. Asking qwen3.5-9b to count to five cost us 10 completion tokens and 279 reasoning tokens — fine in a chat, wasteful on every title you generate.

What's different

  • Every model looks like a chat model. Open WebUI has no type discriminator to work with, so embedding and image models land in the picker alongside the rest. _meta.type on GET /v1/models?include_meta=true is how you tell them apart; Model IDs is where you act on it.
  • environment_impact and billing_cost reach the client untouched, and nothing renders them. Open WebUI passes our extra response fields straight through its proxy but has no UI for them. The usage dashboard aggregates the same numbers.
  • The Responses API toggle works. Setting API Type to Responses on the connection routes to /v1/responses, which we implement. Chat Completions stays the default and is the better-traveled path — switch only if you need something specific to the Responses shape.
  • Tool calls pass through unchanged. Native function calling uses the OpenAI tool_calls schema, so it works on any model that supports tools. Check _meta.capabilities.function_calling before wiring an agent to a model that can't call one, or read it off the model card at melious.ai/hub/models.

When it breaks

  • The server had an error while processing your request. Sorry about that! — the selected model can't serve a chat request. It's an embedding, image, audio, or guardrail model. Set Model IDs so it can't be picked.
  • Environment variables had no effect — OPENAI_API_BASE_URL and OPENAI_API_KEY are read into the database on first start only. Change the connection in Admin Panel → Settings → Connections, or start over with a fresh volume.
  • Model '<MODEL_ID>' was not found — Open WebUI caches the model list in memory. Save the connection again, or reload the page, after editing Model IDs.
  • 503 with "code": "provider_error" on one model — the upstream provider behind that model is having a moment. Other models on the same key keep working; retry or switch. See Rate limits if it's every request rather than one model.

Errors and retry patterns: Errors.

On this page