Harness gateway
OpenAI, Anthropic, Codex, model discovery, streaming, and airplane-mode local workers.
OpenAI-, Anthropic-, and Codex-compatible model calls, model discovery, streaming, and airplane-mode local workers. Use the endpoint returned by GET /v1/teams/{team} — production default https://gateway.s46.dev.
Route inventory
| Method | Route | Purpose |
|---|---|---|
GET | /v1/models | OpenAI-style model list. |
POST | /v1/responses | OpenAI Responses-compatible request. |
POST | /v1/chat/completions | OpenAI Chat Completions-compatible request. |
GET | /anthropic/v1/models | Anthropic-style model list. |
POST | /anthropic/v1/messages | Anthropic Messages-compatible request. |
GET | /codex/v1/models | Codex/OpenAI-style model list. |
POST | /codex/v1/responses | Codex Responses-compatible request. |
GET | /v1/workers · /v1/workers/{id} | Airplane-mode local worker discovery. |
The gateway also exposes GET /healthz, GET /readyz, and GET /debug/vars — see Operations.
Chat completions
OpenAI Chat Completions-compatible. Omit model to use the team default. Set "stream": true for text/event-stream chunks that terminate with [DONE].
curl -X POST https://gateway.s46.dev/v1/chat/completions \
-H "Authorization: Bearer $S46_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "s46/devstral-small-2-24b",
"messages": [
{ "role": "user", "content": "Write a short status update." }
]
}'// Drop-in for the OpenAI SDK — swap the base URL.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: accessToken,
baseURL: "https://gateway.s46.dev/v1",
});
const completion = await client.chat.completions.create({
model: "s46/devstral-small-2-24b",
messages: [{ role: "user", content: "Write a short status update." }],
});from openai import OpenAI
client = OpenAI(api_key=access_token,
base_url="https://gateway.s46.dev/v1")
completion = client.chat.completions.create(
model="s46/devstral-small-2-24b",
messages=[{"role": "user", "content": "Write a short status update."}],
)Responses & Codex
OpenAI Responses-compatible request/response shapes. Codex routes use the same shapes. Streaming requests set "stream": true and receive OpenAI Responses-style events.
curl -X POST https://gateway.s46.dev/v1/responses \
-H "Authorization: Bearer $S46_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "s46/devstral-small-2-24b",
"input": "Write a short status update.",
"stream": false
}'const res = await fetch("https://gateway.s46.dev/v1/responses", {
method: "POST",
headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
body: JSON.stringify({
model: "s46/devstral-small-2-24b",
input: "Write a short status update.",
stream: false,
}),
}).then((r) => r.json());res = requests.post(
"https://gateway.s46.dev/v1/responses",
headers={"Authorization": f"Bearer {access_token}"},
json={"model": "s46/devstral-small-2-24b",
"input": "Write a short status update.", "stream": False},
).json()Anthropic Messages
Anthropic Messages-compatible. The local llama.cpp adapter supports Anthropic tools, tool_choice, tool_use, and tool_result by normalizing them through an internal OpenAI-compatible tool-call representation.
curl -X POST https://gateway.s46.dev/anthropic/v1/messages \
-H "Authorization: Bearer $S46_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "s46/devstral-small-2-24b",
"max_tokens": 512,
"messages": [
{ "role": "user", "content": [ { "type": "text", "text": "Write a short status update." } ] }
]
}'const msg = await fetch("https://gateway.s46.dev/anthropic/v1/messages", {
method: "POST",
headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
body: JSON.stringify({
model: "s46/devstral-small-2-24b",
max_tokens: 512,
messages: [{ role: "user", content: [{ type: "text", text: "Write a short status update." }] }],
}),
}).then((r) => r.json());msg = requests.post(
"https://gateway.s46.dev/anthropic/v1/messages",
headers={"Authorization": f"Bearer {access_token}"},
json={
"model": "s46/devstral-small-2-24b",
"max_tokens": 512,
"messages": [{"role": "user", "content": [{"type": "text", "text": "Write a short status update."}]}],
},
).json()Model discovery
GET /v1/models and /codex/v1/models return an OpenAI-shaped list; /anthropic/v1/models returns the Anthropic shape.
curl https://gateway.s46.dev/v1/models \
-H "Authorization: Bearer $S46_ACCESS_TOKEN"const { data } = await fetch("https://gateway.s46.dev/v1/models", {
headers: { Authorization: `Bearer ${accessToken}` },
}).then((r) => r.json());models = requests.get("https://gateway.s46.dev/v1/models",
headers={"Authorization": f"Bearer {access_token}"}).json(){
"object": "list",
"data": [
{
"id": "s46/devstral-small-2-24b",
"object": "model",
"created": 1893456000,
"owned_by": "sovereign46",
"metadata": {
"displayName": "Devstral Small 2 24B",
"certified": true,
"published": true,
"verificationState": "trusted"
}
}
]
}{
"data": [
{ "id": "s46/devstral-small-2-24b", "type": "model", "display_name": "Devstral Small 2 24B" }
],
"has_more": false
}Policy & availability failures
| Status | Code | Meaning |
|---|---|---|
403 | model_not_allowed | Requested model is not certified/allowed for the caller's team. |
429 | rate_limited | Per-IP stream/request rate limit exceeded. |
503 | model_unavailable | Model is allowed but no upstream/local serving path is available. |
Airplane-mode workers
Discover local workers. Current id: local-llamacpp. Worker states: not_configured, unavailable, unhealthy, model_missing, ready. When configured, requests using the s46 model id are rewritten to the backend alias and proxied to llama-server; max tokens are clamped to local config.
curl https://gateway.s46.dev/v1/workers \
-H "Authorization: Bearer $S46_ACCESS_TOKEN"const { workers } = await fetch("https://gateway.s46.dev/v1/workers", {
headers: { Authorization: `Bearer ${accessToken}` },
}).then((r) => r.json());workers = requests.get("https://gateway.s46.dev/v1/workers",
headers={"Authorization": f"Bearer {access_token}"}).json(){
"workers": [
{
"id": "local-llamacpp",
"mode": "airplane",
"kind": "local",
"protocol": "openai-compatible",
"state": "ready",
"models": [
{ "id": "s46/devstral-small-2-24b", "backendModel": "devstral-small-2:24b-instruct-2512-q4_K_M", "state": "ready" }
],
"capabilities": ["chat", "code", "streaming", "tools"]
}
]
}Upstream proxy behavior
When upstream URLs are configured, the gateway proxies compatible requests without forwarding the caller's Authorization header or cookies. If S46_UPSTREAM_BEARER_TOKEN is set, that token is sent upstream.
| Route group | Upstream setting | Prefix behavior |
|---|---|---|
/v1/* | S46_OPENAI_UPSTREAM_URL | Preserves /v1/*. |
/anthropic/* | S46_ANTHROPIC_UPSTREAM_URL | Strips /anthropic, after local-model handling. |
/codex/* | S46_CODEX_UPSTREAM_URL | Strips /codex before forwarding. |