nyx

Key to first token in about a minute

Nyx is one OpenAI-compatible endpoint in front of fourteen open-weight models. Point your existing SDK at https://nyxprovider.com/v1, keep every line of request code you already have, and stream tokens with 71µs median routing overhead. Everything on this page runs against production.

Overview

Nyx serves open-weight models behind the OpenAI chat completions schema. There is one base URL for every model, every region, and every plan:

https://nyxprovider.com/v1

Every official OpenAI SDK works unchanged. Set base_url to https://nyxprovider.com/v1, pass a Nyx key, and pick a model id from the catalog. The router adds 71µs at p50 and 235µs at p99 between your request and the model server, and prices for all fourteen models are published live at /v1/models, so a client can read them programmatically before sending a single prompt.

  • POST /v1/chat/completions, streaming and non-streaming, on every model.
  • GET /v1/models, the catalog with per-token prices in the response body.
  • Prompt caching bills repeated prefixes at the cached rate automatically, with no request changes.
  • Token usage arrives in the final chunk of every streamed response.

Authentication

Requests authenticate with a bearer token in the Authorization header. Keys start with nyx_sk_ and are shown once at creation. A key is scoped to your account, works on every model, and can be revoked from the console without affecting other keys.

auth.sh
# any authenticated request, here the model catalog
curl https://nyxprovider.com/v1/models \
  -H "Authorization: Bearer nyx_sk_live_8f2ac41d77e09b63"

Keys belong on servers only. Never embed one in a browser bundle, a mobile app, or a public notebook. Anyone holding the key can spend against your account until you revoke it, so route browser and mobile traffic through your own backend and keep the key in an environment variable there.

Chat completions

POST /v1/chat/completions takes the OpenAI request body: a model id, a messages array, and optional sampling parameters. The response schema matches OpenAI's field for field, so response parsing, retry wrappers, and logging middleware you already run keep working.

chat.sh
curl https://nyxprovider.com/v1/chat/completions \
  -H "Authorization: Bearer $NYX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-120b",
    "stream": true,
    "max_tokens": 400,
    "messages": [
      {"role": "system", "content": "Answer in two sentences."},
      {"role": "user", "content": "Why does KV cache reuse cut latency?"}
    ]
  }'

Parameters

ParameterTypeNotes
modelstring, requiredA model id from /v1/models, for example gpt-oss-120b or kimi-k3.
messagesarray, requiredChat turns with role and content, OpenAI schema.
streambooleanDefaults to false. Set true for server-sent events.
max_tokensintegerHard cap on generated tokens. Defaults to the model's context limit minus the prompt.
temperaturenumber0 to 2, defaults to 1.0. Lower is more deterministic.

Streaming

With stream: true the response is server-sent events, relayed byte for byte. The router never buffers, reframes, or batches chunks: the bytes the model server emits are the bytes your client reads, which is why time-to-first-token on Nyx tracks the model itself rather than the proxy in front of it.

stream.py
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://nyxprovider.com/v1",
    api_key=os.environ["NYX_API_KEY"],
)

stream = client.chat.completions.create(
    model="gpt-oss-120b",
    stream=True,
    messages=[{"role": "user", "content": "Explain SSE in one paragraph."}],
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

The final data event before the stream closes is the literal sentinel data: [DONE], exactly as OpenAI sends it. SDKs handle it for you; if you parse SSE by hand, stop reading when you see it. Usage counts arrive in the last JSON chunk before the sentinel.

List models

GET /v1/models returns every model currently routable, with context length and the live per-million-token price in the same response. The price in this endpoint is the price you are billed, and the pricing page renders from the same data.

GET /v1/models
{
  "object": "list",
  "data": [
    {
      "id": "gpt-oss-120b",
      "object": "model",
      "context_length": 131072,
      "pricing": {
        "input_per_mtok": 0.0273,
        "output_per_mtok": 0.1547
      }
    },
    {
      "id": "kimi-k3",
      "object": "model",
      "context_length": 1000000,
      "pricing": {
        "input_per_mtok": 2.548,
        "output_per_mtok": 12.74
      }
    }
    // ... 8 more models, trimmed here
  ]
}

The endpoint needs no authentication for reads, so a deploy pipeline can verify a model id exists before shipping, and a cost dashboard can poll current prices without holding a key.

Errors

Errors use standard HTTP status codes with an OpenAI-shaped JSON body containing error.message and error.type.

StatusMeaningWhat to do
400Invalid request body or parameters.Fix the request. The message names the offending field.
401Missing, malformed, or revoked key.Check the Authorization header and the key in your console.
404Unknown model id.Pick an id from GET /v1/models.
429Over declared capacity.Wait the number of seconds in the Retry-After header, then retry.
500Upstream model server fault.Retry with backoff. These are rare and counted against our uptime.

Backpressure is honest. When a model is at its declared capacity, Nyx returns 429 immediately, in microseconds, with a Retry-After header. It never accepts the request into a hidden queue that times out 30 seconds later, so your retry logic sees the real state of the fleet the moment it exists and a slow failure never masquerades as a slow success.

SDKs

There is no Nyx SDK to install, on purpose. The official OpenAI libraries for Python and JavaScript are the supported clients, and any OpenAI-compatible client, framework, or gateway works by changing the base URL and key.

setup.py
# pip install openai
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://nyxprovider.com/v1",
    api_key=os.environ["NYX_API_KEY"],
)

r = client.chat.completions.create(
    model="deepseek-v3.2",
    messages=[{"role": "user", "content": "Say hello."}],
)
print(r.choices[0].message.content)
setup.mjs
// npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://nyxprovider.com/v1",
  apiKey: process.env.NYX_API_KEY,
});

const r = await client.chat.completions.create({
  model: "qwen3-coder-next",
  messages: [{ role: "user", content: "Say hello." }],
});
console.log(r.choices[0].message.content);

LangChain, LlamaIndex, Vercel AI SDK, LiteLLM, and curl all speak this protocol already. If a tool accepts an OpenAI base URL, it runs on Nyx with no adapter.

Start building on Nyx

One endpoint, open models, prices under every listing. Your first key takes about a minute.