Overview
| Base URL | https://mom.vllm-sr.ai/v1 |
| Model | vllm-sr/auto |
| Endpoints | POST /v1/chat/completions · GET /v1/models |
| Pool | GLM-5.3-Flash, Qwen3.8-Flash-Next and Qwen3.8-27B, two replicas each, on AMD Instinct™ MI325X |
Any OpenAI SDK or tool that lets you set a base URL works: the OpenAI Python and Node SDKs, LangChain, LlamaIndex, agent frameworks and coding assistants.
Authentication
Send your key as a Bearer token. Create a key in your browser; it looks like sk-pt- followed by 43 letters and digits.
Authorization: Bearer $VLLM_SR_API_KEYX-API-Key: <key> is accepted too. Keep keys on servers: never put them in client-side code, apps or public repositories. If a key leaks, revoke it on the Keys page.
Chat completions
POST /v1/chat/completions takes the OpenAI request body. The parameters you need most:
| Field | Notes |
|---|---|
| model | vllm-sr/auto (required). |
| messages | The conversation: system, user, assistant and tool messages. Images go in image_url content parts as data URLs. |
| stream | true for server-sent events. Add stream_options: {"include_usage": true} for a final usage chunk. |
| max_tokens | Output budget, reasoning included. Omit it to use the model service default. |
| tools, tool_choice | Function calling; requests with tools route to the agentic decision. |
| temperature, top_p, stop, response_format | As in the OpenAI API. |
curl https://mom.vllm-sr.ai/v1/chat/completions \
-H "Authorization: Bearer $VLLM_SR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "vllm-sr/auto",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What does a KV cache store?"}
],
"max_tokens": 300
}'The answer is a standard chat.completion object with choices and usage. Its model field names the backend that answered; the routing headers below name the model in the pool.
Streaming
With "stream": true the answer arrives as server-sent events: one data: {...} line per chunk, ending with data: [DONE]. Reasoning models stream their thinking in delta.reasoning before the answer in delta.content. The stream passes through untouched.
import os
from openai import OpenAI
client = OpenAI(base_url="https://mom.vllm-sr.ai/v1", api_key=os.environ["VLLM_SR_API_KEY"])
stream = client.chat.completions.create(
model="vllm-sr/auto",
messages=[{"role": "user", "content": "Explain speculative decoding in five sentences."}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage)Tools
Declare functions in tools; the model answers with tool_calls, you run them and send the results back as tool messages. Agent loops run with up to 16 requests at once per key.
tools = [{"type": "function", "function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
}}]
resp = client.chat.completions.create(model="vllm-sr/auto", tools=tools,
messages=[{"role": "user", "content": "Do I need an umbrella in San Jose today?"}])
print(resp.choices[0].message.tool_calls)Routing headers
Every answer says how it was routed:
| Header | Meaning |
|---|---|
| x-vsr-selected-model | The pool model that answered, e.g. qwen/qwen3.8-27b. |
| x-vsr-selected-decision | The routing decision, e.g. fast, code, agentic. See how it decides. |
| x-vsr-routing-latency-ms | Time spent reading the request and deciding. |
| X-Request-Id | The request's id; quote it when you report a problem. |
| X-RateLimit-Limit-Requests, -Tokens, -Concurrency | Your key's per-minute and concurrency limits. |
In Python, client.chat.completions.with_raw_response.create(...) gives you the headers.
Models
GET /v1/models lists vllm-sr/auto, the one model name you call. The pool behind it can change; your code does not.
Limits
Each key has its own budget, sized against the measured capacity of the pool so that one agent can run freely. The live values:
| Limit | Value |
|---|---|
| Loading… | |
- Daily quotas reset at 00:00 UTC. Tokens count prompt and output, charged when a request finishes.
- When the whole service is busy, a request waits up to 20 seconds for a free slot before it is answered
429 server_overloaded. - Every 429 carries
Retry-Afterin seconds. Back off and retry; do not open more keys to get around a limit.
Errors
Errors use the OpenAI shape: {"error": {"message", "type", "code"}}.
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_request | A malformed body, or a request the model rejects. |
| 401 | missing_api_key · invalid_api_key | No key, or an unknown or revoked key. |
| 403 | key_disabled · access_denied | The key was disabled by an operator, or the network is blocked. |
| 404 · 405 | not_found · method_not_allowed | An endpoint or method that is not published. |
| 413 | request_too_large | The body is over the size limit. |
| 429 | rate_limit_exceeded | The key's (or network's) requests or tokens per minute. |
| 429 | concurrency_limit | Too many requests at once for the key or network. |
| 429 | quota_exceeded | The key's daily requests or tokens; resets 00:00 UTC. |
| 429 | server_overloaded | The pool is at capacity; retry after Retry-After. |
| 502 · 503 | upstream_unavailable · unavailable | A model or the key service did not answer; retry shortly. |
Keys API
The site uses these endpoints; you can call them too. Key-authenticated endpoints take the key in X-API-Key.
| Request | What it does |
|---|---|
| POST /pt/api/keys/challenge | A proof-of-work challenge: find a decimal nonce such that SHA-256 of challenge + ":" + nonce starts with difficulty zero bits. Single use, valid 10 minutes. |
| POST /pt/api/keys | {"challenge", "nonce", "label", "accept_terms": true} → 201 {"api_key", "key_id", ...}. The key is shown once. |
| GET /pt/api/keys/self | The key's status, limits and today's usage. |
| GET /pt/api/keys/self/usage | 30 days by day, today by hour, routed models, latency and quota. |
| DELETE /pt/api/keys/self | Revoke key: it stops at once; its data is kept. |
| POST /pt/api/keys/self/forget | Delete key and its data: revokes it and deletes its logged requests and responses and its usage records. |
| GET /pt/api/info · /pt/api/status · /pt/api/stats | Models and limits; service status; aggregated usage. No key needed. |
Data and logging
Requests and responses are logged and kept to operate, secure, debug, analyse and improve the service, including the routing, and to train and evaluate models. No request header turns logging off. Do not send secrets, credentials or sensitive personal data. IP addresses are kept for up to 30 days. The privacy notice has the details, and the terms of use apply.