OAuth PKCE

Connect users to TheRouter.ai with a secure PKCE authorization flow

TheRouter.ai supports OAuth with Proof Key for Code Exchange (PKCE). This lets your users authorize your app and issue user-controlled keys without sharing long-lived credentials.

Flow overview

pkce-flow.txt
1) Your app generates code_verifier and code_challenge
2) Redirect user to https://therouter.ai/auth with callback_url + challenge
3) User authenticates and approves access
4) TheRouter.ai redirects to callback_url?code=...
5) Your backend exchanges code at https://api.therouter.ai/v1/auth/keys
6) Store returned user-controlled API key securely

Step 1: Authorization redirect

S256 (recommended)
https://therouter.ai/auth?callback_url=<YOUR_CALLBACK_URL>&code_challenge=<CODE_CHALLENGE>&code_challenge_method=S256
Use S256
Use SHA-256 code challenges whenever possible for stronger PKCE protection.

Generate code challenge

create-code-challenge.ts
import { Buffer } from "buffer";

export async function createCodeChallenge(codeVerifier: string) {
  const bytes = new TextEncoder().encode(codeVerifier);
  const digest = await crypto.subtle.digest("SHA-256", bytes);
  return Buffer.from(digest).toString("base64url");
}

Step 2: Exchange code for key

exchange-code.ts
const response = await fetch("https://api.therouter.ai/v1/auth/keys", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    code: "<CODE_FROM_QUERY>",
    code_verifier: "<CODE_VERIFIER>",
    code_challenge_method: "S256",
  }),
});

const { key } = await response.json();

Step 3: Use the returned key

use-user-key.ts
const completion = await fetch("https://api.therouter.ai/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: "Bearer <USER_CONTROLLED_KEY>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/gpt-4o",
    messages: [{ role: "user", content: "Hello from OAuth" }],
  }),
});

Common error codes

  • 400 Invalid code_challenge_method: the method differs between authorize and exchange steps.
  • 403 Invalid code or code_verifier: the code is expired, reused, or verifier is incorrect.
  • 405 Method Not Allowed: use HTTPS and POST for the token exchange request.
Local development
For local-first apps, http://localhost:3000 works well as callback during development.