Setup
burn routes by the first path segment. A request to /openai/v1/chat/completions goes to the configured OpenAI URL with /v1/chat/completions appended. The query string is preserved.
Built-in providers
| Route prefix | Provider | Upstream URL | API format |
|---|---|---|---|
/openai | OpenAI | https://api.openai.com | openai |
/anthropic | Anthropic | https://api.anthropic.com | anthropic |
/openrouter | OpenRouter | https://openrouter.ai/api | openai |
/deepseek | DeepSeek | https://api.deepseek.com | openai |
/groq | Groq | https://api.groq.com/openai | openai |
/gemini | Gemini (OpenAI compatibility) | https://generativelanguage.googleapis.com/v1beta/openai | openai |
The formats matter for usage parsing and price matching. openai reads prompt_tokens, completion_tokens, cached-token details, and reasoning-token details. anthropic reads input_tokens, output_tokens, cache_read_input_tokens, and cache_creation_input_tokens.
OpenAI
Start the proxy, then set the base URL in your OpenAI client:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://127.0.0.1:8787/openai/v1',
});The SDK still reads OPENAI_API_KEY from the environment. burn forwards the authorization header upstream without reading or storing it.
Anthropic
The Anthropic SDK appends /v1/messages, so the base URL stops at /anthropic:
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
baseURL: 'http://127.0.0.1:8787/anthropic',
});If you add /v1 here, requests will go to /anthropic/v1/v1/messages and the provider will return a 404.
Other providers
Any endpoint that speaks the OpenAI chat completions format can be routed through burn. Add it once:
burn provider add local http://127.0.0.1:11434/v1 openaiThen point the client at the new route:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://127.0.0.1:8787/local/v1',
});The same works for vLLM, LM Studio, a gateway, or a provider that exposes an OpenAI-compatible endpoint. Use anthropic as the format for an endpoint that speaks the Anthropic messages API:
burn provider add my-gateway https://gateway.example.com anthropicburn run
burn run avoids setting environment variables by hand. It starts a proxy on an ephemeral port, sets the OpenAI and Anthropic base URLs for the child process, runs the command, closes the proxy, and prints a summary:
burn run -- node ./agent.jsEverything after -- is the command. The command inherits its normal environment plus:
OPENAI_BASE_URL=http://127.0.0.1:<random-port>/openai/v1
ANTHROPIC_BASE_URL=http://127.0.0.1:<random-port>/anthropicThe child process exit code becomes burn's exit code. If nothing was logged, burn prints a hint to check that the SDK picked up the base URL. The proxy exists only for that command, so a long-running editor or server process should use burn proxy instead.
burn env
burn env prints the export lines without starting a proxy:
burn envexport OPENAI_BASE_URL=http://127.0.0.1:8787/openai/v1
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787/anthropicIt accepts --port when your proxy is on a different port:
burn env --port 8788Paste the lines into your shell, or use eval "$(burn env)" in a POSIX shell. The command does not modify your shell by itself.
Tagging requests
Send an x-burn-tag header and the row is tagged:
const client = new OpenAI({
baseURL: 'http://127.0.0.1:8787/openai/v1',
defaultHeaders: { 'x-burn-tag': 'nightly-evals' },
});Or with fetch:
await fetch('http://127.0.0.1:8787/openai/v1/chat/completions', {
method: 'POST',
headers: {
'content-type': 'application/json',
authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
'x-burn-tag': 'nightly-evals',
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'Hello' }],
}),
});The tag is stored on the row, truncated to 200 characters, and stripped before the request goes upstream. Group by it with:
burn by-tag --since 7dAdding a provider
burn provider add <name> <url> [openai|anthropic]namemust be a single path segment: letters, digits, dots, dashes, and underscores. It becomes the first path segment of the local route.urlmust start withhttp://orhttps://. Trailing slashes are removed.- The format is optional and defaults to
openai.
List the providers burn knows about:
burn providerThe list shows the built-in providers and the ones in your config, with a source column that says built in or yours.
Remove a custom provider:
burn provider remove <name>Built-in providers cannot be removed with this command. Add a custom entry with the same name to override one, or use a different name for your route.
Starting the proxy
$ npx @xnah/burn proxyIf the proxy is already running in another terminal, do not start a second one on the same port. Use --port for a second instance, or stop the first one with Ctrl+C.