The Milgram proxy is a transparent proxy for model provider APIs. A client keeps talking to the API it already speaks (Anthropic Messages, OpenAI Chat Completions or Responses, Gemini, OpenRouter, Moonshot); only its base URL changes, so it reaches the provider through Milgram. Milgram inspects the request, forwards it, inspects the response on its way back, and records both.
Two changes to any client
Section titled “Two changes to any client”-
Base URL. Replace the provider’s address with the matching proxy path:
https://api.milgram.dev/v1/proxy/<provider> -
API key header. Add your Milgram API key as a header:
X-Milgram-API-Key: mlg_…
Your provider credential does not change: whatever the client sends to authenticate with the provider (an API key, or the token of a subscription login) is forwarded to the provider untouched. The one exception is Kimi’s pay-per-token platform, whose key you store in the console for the proxy to put in place of your Milgram key. The integration pages show both changes for each supported client.
Providers
Section titled “Providers”| Path | Forwards to | Typical client |
|---|---|---|
/proxy/anthropic |
Anthropic API | Claude Code, the Anthropic SDKs |
/proxy/openai |
OpenAI API (Chat Completions and Responses) | opencode, the OpenAI SDKs, Codex with an API key |
/proxy/chatgpt |
ChatGPT’s Codex backend | Codex signed in with ChatGPT |
/proxy/google |
Gemini API | The Gemini SDKs |
/proxy/google-code-assist |
Gemini Code Assist | Gemini CLI signed in with Google |
/proxy/openrouter |
OpenRouter API | Any OpenAI-compatible client using OpenRouter |
/proxy/moonshot |
Kimi (Moonshot) API | Kimi Code CLI |
Each path takes the provider’s own paths for the endpoints the proxy supports, for example
https://api.milgram.dev/v1/proxy/anthropic/v1/messages. Other provider endpoints (files, batches, embeddings
and so on) are not proxied.
| Path | Supported endpoints |
|---|---|
/proxy/anthropic |
/v1/messages, /v1/messages/count_tokens |
/proxy/openai |
/v1/chat/completions, /v1/responses, /v1/models, /v1/images/* |
/proxy/chatgpt |
/responses, /models, /images/* |
/proxy/google |
/v1beta/models/{model}:generateContent, :streamGenerateContent |
/proxy/google-code-assist |
Gemini CLI’s Code Assist methods |
/proxy/openrouter |
/api/v1/chat/completions |
/proxy/moonshot |
/v1/chat/completions, /v1/models, /v1/usages |
Headers
Section titled “Headers”| Header | Direction | Meaning |
|---|---|---|
X-Milgram-API-Key |
request | Your Milgram API key. Authorization: Bearer mlg_… is also accepted, when the provider’s key travels in another header. |
X-Milgram-Session |
request, optional | Names the session the request belongs to, at most 512 bytes. Without it, Milgram follows the conversation itself. |
X-Milgram-Verdict |
response | clean, flagged or unscanned. On a streamed response that is not held (shadow or log), it can only cover the request: it reads flagged if the request was flagged and unscanned otherwise, and the response’s own findings appear in the console. |
What happens to a flagged request
Section titled “What happens to a flagged request”That depends on the API key’s default action, or on its policies once one is attached (see policy actions).
- Shadow and log (the default is shadow): everything is forwarded and streamed responses arrive as they
are generated. The finding is recorded and reported in
X-Milgram-Verdict. Nothing is ever refused. - Block: a flagged request is refused with
403and never reaches the provider. Enforcing requires inspecting a response before the client sees it, so a blocking key holds streamed responses until they are complete, refuses requests while scanning is unavailable, and withholds with a403any response over 8 MiB or with a single part over 64 KiB. - Mask (policies only): the matched content is replaced with a placeholder, in the request before it is forwarded and in the response before it is delivered.
Start in shadow: it shows what would be flagged on your real traffic, without affecting it. Move a key to blocking once you are satisfied with what you see.
What you see in the console
Section titled “What you see in the console”Every exchange the proxy forwards appears in the console:
- Sessions: each conversation or agent run, turn by turn, with its tool calls and results, and the verdict of each part.
- Samples: every scanned text with its findings (category, severity, where it was found), to review, confirm or correct.
- Overview: flagged events, detections by category and severity, tokens, latency and throughput, recent detections and active sessions.