DevPlace OpenAI-Compatible Gateway
The OpenAI-compatible proxy at /openai/v1: chat completions and streaming, the generic molodetz model names, embeddings, vision augmentation that rewrites images to text, forced-model behaviour, and per-call usage and cost accounting.
An OpenAI-compatible proxy mounted at /openai/v1. It forwards requests to a configured upstream using the gateway's own credentials, so no DevPlace key is required - but an administrator must enable the openai service first. Point any OpenAI-compatible client at https://devplace.net/openai/v1.
This gateway is the single point of truth for AI on the platform. Every other DevPlace service (news, bots, Devii) calls it by default instead of an external provider, sends the generic model name molodetz, and authenticates with an internal key that is auto-generated on first boot. The real provider URLs, models, and keys (DeepSeek, OpenRouter) live only here, so an operator switches providers or backends in one place. DEEPSEEKAPIKEY and OPENROUTERAPIKEY are migrated into the editable settings on boot and the value in use is shown. Because Force model is on by default, the upstream always receives the configured model regardless of what a client (or molodetz) requests.
The gateway also performs vision augmentation: when a request includes an image, the gateway describes the image with a configured vision model and rewrites it to text, so a vision-less upstream still works. The vision model, URL, and key are configured alongside the other gateway settings.
The gateway additionally serves text embeddings at /openai/v1/embeddings. Clients request the generic model molodetz~embed, which the gateway maps to the configured embedding model (OpenRouter's Qwen3 8B embedding model by default). Usage and cost are tracked per call exactly like chat and vision.
The gateway also serves image generation at /openai/v1/images/generations. Clients request the generic model molodetz-img-small, which the gateway maps to the configured image model (OpenRouter's Flux 1.1 Pro by default). Cost is tracked per call with a flat per-image price when the upstream returns no native cost.
Quick start
Copy the command below and paste it into a terminal. If you are signed in the 63995001-2291-45bf-9fe3-45dae21cfcee and user-retoor-app-v-1-0-0 placeholders are already filled in with your own values; otherwise replace them with the API key from your profile page and any application identifier.
curl -X POST "https://devplace.net/openai/v1/chat/completions" -H "Authorization: Bearer 63995001-2291-45bf-9fe3-45dae21cfcee" -H "X-App-Reference: user-retoor-app-v-1-0-0" -H "Content-Type: application/json" -d '{
"model": "molodetz",
"messages": [{"role": "user", "content": "Hello, how are you?"}]
}'
The response carries X-Gateway-* headers with token counts and dollar cost for the call. For streaming, add "stream": true to the JSON body.
Model routing and providers
On top of the single default upstream above, an administrator can register additional named providers and map any number of requested model names onto them, so one gateway can front many models across many backends. A model route binds a source model name (what a client sends) to a target provider and upstream model, and carries:
- its own pricing economy (input, output, and cache-hit / cache-miss prices per million tokens),
- an optional vision model, which turns on the image-to-text merge for that route (so a text-only
- an optional context window used for the context-utilization header.
used to compute that call's cost when the upstream returns no native cost;
model can answer about images);
Resolution is transparent to clients: when the requested model matches an active route, the gateway forwards to that route's provider and target model and meters the call against the route's economy. When it matches no route, the request falls through to the default upstream unchanged (so molodetz, molodetz~embed, and any existing client keep working exactly as before). Providers and routes are managed by administrators on the Gateway page (/admin/gateway).
Per-call cost and usage headers
Every gateway response - chat, embeddings, and passthrough, on both success and error - carries X-Gateway-* response headers describing that single call, so a client can read its own token usage and dollar cost directly from the response with no extra request:
| Header | Meaning |
|---|---|
X-Gateway-Model | Upstream model actually used for the call |
X-Gateway-Backend | Backend that served it: chat, embed, image, or passthrough |
X-Gateway-Prompt-Tokens | Input (prompt) tokens |
X-Gateway-Completion-Tokens | Output (completion) tokens |
X-Gateway-Total-Tokens | Total tokens (prompt + completion) |
X-Gateway-Cache-Hit-Tokens | Prompt tokens served from the upstream prompt cache |
X-Gateway-Cache-Miss-Tokens | Prompt tokens not served from cache |
X-Gateway-Reasoning-Tokens | Reasoning tokens, when the model reports them |
X-Gateway-Cost-USD | Total cost of the call in US dollars |
X-Gateway-Input-Cost-USD | Input portion of the cost in US dollars |
X-Gateway-Output-Cost-USD | Output portion of the cost in US dollars |
X-Gateway-Cost-Native | 1 if the dollar cost is the upstream's own reported cost, 0 if computed from the configured per-million pricing |
X-Gateway-Tokens-Per-Second | Output tokens per second for the call |
X-Gateway-Upstream-Latency-Ms | Upstream round-trip latency in milliseconds |
X-Gateway-Total-Latency-Ms | Full end-to-end gateway time for the call in milliseconds |
X-Gateway-Gateway-Overhead-Ms | Gateway processing time minus the upstream and queue wait, in milliseconds |
X-Gateway-Queue-Wait-Ms | Time spent waiting on the concurrency semaphore before dispatch, in milliseconds |
X-Gateway-Connect-Ms | Upstream connection establishment time in milliseconds |
X-Gateway-Context-Window | The model's context window in tokens, when known |
X-Gateway-Context-Utilization | Total tokens as a fraction of the context window, when known |
Dollar costs use the upstream's native cost field when it returns one (X-Gateway-Cost-Native: 1); otherwise they are computed from the per-million prices of the matched model route, falling back to the prices configured on the openai service when no route matches. The denied paths that make no upstream call (embeddings or image generation disabled) return no usage headers.
Request header X-App-Reference
Clients SHOULD send an X-App-Reference header to identify themselves for cost attribution. The value is a free-form slug (max 30 characters, letters, digits, _, ., -). When missing or invalid, the gateway defaults to default. The value is recorded in every usage ledger row and can be queried alongside owner-kind and owner-id to attribute spending per application.
X-App-Reference: devplace-devii-v-1-0-0
Administrators enable and configure this gateway under Background Services (the openai service).
The gateway is exempt from rate limiting, but every other endpoint follows the shared Conventions & Errors; see Authentication for signing DevPlace's own requests.
POST /openai/v1/chat/completions - Chat completions
OpenAI-compatible chat completion. Supports streaming.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
model | json | string | no | Model id. When it matches a configured model route the gateway forwards to that route's provider and upstream model; otherwise it falls back to the configured default upstream model. |
messages | json | string | yes | Chat messages array. |
stream | json | string | no | Set true for a streamed SSE response. |
Returns
503when the gateway service is not running.
Every response carries the
X-Gateway-*token and dollar-cost headers (see Per-call cost and usage headers above), including the streamed SSE response.
If
modelmatches a configured model route it is forwarded to that route's provider, upstream model, and per-model pricing (with an optional vision model); otherwise it falls through to the default upstream (see Model routing and providers above).
POST /openai/v1/embeddings - Embeddings
OpenAI-compatible text embeddings. Request model molodetz~embed.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
model | json | string | no | Embedding model id; the gateway maps molodetz~embed to the configured model, or to a matching embed model route's provider and target model. |
input | json | string | yes | String or array of strings to embed. |
dimensions | json | string | no | Optional output vector size (Matryoshka, 32-4096). |
Returns
503when the gateway service is not running or embeddings are disabled.
Every response carries the
X-Gateway-*token and dollar-cost headers (see Per-call cost and usage headers above).
If
modelmatches a configured embed model route it is forwarded to that route's provider and upstream model; otherwise it falls back to the configured default embedding model.
POST /openai/v1/images/generations - Image generation
OpenAI-compatible image generation. Request model molodetz-img-small.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
model | json | string | no | Image model id; the gateway maps molodetz-img-small to the configured model, or to a matching image model route's provider and target model. |
prompt | json | string | yes | Text prompt describing the image to generate. |
size | json | string | no | Output dimensions (provider-dependent). |
response_format | json | string | no | Return format: url or b64_json. |
Returns
503when the gateway service is not running or image generation is disabled.
Every response carries the
X-Gateway-*token and dollar-cost headers (see Per-call cost and usage headers above).
If
modelmatches a configured image model route it is forwarded to that route's provider and upstream model; otherwise it falls back to the configured default image model.
POST /openai/v1/{path} - Passthrough
Any other /v1 path is forwarded to the upstream as-is.
Minimal role: Member
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
path | path | string | yes | Upstream API path after /v1/. |