Skip to main content
Nemu sits between your application and the model providers you have connected. You send one gateway key; Nemu resolves the model, picks the provider credential, applies your mappings, quotas and budgets, records the request, and forwards it upstream. Provider keys never leave the console.

Base URLs

Anthropic clients append /v1/messages to whatever base URL you give them, so https://api.nemu.cc works as an Anthropic base URL too: both https://api.nemu.cc/v1/messages and https://api.nemu.cc/anthropic/v1/messages serve the Messages API.

Authentication

Send the gateway key either way. Anthropic clients tend to use x-api-key, OpenAI clients use the bearer header, and Nemu accepts both on every endpoint.
Keys are created in the console and look like sk_xxxxx-xxxxx. followed by a 40 character secret. A key belongs to one workspace and can only reach the providers and models enabled in that workspace.

Endpoints

Liveness and readiness

GET /health answers whether the gateway process is up. It reads nothing and depends on nothing, so it stays fast and stays honest about one thing only.
GET /ready additionally checks that the gateway can reach its database and its cache, within a two second budget. It answers 200 with "status": "ok" when both respond and 503 with "status": "degraded" when either does not or is too slow. Use /health to ask whether the process is alive and /ready to ask whether it can serve a request. commit is the git commit the running build was made from, and it is also returned by GET /v1/health and GET /anthropic/health, which both require a key. version is the release version and moves independently of it.

Choosing a model

GET /v1/models returns exactly the strings you can put in model. Each one is the model’s gateway name: the provider name, a slash, and the alias you gave it in the console.
For models added from the models.dev catalog, the gateway name is yours to choose and is independent of the upstream model id, so anthropic/fable-5.1 can point at claude-fable-5-1 upstream. Edit it under Models in the console. The gateway name is the only model name a client may send. The upstream id is not accepted, so nothing you run can address a provider model that you have not deliberately exposed, and renaming a model in the console changes the name your clients use without touching the provider. Two other values are accepted in model:
  • A mapping. Mappings match a pattern and rewrite it to a gateway name, which is how you keep a client that hardcodes gpt-4o pointed at whatever you want.
  • auto. When automatic routing is configured, Nemu picks the model.

Variants

A gateway name can carry a variant in square brackets, the way some clients write claude-opus-5[1m]. The variant is stripped before the model is resolved, so anthropic/fable-5.1[1m] addresses anthropic/fable-5.1. [1m] asks for a one million token context: it raises the accounted context window and, for Anthropic providers, sends the context-1m-2025-08-07 beta header upstream. The window is only ever raised, never lowered. On a model that already reaches a million tokens, as anthropic/fable-5.1 does, the suffix changes nothing and is accepted anyway. That is the point of it: a client can append [1m] to every model name it sends without keeping track of which models need asking and which already have the context. The beta header still goes upstream on an Anthropic provider even when the model did not need it. Three spellings address the same variant: [1m], [1m-context] and [context-1m]. Case and surrounding spaces are ignored, so [1M] and [ 1m ] both work. Anything else inside the brackets is stripped from the name and then ignored, so anthropic/fable-5.1[turbo] resolves to anthropic/fable-5.1 and asks for nothing rather than failing. The exception is a bracketed string longer than sixteen characters, which is not read as a variant at all: it stays part of the model name, and the lookup then fails because no model is called that.

Compatibility

Nemu speaks three wire protocols on the way in and translates to whatever the upstream provider speaks. An Anthropic-shaped request can be served by an OpenAI-compatible provider and the other way round: system blocks, tool calls, streaming events, thinking blocks and cache breakpoints are converted in both directions. Reasoning is handled per model. Anthropic-style thinking budgets, OpenAI-style reasoning_effort and adaptive modes are mapped to whatever the target model actually supports, so a request that asks for thinking on a model without it succeeds instead of failing with a 400. The full list of what is translated, what comes back and what is dropped is on Any model through any API.

Errors

Every error says which side failed. The x-nemu-error-origin response header is nemu when the gateway stopped the request and provider when the upstream did, so a 402 from your provider’s billing is never confused with a 402 from your nemu budget.
Anthropic endpoints return Anthropic’s {"type":"error","error":{...}} shape with the matching invalid_request_error, authentication_error, not_found_error, rate_limit_error or overloaded_error type. When an upstream provider explains itself, that explanation reaches you in place of the gateway’s own description of the status, whether the provider sends an error object or a plain reason. A reason that only repeats the status, such as Not Found on a 404, is replaced by the fuller description instead. If the provider fails partway through a streamed reply, the tokens it delivered before failing are counted against your quotas and budget, and the request shows under Metrics as failed with that cost. A request that fails before any output costs nothing. Errors that the gateway itself raised end with a reference, as in ... (id: 6f1c2a9e-...). That is the id of the request’s row under Metrics, so a report can be traced to the exact request without guessing.

Limits and accounting

Requests are counted against your plan and against any quota rules and monthly budget set for the workspace. A 429 carries Retry-After and the limit that was hit, so a client can pace itself instead of guessing.

When the gateway is overloaded

Separately from your own limits, the gateway watches the load on the machine it runs on. When processor or memory use stays above 90 percent for a full minute, it stops accepting new requests and answers 529 with an overloaded_error and a Retry-After header. Work already in flight is never interrupted, so a response that has started streaming finishes normally.
If the load has still not cleared after five minutes, new requests are held in a short queue instead of being refused, and admitted as capacity frees up. A request that waits longer than 20 seconds is refused with the same 529, and so is one that arrives when the queue is already full. Retry-After is 10 seconds while requests are being refused and 30 seconds once they are being queued. Both states clear on their own once the machine has been below the threshold for 30 seconds. Live state is published at status.nemu.cc. Request bodies are capped per plan, which matters for coding agents because the whole conversation is resent every turn: Going over returns a 413 naming both the size sent and the limit. Every request lands in Metrics with its model, provider, latency, token counts, cost and origin. Requests that came from nemu’s own chat are labelled as such rather than showing an internal address.

Caching

Providers, models, mappings, prompts and quota rules are cached for speed. Changing any of them in the console or through the management API clears the gateway’s copy immediately, so a rotated provider key takes effect on the next request.