Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion skills/openrouter-oauth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ For other install methods (Claude Code plugin marketplace, Cursor Rules, etc.) s

## Compatibility

Browser environment — requires Web Crypto API, `localStorage`, and `sessionStorage`.
Browser, CLI, and Node.js environments. Browser flows require Web Crypto API, `localStorage`, and `sessionStorage`. Headless flows require Web Crypto API and can keep the verifier in process memory.

## What it covers

Expand All @@ -27,3 +27,4 @@ See [SKILL.md](SKILL.md) for the full reference, including:
- Copy-pasteable auth module with no dependencies
- A ready-to-use "Sign In with OpenRouter" button component
- Programmatic API-key acquisition flows (no UI required)
- Headless authorization for SSH sessions, remote development boxes, and containers without a reachable callback
27 changes: 23 additions & 4 deletions skills/openrouter-oauth/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: openrouter-oauth
description: Implement "Sign In with OpenRouter" using OAuth PKCE — framework-agnostic, no SDK or client registration required. Use when the user wants to add OpenRouter login, authentication, sign-in buttons, OAuth, or AI model inference API keys for browser-based apps. No client registration, no backend, no secrets required.
version: 2.0.0
compatibility: browser (requires Web Crypto API, localStorage, sessionStorage)
description: Implement "Sign In with OpenRouter" using OAuth PKCE — framework-agnostic, no SDK or client registration required. Use when the user wants to add OpenRouter login, authentication, sign-in buttons, OAuth, or AI model inference API keys for browser apps, CLI tools, or remote environments. No client registration, no backend, no secrets required.
version: 2.1.0
compatibility: browser, CLI, or Node.js (requires Web Crypto API; browser flows also use localStorage and sessionStorage)
---

# Sign In with OpenRouter
Expand All @@ -16,7 +16,7 @@ Live demo: [openrouterteam.github.io/sign-in-with-openrouter](https://openrouter
| User wants to… | Do this |
|---|---|
| Add sign-in / login to a web app | Follow the full PKCE flow + button guidance below |
| Get an API key programmatically (no UI) | Just implement the PKCE flow — skip the button section |
| Get an API key programmatically (no UI) | Use the headless / no-callback flow below |
| Use the OpenRouter SDK after auth | Do PKCE here for the key, then see `openrouter-typescript-sdk` skill for `callModel`/streaming |

---
Expand Down Expand Up @@ -48,6 +48,25 @@ https://openrouter.ai/auth?callback_url={url}&code_challenge={challenge}&code_ch
| `code_challenge` | The S256 challenge from Step 1 |
| `code_challenge_method` | Always `S256` |

### Headless / no-callback flow

For SSH sessions, remote development boxes, containers, and other environments where a localhost callback cannot be reached, omit `callback_url` entirely. After the user authorizes, OpenRouter displays the authorization code on screen for them to paste into the app.

```
https://openrouter.ai/auth?code_challenge={challenge}&code_challenge_method=S256&key_label={label}
```

| Param | Value |
|---|---|
| `code_challenge` | The S256 challenge from Step 1 (required) |
| `code_challenge_method` | `S256` (required; `plain` is rejected) |
| `key_label` | Optional app title on the approval screen; defaults to `A command-line app` |

- Do not include `callback_url` or `oauth_client_id`. A no-callback request with `oauth_client_id`, a missing `code_challenge`, or a `plain` challenge method is rejected and redirected to the OpenRouter home page instead of showing a code.
- Keep the `code_verifier` in the process until the user pastes the displayed code. `sessionStorage` and `localStorage` from the browser auth module do not apply in a CLI or Node.js context.
Comment thread
perry-the-pr-maintainer[bot] marked this conversation as resolved.
- The displayed code is single-use and expires 10 minutes after issuance.
- After the user pastes the code, continue with Step 4. The `POST /api/v1/auth/keys` exchange is unchanged.

### Step 3: Handle the redirect back

User returns to your `callback_url` with `?code=` appended. Extract the `code` query parameter.
Expand Down