{"_id":"@aaronjmars/openroutercli","_rev":"7-909388919ea8cc2a64b063f21d694f79","name":"@aaronjmars/openroutercli","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.2":{"name":"@aaronjmars/openroutercli","version":"0.1.2","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.1.2","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"684428258911b22721fd44b21b31621b2806e80b","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.1.2.tgz","fileCount":27,"integrity":"sha512-rcTwSNJ0zrDbWLTce1wJQmdk7XTgv6nRAzRpj91ncf0tAQvdSpARX+EY8RSB91dJiklOmBSWx0EFugrnV0aJog==","signatures":[{"sig":"MEUCIGn+Emm3m92KCgG4n2poa7r5I8LhP1fpsuNUUVD4rYQfAiEAgOk/lyArWmCBIzqm7gpl5reA7waK4u1xXtrh+hrXS+o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":250291},"type":"module","engines":{"node":">=20"},"gitHead":"246da008497600bdc3c5c2968f7c278a4a86a98c","scripts":{"start":"node bin/openrouter.js"},"_npmUser":{"name":"aaronjmars","email":"aaronjmars@proton.me"},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"11.7.0","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"24.12.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.1.2_1777478051610_0.41408882124857027","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@aaronjmars/openroutercli","version":"0.1.3","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.1.3","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"95d10509821fbdca73c2bd127e0efe5932daaf88","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.1.3.tgz","fileCount":27,"integrity":"sha512-zCzKcoTTohc5C64EWaRB/uS4D3o8RNjctdnAelAf6uM/9LTpCgwc0XWa+Xq5+AnWEgm2smM7SmqzOquJfNGhtg==","signatures":[{"sig":"MEYCIQDR3qZ46p7ZMPp0RrclQoc54fYjHjxq+PTiNSOWF+LO8AIhALFJsRe9ruJRU1Obn+wmutTSCg86wCyyIh/bry6rOJ82","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":252799},"type":"module","engines":{"node":">=20"},"gitHead":"0060ad5ced1812423eec41c7ac9c4072c5255654","scripts":{"start":"node bin/openrouter.js"},"_npmUser":{"name":"aaronjmars","email":"aaronjmars@proton.me"},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"11.7.0","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"24.12.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.1.3_1783039496310_0.7588373042997003","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@aaronjmars/openroutercli","version":"0.1.4","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.1.4","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"b84a7513dedd19d63f71753fa9c9bcdebd61475b","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.1.4.tgz","fileCount":27,"integrity":"sha512-WTi7GTnOvcwTPeMd3xc7f4sccDlX4dFdj3AkItPxCGWUuByyGywfoz1YSVELpL3IJIGIwrzZh05nXBUXYwhjRA==","signatures":[{"sig":"MEUCIQC0C5OhpFO/annsXfm7ChZYma1/ZaFXoFmQbT72cb2vAgIgAUHIQNGzGvN0Uw+mGKJfD/aRGrx9d6zWyjV96V+Huow=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":251963},"type":"module","engines":{"node":">=20"},"gitHead":"08788e576bba5e75254f276edb680199078c072b","scripts":{"start":"node bin/openrouter.js"},"_npmUser":{"name":"aaronjmars","email":"aaronjmars@proton.me"},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"11.17.0","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"26.5.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.1.4_1784648296559_0.7634783752765151","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@aaronjmars/openroutercli","version":"0.1.6","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.1.6","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"5bb64c8c14a634b0e46b75db6c969e0fbe494d30","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.1.6.tgz","fileCount":27,"integrity":"sha512-FLSdVrVX0UwPbMBvI8BdamGoMOySztHXZ9UMF7tgt5KGTipCZ4eL9h3sLIBv4bYLgNGJ9zrQ6W+7SozP71qujQ==","signatures":[{"sig":"MEYCIQCy44pAmYGyX7XchsvJkyG9YKuJosumKJgdDfGV4CRp/gIhAOiapN5a4vC6kWazzaZ1Pwvq7pNdz2QBgWUQznSKpYBe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aaronjmars%2fopenroutercli@0.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":255899},"type":"module","engines":{"node":">=20"},"gitHead":"2b0750d1e8a6a0f23fe1be66f98b31fc97e2c528","scripts":{"start":"node bin/openrouter.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:81fabc0e-c412-4147-b86c-617ed0ae2566"}},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"12.0.2","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"24.18.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.1.6_1785417180001_0.4516080681949619","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aaronjmars/openroutercli","version":"0.2.0","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.2.0","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"adbf6601f9905c2e3ba245a531f7c63b4ceb4fc9","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.2.0.tgz","fileCount":32,"integrity":"sha512-MNR1G0jaiJIJYUjZKXLWSs/MQtzT+ctEWLEv2Zj9B6gzgmvc8vQxhhbMGKJ8AVeruX5DHRXKBdr1XXF9K+/Kgw==","signatures":[{"sig":"MEQCIGXWrUknR1joi1HigSEu3dFC/ldVRBUJ2hctPlCHHKi9AiAYj1rqjk2eYYJmMG99JB6JA5hUsj73peMf3pvJzLEW9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIBg+d1LucSfCxVzVfbdxDhC+kV2D8bFXSv6KG/cjRZZ+AiB5Re7HqCmBO8R2UiAmgj+v83aydVFZKJV/9i20CzvzLA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aaronjmars%2fopenroutercli@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":288014},"type":"module","engines":{"node":">=20"},"gitHead":"42250846ebdfb13744bd4c2ba181ccf80d26d930","scripts":{"start":"node bin/openrouter.js","format":"biome format --write .","format:check":"biome ci ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:81fabc0e-c412-4147-b86c-617ed0ae2566"}},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"12.0.2","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"24.20.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@biomejs/biome":"^2.5.12"},"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.2.0_1788727505714_0.8599732820467989","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aaronjmars/openroutercli","version":"0.2.1","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"author":{"name":"aaronjmars"},"license":"MIT","_id":"@aaronjmars/openroutercli@0.2.1","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"homepage":"https://github.com/aaronjmars/openroutercli#readme","bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"dist":{"shasum":"6433f5685f906072b407197c6f78519ecf2b1b42","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.2.1.tgz","fileCount":32,"integrity":"sha512-akQlhRbczoltFBqXXhGa70mLLPz4HRwDxCg2hLB4SALcTv4HXdeiGXz7NFqaX7G4Qfc68H75De45LTrGS++Alg==","signatures":[{"sig":"MEUCIB2FBwVDqGKd8iBYbxqvtDD0BySAjzj3MAAvY/vX9o48AiEA0Fx0TYyC+T5B62PUhDa0u4Izg5K1LvHX5W/ZPrniFHo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCkPMvxPTqRj7l2FJe/RQUo7jbfX+1O5NKd6S+z/SxLVwIhAPnjYJ5wtDpoj60F4s0PT6MknoVKzgDeofkb3KrdItPg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aaronjmars%2fopenroutercli@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":291180},"type":"module","engines":{"node":">=20"},"gitHead":"5ac7684a677d2b30afb19769b45b62818e4981c6","scripts":{"start":"node bin/openrouter.js","format":"biome format --write .","format:check":"biome ci ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:81fabc0e-c412-4147-b86c-617ed0ae2566"}},"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"12.0.2","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"_nodeVersion":"24.20.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@biomejs/biome":"^2.5.12"},"_npmOperationalInternal":{"tmp":"tmp/openroutercli_0.2.1_1788728216521_0.8398688618593473","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"_id":"@aaronjmars/openroutercli@0.2.2","bin":{"or":"bin/openrouter.js","openrouter":"bin/openrouter.js"},"bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"dist":{"shasum":"1fc8c18d8934b9b1bb65832794faf405c42633b5","tarball":"https://registry.npmjs.org/@aaronjmars/openroutercli/-/openroutercli-0.2.2.tgz","fileCount":32,"integrity":"sha512-dFD/IifoGXNfkAJKJWdoqJlgaG3kMqcsmzmdfjMhL9FvGf0X0cXLWJQUCUtk/6tyMOo6S4SBnOne1VKMGX/f+w==","signatures":[{"sig":"MEYCIQCt81ntqKr2WG5kiwA4Up92nr9nw5QgQLXV+TGuOhJbVQIhAKPUQNzzNcwZBDYwS3NlE7J5SI3tiX3hiD/p292z7t3M","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHmdAuZSLZ+icOyl71EcbjM9atnG8BtjLuMuvBviZtF7AiBJZSNaC9F9OXVon0vGaA1dj6l05x/DoIxABqFI4HZvFg=="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aaronjmars%2fopenroutercli@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":291176},"name":"@aaronjmars/openroutercli","type":"module","author":{"name":"aaronjmars"},"engines":{"node":">=20"},"gitHead":"732950a8585454bd74244f4621410290f9963a98","license":"MIT","scripts":{"start":"node bin/openrouter.js","format":"biome format --write .","format:check":"biome ci ."},"version":"0.2.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:81fabc0e-c412-4147-b86c-617ed0ae2566"}},"homepage":"https://github.com/aaronjmars/openroutercli#readme","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"_npmVersion":"12.0.2","description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","directories":{},"maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"_nodeVersion":"24.20.0","preferGlobal":true,"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@biomejs/biome":"^2.5.12"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openroutercli_0.2.2_1788728379221_0.6660657117589495"}}},"time":{"created":"2026-04-29T15:54:11.465Z","modified":"2026-09-06T20:59:39.658Z","0.1.2":"2026-04-29T15:54:11.820Z","0.1.3":"2026-07-03T00:44:56.458Z","0.1.4":"2026-07-21T15:38:16.768Z","0.1.6":"2026-07-30T13:13:00.136Z","0.2.0":"2026-09-06T20:45:05.787Z","0.2.1":"2026-09-06T20:56:56.654Z","0.2.2":"2026-09-06T20:59:39.334Z"},"bugs":{"url":"https://github.com/aaronjmars/openroutercli/issues"},"author":{"name":"aaronjmars"},"license":"MIT","homepage":"https://github.com/aaronjmars/openroutercli#readme","keywords":["openrouter","cli","llm","ai","chat","agent","claude","gpt","openai","anthropic","embeddings","tts","rerank","oauth"],"repository":{"url":"git+https://github.com/aaronjmars/openroutercli.git","type":"git"},"description":"Command-line interface for the OpenRouter API. Built for humans and LLM agents.","maintainers":[{"name":"aaronjmars","email":"aaronjmars@proton.me"}],"readme":"<p align=\"center\">\n  <img src=\"./openrouter-logo.jpeg\" alt=\"openrouter-cli\" width=\"120\" />\n</p>\n\n<h1 align=\"center\">openrouter-cli</h1>\n\n<p align=\"center\">\n  <em>Unofficial - not affiliated with or endorsed by OpenRouter.</em>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/@aaronjmars/openroutercli\"><img src=\"https://img.shields.io/npm/v/%40aaronjmars%2Fopenroutercli?style=flat-square&logo=npm&color=cb3837\" alt=\"npm version\"></a>\n  <a href=\"https://www.npmjs.com/package/@aaronjmars/openroutercli\"><img src=\"https://img.shields.io/npm/dm/%40aaronjmars%2Fopenroutercli?style=flat-square&logo=npm&color=cb3837\" alt=\"npm downloads\"></a>\n  <a href=\"https://github.com/aaronjmars/openroutercli/stargazers\"><img src=\"https://img.shields.io/github/stars/aaronjmars/openroutercli?style=flat-square&logo=github\" alt=\"GitHub stars\"></a>\n  <a href=\"https://github.com/aaronjmars/openroutercli/network/members\"><img src=\"https://img.shields.io/github/forks/aaronjmars/openroutercli?style=flat-square&logo=github\" alt=\"GitHub forks\"></a>\n  <a href=\"https://openrouter.ai/\"><img src=\"https://img.shields.io/badge/Powered%20by-OpenRouter-6E4AFF?style=flat-square&labelColor=1a1a2e\" alt=\"Powered by OpenRouter\"></a>\n</p>\n\n<p align=\"center\">\n  <strong>Every OpenRouter endpoint, on the command line - for humans and LLM agents</strong><br>\n  Browser-based OAuth login, full access to chat / messages / responses / embeddings / rerank / audio / video / models / providers / generations / credits / activity / keys / guardrails / workspaces, and a raw <code>request</code> escape hatch. <code>--json</code> on every command. Zero npm dependencies.\n</p>\n\n---\n\n## What it does\n\n- One CLI for the entire [OpenRouter API](https://openrouter.ai/docs) - every endpoint in the OpenAPI spec is reachable.\n- Login once with browser-based **OAuth (PKCE)**, paste an existing key, or use env vars. Separate slot for **management/provisioning keys**.\n- Streams chat completions in a TTY; emits clean JSON when piped or with `--json`. Built so an agent can `--json | jq` reliably.\n- Knows the difference between user keys and management keys - picks the right one per command.\n\n## Quick start\n\nThe recommended path: **install with npm + `openrouter login`.** First request in under 60 seconds.\n\n**Prereqs** - Node.js 20+ and an [OpenRouter account](https://openrouter.ai/).\n\nInstall:\n\n- **npm** - `npm install -g @aaronjmars/openroutercli`\n- **npx** *(no install)* - `npx -p @aaronjmars/openroutercli openrouter --help`\n- **From source** - `git clone https://github.com/aaronjmars/openroutercli && cd openroutercli && npm link`\n\nThen:\n\n```bash\nopenrouter login                                            # OAuth in the browser\nopenrouter chat \"say hi\" -m openai/gpt-4o-mini              # streaming chat\nopenrouter --json models --filter sonnet | jq '.data[].id'  # pipeable JSON\nopenrouter credits                                          # what's left in the tank\n```\n\n**Other paths** - drop in an existing key with `openrouter login --key sk-or-...`, pipe one in with `--stdin`, or set `OPENROUTER_API_KEY` for ephemeral use. Management keys (for `keys` / `guardrails` / `workspaces` / `activity`) come from the [dashboard](https://openrouter.ai/settings/provisioning-keys) and are saved with `openrouter login --management`.\n\n### Two key types - user vs management\n\n<p align=\"center\">\n  <img src=\"./keys.png\" alt=\"User key vs management key - what each one unlocks\" />\n</p>\n\nThe CLI keeps a separate slot for each key type and auto-routes per command.\n`--key sk-or-...` always wins as an override; otherwise inference reaches for\nthe user slot, account-management commands reach for the management slot, and\neither falls back to the other when one slot is empty. Management keys\n**cannot** be obtained via OAuth - mint one in the [dashboard](https://openrouter.ai/settings/provisioning-keys)\nand run `openrouter login --management`.\n\n## Features\n\n| Feature | What it does |\n|---|---|\n| **OAuth PKCE login** | `openrouter login` opens the browser, catches the callback locally, exchanges the code, and stores the key - `0600` perms in `~/.config/openrouter/`. No paste-an-API-key dance. |\n| **Two-slot key management** | User key + management/provisioning key live in separate slots. `keys`, `guardrails`, `workspaces`, `activity` auto-pick the management key; everything else uses the user key. `--key` always wins. |\n| **Streaming + JSON modes** | Streams in a TTY, switches to JSON when piped or `--json` is set. No global flag plumbing - works on every command. |\n| **Chat with everything** | Tool calls (`--tool @file.json --tool-choice required`), structured output (`--schema schema.json`), JSON mode, multimodal images (`--image url\\|path`), reasoning effort, provider routing, fallback models, seed, stop sequences, full sampling controls. |\n| **Interactive REPL** | `openrouter chat -i` - slash commands `/model <id>`, `/reset`, `/exit`. History preserved per session. |\n| **Multi-format inference** | `chat` (OpenAI), `messages` (Anthropic), `responses` (OpenAI Responses) - same auth, same flags, same JSON contract. |\n| **Embeddings + rerank + TTS + video** | `embed`, `rerank`, `speech`, `video {create,wait,download}` - async video jobs poll-until-done with `video wait <jobId>`. |\n| **Model discovery with detail** | `models list` (filter, sort by price/context), `models show <id>` (full pricing breakdown - prompt, completion, cache r/w, reasoning, image, web search), `models endpoints <id> --sort throughput\\|latency\\|prompt\\|completion\\|uptime --best` for choosing the right provider variant. |\n| **Spend + activity + generations** | `credits` for balance, `whoami` for daily/weekly/monthly usage + rate limit, `keys get <hash>` for per-key spend, `activity --api-key-hash <hash>` for daily aggregates, `generation <id> [--content]` for full per-request metadata + input/output. |\n| **Account + governance** | `keys`, `guardrails` (allow/deny lists, USD limits, ZDR), `workspaces` (defaults + members), `org members`, `auth-code` to mint claim links. All require a management key. |\n| **Raw escape hatch** | `openrouter request <METHOD> <path> --body @file.json --query k=v --header k:v` - talk to any current or future endpoint without waiting for a CLI release. |\n| **Agent-friendly errors** | Stable exit codes (1 usage, 2 API, 3 no key, 4 job failed). API error messages surfaced verbatim. `OPENROUTER_DEBUG=1` for stack traces. |\n| **Zero npm dependencies** | Pure Node 20+ - built-in `fetch`, `parseArgs`, `crypto`. Cold install in seconds. Easy to audit. |\n\nEach command supports `openrouter <command> --help` for full per-command flags.\n\n## Use cases\n\n- **Throwaway prompts from the shell** - `echo \"summarize this\" \\| openrouter chat -m openai/gpt-4o-mini` instead of opening a browser tab.\n- **Agent / script integration** - `openrouter --json chat ... \\| jq` keeps stdout clean and machine-parseable; meaningful exit codes let scripts branch on errors.\n- **Comparing models head-to-head** - `for m in claude-sonnet-4.5 gpt-4o gemini-2.5-pro; do openrouter chat \"$prompt\" -m anthropic/$m; done`\n- **Picking the cheapest / fastest provider variant** - `openrouter models endpoints <id> --sort throughput --best` before locking in a model in production.\n- **Cost monitoring** - `openrouter credits` + `openrouter whoami` in cron / a status bar; `openrouter keys get <hash>` per-app.\n- **Provisioning per-customer keys** - wrap `openrouter keys create` in your onboarding flow; rotate / disable / delete via `keys update --disabled` and `keys delete`.\n- **Auditing a specific request** - paste a `gen-...` id into `openrouter generation <id> --content` to see exactly what was sent and returned, with cost.\n- **CI smoke-tests for prompt changes** - fixed seed, JSON-schema response, exit non-zero on regression.\n\n## Examples\n\n```bash\n# Browser OAuth login (recommended)\nopenrouter login\n\n# Manual key entry (and management/provisioning key)\nopenrouter login --key sk-or-v1-...\nopenrouter login --management --key sk-or-v1-...\n\n# Streaming chat\nopenrouter chat \"Write a haiku about caching\" -m anthropic/claude-sonnet-4.5\n\n# Multimodal\nopenrouter chat \"What's in this picture?\" -m google/gemini-2.5-flash --image ./photo.jpg\n\n# Strict JSON output\nopenrouter chat \"List 3 fruits\" -m openai/gpt-4o-mini \\\n  --schema '{\"type\":\"object\",\"properties\":{\"fruits\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"fruits\"]}'\n\n# Tool calling\nopenrouter chat \"What is 2+2?\" -m openai/gpt-4o-mini \\\n  --tool @calc.json --tool-choice required --raw\n\n# Discovery\nopenrouter models --filter claude --sort prompt\nopenrouter models show anthropic/claude-sonnet-4.5\nopenrouter models endpoints anthropic/claude-sonnet-4.5 --sort throughput --best\nopenrouter providers\n\n# Spend / runs\nopenrouter credits\nopenrouter whoami\nopenrouter generation gen-1234567890 --content\nopenrouter activity --date 2026-04-28 --api-key-hash <hash>\n\n# Management (provisioning key required)\nopenrouter keys create \"agent-key\" --limit 25 --limit-reset monthly\nopenrouter guardrails create \"no-paid-models\" --allowed-providers \"\" --enforce-zdr\nopenrouter workspaces create \"staging\" --slug staging --default-text-model openai/gpt-4o-mini\n\n# Raw escape hatch - call any endpoint\nopenrouter request POST /chat/completions --body @body.json\nopenrouter request GET /endpoints/zdr\n```\n\n## Documentation\n\n| | |\n|---|---|\n| `openrouter --help` | Top-level command index |\n| `openrouter <command> --help` | Per-command flags + examples |\n| [SKILL.md](./SKILL.md) | Drop-in skill description for LLM agents (Claude Code / Cursor / etc.) - what to use, when, how, with patterns and pitfalls |\n| [OpenRouter API docs](https://openrouter.ai/docs) | Upstream API reference |\n| [OpenRouter dashboard](https://openrouter.ai/keys) | Manage keys, billing, workspaces in the browser |\n| [Provisioning keys](https://openrouter.ai/settings/provisioning-keys) | Where management keys are minted |\n\nEndpoint coverage map:\n\n| OpenRouter endpoint | Command |\n|---|---|\n| `POST /auth/keys` (PKCE exchange) | `openrouter login` |\n| `POST /auth/keys/code` | `openrouter auth-code` |\n| `GET /key` | `openrouter whoami` |\n| `GET /credits` | `openrouter credits` |\n| `GET /activity` | `openrouter activity` |\n| `GET /models` | `openrouter models list` |\n| `GET /models/count` | `openrouter models count` |\n| `GET /models/user` | `openrouter models user` |\n| `GET /models/{author}/{slug}/endpoints` | `openrouter models endpoints` |\n| `GET /providers` | `openrouter providers` |\n| `GET /endpoints/zdr` | `openrouter zdr` |\n| `POST /chat/completions` | `openrouter chat`, `openrouter complete` |\n| `POST /messages` | `openrouter messages` |\n| `POST /responses` | `openrouter responses` |\n| `POST /embeddings` / `GET /embeddings/models` | `openrouter embed [models]` |\n| `POST /rerank` | `openrouter rerank` |\n| `POST /audio/speech` | `openrouter speech`, `openrouter tts` |\n| `POST /videos`, `GET /videos/{id}`, `GET /videos/{id}/content`, `GET /videos/models` | `openrouter video {create,get,wait,download,models}` |\n| `GET /generation`, `GET /generation/content` | `openrouter generation [--content]` |\n| `GET/POST/PATCH/DELETE /keys[/{hash}]` | `openrouter keys {list,get,create,update,delete}` |\n| `GET/POST/PATCH/DELETE /guardrails[/{id}]` + assignments | `openrouter guardrails ...` |\n| `GET/POST/PATCH/DELETE /workspaces[/{id}]` + members | `openrouter workspaces ...` |\n| `GET /organization/members` | `openrouter org members` |\n| anything else | `openrouter request <METHOD> <path>` |\n\n## Configuration\n\n| flag | env | description |\n|---|---|---|\n| `-k, --key <key>` | `OPENROUTER_API_KEY` (user, alias `OPENROUTER_KEY`) / `OPENROUTER_MANAGEMENT_KEY` (mgmt) | API key to use; flag overrides env / config |\n| `--base-url <url>` | `OPENROUTER_BASE_URL` | API base (default `https://openrouter.ai/api/v1`) |\n| `--referer <url>` | `OPENROUTER_REFERER` | `HTTP-Referer` header (your app URL) |\n| `--title <name>` | `OPENROUTER_TITLE` | `X-Title` header (your app name; appears on openrouter.ai) |\n| `--json` | - | JSON output, no streaming, no color |\n| `-q, --quiet` | - | Suppress informational stderr |\n| `-V, --version` | - | Print the version |\n| - | `NO_COLOR` (alias `OPENROUTER_NO_COLOR`) | Disable ANSI colors |\n| - | `OPENROUTER_DEBUG=1` | Stack traces on error |\n\nConfig file: `~/.config/openrouter/config.json` (or `$XDG_CONFIG_HOME/openrouter/`), `0600` perms.\n\n## License & disclaimer\n\nMIT. See [LICENSE](./LICENSE).\n\nThis is an **unofficial** community project. It is not affiliated with,\nendorsed by, or sponsored by OpenRouter. \"OpenRouter\" and the OpenRouter\nlogo are trademarks of their respective owners; usage here is for\nidentification only.\n\n---\n\nBuilt by [Aaron Elijah Mars](https://aaronjmars.com), founder of Aeon and MiroShark · [@aaronjmars](https://github.com/aaronjmars)\n","readmeFilename":"README.md"}