Docs
Point your agent at one endpoint.
Vynaris is an OpenAI-compatible chat completions gateway at https://api.vynaris.com/v1. Swap the base URL in whatever client you already use, keep your prompts and tool definitions, and read the receipt on every response.
Quickstart
Three steps.
Get a key
Sign in at app.vynaris.com/signin and copy your key. It looks like vyn_sk_live_… and is shown once, at creation — save it somewhere safe.
Set the base URL
Point your client’s base_url at https://api.vynaris.com/v1 (OpenAI-shaped clients) or https://api.vynaris.com (Anthropic SDK). Nothing else in your stack changes.
Send a request
Set model to auto and let the router pick, or send a frontier model name and it gets right-sized with a receipt.
Every snippet below uses the placeholder key vyn_sk_live_XXXX. Real keys come from your dashboard’s API keys page.
Harness
curl
The rawest possible integration — useful for verifying a key works before wiring up an SDK.
curl https://api.vynaris.com/v1/chat/completions \
-H "Authorization: Bearer vyn_sk_live_XXXX" \
-H "Content-Type: application/json" \
-d '{"model": "auto", "messages": [{"role": "user", "content": "Say hi in five words."}]}'Harness
OpenAI SDK (Python)
Change base_url and api_key; every other call in your codebase is unchanged.
from openai import OpenAI
client = OpenAI(base_url="https://api.vynaris.com/v1", api_key="vyn_sk_live_XXXX")
resp = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Say hi in five words."}],
)
print(resp.choices[0].message.content)Harness
OpenAI SDK (TypeScript)
Same swap in the TypeScript client — set baseURL and apiKey when constructing the client.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.vynaris.com/v1",
apiKey: "vyn_sk_live_XXXX",
});
const resp = await client.chat.completions.create({
model: "auto",
messages: [{ role: "user", content: "Say hi in five words." }],
});
console.log(resp.choices[0].message.content);Harness
Anthropic SDK (Python)
The Anthropic SDK works against base_url=https://api.vynaris.com for the client construction shown below. Note: Vynaris’s native /v1/messages wire format is not yet implemented — route Anthropic-shaped traffic through the OpenAI-compatible /v1/chat/completions endpoint documented above until that lands.
import anthropic
client = anthropic.Anthropic(base_url="https://api.vynaris.com", auth_token="vyn_sk_live_XXXX")
msg = client.messages.create(
model="auto", max_tokens=64,
messages=[{"role": "user", "content": "Say hi in five words."}],
)
print(msg.content)Harness
Claude Code
Claude Code reads its endpoint from environment variables. This wires it to Vynaris for the current shell session; because /v1/messages is not yet implemented, treat this as environment setup for future compatibility rather than a guarantee that every Claude Code call is served today.
export ANTHROPIC_BASE_URL=https://api.vynaris.com export ANTHROPIC_AUTH_TOKEN=vyn_sk_live_XXXX claude
Harness
Cursor
Add Vynaris as a custom OpenAI-compatible provider in Cursor’s model settings.
# Cursor → Settings → Models → API keys # OpenAI API key: vyn_sk_live_XXXX # Override base URL: https://api.vynaris.com/v1 # Then pick any model and send a chat message.
Harness
Hermes (hermes-agent)
NousResearch’s hermes-agent uses named custom providers in ~/.hermes/config.yaml — note that OPENAI_BASE_URL does not apply to custom providers, and keys belong in an env var via key_env, never in the file. Switch models at runtime with /model custom:vynaris:auto.
# Hermes (NousResearch hermes-agent) — add Vynaris as a custom provider.
# Note: OPENAI_BASE_URL does NOT apply to custom providers; use config.yaml.
# ~/.hermes/config.yaml
custom_providers:
- name: vynaris
base_url: https://api.vynaris.com/v1
key_env: VYNARIS_KEY # keys never live in config.yaml
api_mode: chat_completions
model:
default: custom:vynaris:auto # or /model custom:vynaris:auto at runtime
# shell
export VYNARIS_KEY=vyn_sk_live_XXXX
hermes --tuiHarness
OpenClaw
Add Vynaris as a custom provider in ~/.openclaw/openclaw.json with "api": "openai-completions", then select vynaris/auto as your model.
// OpenClaw → add Vynaris as a custom provider
// (~/.openclaw/openclaw.json, then pick "vynaris/auto" as your model)
{
"models": {
"providers": {
"vynaris": {
"baseUrl": "https://api.vynaris.com/v1",
"apiKey": "vyn_sk_live_XXXX",
"api": "openai-completions",
"models": [{ "id": "auto", "name": "Vynaris auto-route" }]
}
}
}
}Harness
Pi coding agent
Pi (badlogic/pi-mono) reads custom providers from ~/.pi/agent/models.json, hot-reloaded when you open /model. Use a distinct key env var: Pi’s precedence rules let OPENAI_API_KEY silently override config-file keys. For any other harness: base URL + key wherever it configures its provider, then verify with /v1/ping.
// Pi coding agent (badlogic/pi-mono) — ~/.pi/agent/models.json
// Reloads automatically when you open /model — no restart needed.
{
"providers": {
"vynaris": {
"baseUrl": "https://api.vynaris.com/v1",
"api": "openai-completions",
"apiKey": "$VYNARIS_KEY",
"models": [
{ "id": "auto", "name": "Vynaris Auto",
"input": ["text"], "contextWindow": 128000, "maxTokens": 16384 }
]
}
}
}
// shell — use a distinct env name: Pi lets OPENAI_API_KEY override
// models.json keys, so don't reuse it for Vynaris.
// export VYNARIS_KEY=vyn_sk_live_XXXX
// then pick the model via /model → vynaris → autoReading your receipt
Every response carries its own receipt.
Every response body includes a vynaris block, and the same facts ride back as x-vynaris-* response headers so you can read them without parsing the body.
{
"id": "chatcmpl-8f2a91",
"choices": [ { "message": { "role": "assistant", "content": "..." } } ],
"vynaris": {
"request_id": "req_8f2a91",
"requested_model": "gpt-4o",
"served_model": "qwen3-8b-ft",
"cost_usd": "0.000418",
"direct_equivalent_usd": "0.01820000"
}
}x-vynaris-request-id: req_8f2a91 x-vynaris-served-model: qwen3-8b-ft x-vynaris-cost-usd: 0.000418 x-vynaris-baseline-usd: 0.0182 x-vynaris-saved: 98%
direct_equivalent_usd is what the requested_model would have cost at list price for the same tokens — the number the savings percentage is computed from.
Errors
What can go wrong, and what to do about it.
Missing, malformed, or revoked key. The error message names the specific problem (e.g. “key revoked” vs. “no key provided”) instead of a generic auth failure.
Your balance (or this key’s spend cap) hit zero. Nothing was sent upstream and nothing was charged. This is terminal for the request — do not retry it.Top up or raise the key’s cap, then send a new request.
The served model’s provider failed or timed out. You were not charged for a failed upstream call. Safe to retry.
Balance & usage APIs
Query your balance and request history.
Both endpoints take the same Authorization: Bearer key as the chat completions endpoint.
- GET /v1/ping — verifies connectivity and that the key is valid. Returns quickly with no charge.
- GET /v1/usage — current balance and aggregate usage for the authenticated account.
- GET /v1/ledger — per-request history: request id, requested and served model, cost, and direct-equivalent cost for each call.
curl https://api.vynaris.com/v1/ping -H "Authorization: Bearer vyn_sk_live_XXXX"
curl https://api.vynaris.com/v1/usage -H "Authorization: Bearer vyn_sk_live_XXXX"
curl https://api.vynaris.com/v1/ledger -H "Authorization: Bearer vyn_sk_live_XXXX"