Deploy Anse | (Just Updated) ChatGPT-Style AI Chat UI for Any OpenAI API, Access Key From Boot
Anse ChatGPT-style AI chat UI for OpenAI-compatible APIs, key on server
Just deployed
Deploy and Host Anse on Railway
Built for an LLM agent to deploy and use. The deploy form has one field, your own LLM API key. Everything else is generated at deploy time, and the contract below lists every address, variable name and one script that checks the service and sends a chat message through it.
Anse is an open-source (MIT) ChatGPT-style web chat client. It talks to OpenAI or any OpenAI-compatible endpoint (OpenRouter, Ollama, vLLM, LiteLLM), keeps conversations in the browser, and installs as a progressive web app on desktop and phone.
About Hosting Anse
This template runs one service: Anse (pinned to one upstream commit) in a small wrapper image, pinned by digest, with no volume because conversations are stored in the browser. Upstream has no authentication, and its server route calls whatever endpoint and key the request body names, so a public deploy of the stock image is an open relay for your LLM key. The wrapper puts one access key in front of every route except GET /api/health, pins the upstream to your LLM_BASE_URL and LLM_API_KEY so the browser never holds the key, and only exposes the OpenAI-compatible provider. The access key is ANSE_PASSWORD, generated for you at deploy time. The wrapper listens on Railway's injected PORT on IPv4 and IPv6, so the public domain and the private network both work. The LLM endpoint defaults to OpenAI (https://api.openai.com, model gpt-4o); LLM_BASE_URL (without /v1) and LLM_MODEL can be added as variables to point at OpenRouter, Ollama or any other OpenAI-compatible server.
Agent contract
- Public URL:
ANSE_PUBLIC_URL(https://plus the service'sRAILWAY_PUBLIC_DOMAIN). It serves the chat UI at/and the chat relay at/api/handle/provider-openai. - Private URL:
http://anse.railway.internal:8080(alsoANSE_PRIVATE_URL). - Credentials:
ANSE_PASSWORD(generated, 32 characters; the Basic username isadmin) andLLM_API_KEY(yours, the only field the deploy form asks for). - Auth: any one of
Authorization: Bearer $ANSE_PASSWORD,X-API-Key: $ANSE_PASSWORD, or HTTP Basicadmin:$ANSE_PASSWORD(the browser prompts for this one). - Health:
GET /api/healthreturns 200 without credentials.
# needs: ANSE_PUBLIC_URL and ANSE_PASSWORD from the service variables
curl -s -o /dev/null -w "health: %{http_code}\n" "$ANSE_PUBLIC_URL/api/health"
curl -s -o /dev/null -w "no key: %{http_code}\n" "$ANSE_PUBLIC_URL/"
curl -s -o /dev/null -w "ui: %{http_code}\n" -u "admin:$ANSE_PASSWORD" "$ANSE_PUBLIC_URL/"
curl -s -X POST "$ANSE_PUBLIC_URL/api/handle/provider-openai" \
-H "Authorization: Bearer $ANSE_PASSWORD" -H "Content-Type: application/json" \
-d '{"conversationId":"agent","conversationType":"chat_single","botId":"chat_single","globalSettings":{"model":"gpt-4o","maxTokens":2048,"messageHistorySize":5,"temperature":0.7,"stream":false},"botSettings":{},"messages":[{"role":"user","content":"Reply with the single word pong."}]}'
A fresh deploy prints health: 200, then no key: 401, then ui: 200, then the model's reply as plain text (pong). The last call is the only one that reaches your LLM provider and bills your key; any baseUrl or apiKey in the request body is replaced by the deployer's. Set "stream":true to get the reply as a streamed body instead of one string. Send globalSettings.model to pick a model; if your LLM_BASE_URL is not OpenAI, use a model name that endpoint serves.
Why Deploy Anse on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Anse on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
- Agent-ready - one deployer field, a contract block and one working request script.
- Not an open LLM relay - upstream ships without authentication and trusts the endpoint and key in the request; here every route except the health check needs the generated access key, and the upstream is pinned server-side.
- Any LLM - OpenAI by default, or any OpenAI-compatible endpoint through
LLM_BASE_URLandLLM_MODEL. - Stateless - nothing to back up, and the image is pinned by digest.
Common Use Cases
- Private ChatGPT-style UI for a team - one shared address and one access key, backed by a model and billing account you choose.
- Front end for a self-hosted model - point
LLM_BASE_URLat Ollama, vLLM or LiteLLM and give people a clean chat interface to it. - Agent-readable chat endpoint - an orchestrating agent calls
POST /api/handle/provider-openaiwith the access key and never sees the provider key.
Dependencies for Anse Hosting
- An API key for an OpenAI-compatible LLM provider (
LLM_API_KEY).
Deployment Dependencies
Implementation Details
| Variable | Purpose |
|---|---|
ANSE_PASSWORD | Generated access key, accepted as Bearer, X-API-Key or the Basic password for user admin. |
LLM_API_KEY | Your LLM provider key. The only field the deploy form asks for. |
ANSE_PUBLIC_URL | HTTPS address of the chat UI and relay. |
ANSE_PRIVATE_URL | Address other services in the project use. |
The image runs railway_app.js, which starts Anse on a loopback port, puts the access-key check and the request rewrite in front of it, and opens separate IPv4 and IPv6 sockets on $PORT. Optional variables you can add: LLM_BASE_URL, LLM_MODEL.
Template Content
LLM_API_KEY

