Skip to content
Rapid Router
← API reference

Sign in with Rapid Router

Part of the Rapid Router API reference. One OpenAI-compatible endpoint, https://rapidrouter.ai/api/v1, in front of every model in the catalog.

28Sign in with Rapid Router

Let your users pay for your app's inference with their own Rapid Router credits, no key copy-pasting. An OAuth PKCE flow: you send the user to our consent page, they approve, and you exchange the returned code for an API key bound to their account. The key is a normal runtime key, visible in their dashboard and revocable by them at any time.

  1. Generate a random code_verifier, hash it to a code_challenge (S256), and send the browser to https://rapidrouter.ai/oauth/authorize.
  2. The user signs in if needed and approves. The browser lands back on your callback_url with ?code=... (or ?error=access_denied if they refuse).
  3. POST the code and your verifier to /v1/auth/keys. No session or auth header needed: the code plus the matching verifier is the proof. The response carries the key secret, shown exactly once.
// 1. verifier + challenge with WebCrypto, then redirect
const bytes = crypto.getRandomValues(new Uint8Array(32))
const verifier = btoa(String.fromCharCode(...bytes))
  .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")
sessionStorage.setItem("rr_verifier", verifier)

const digest = await crypto.subtle.digest("SHA-256",
  new TextEncoder().encode(verifier))
const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
  .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "")

location.href = "https://rapidrouter.ai/oauth/authorize?"
  + new URLSearchParams({
      callback_url: "https://yourapp.com/callback",
      code_challenge: challenge,
      code_challenge_method: "S256",
      app_name: "Your App",
    })

callback_url must be https, or http://localhost (any port) for local development; anything else is rejected before the consent screen renders. Codes expire after 10 minutes and are single-use: a second exchange of the same code answers 400 code_consumed, a stale one 400 code_expired, and a wrong verifier 400 verifier_mismatch. The exchange endpoint is limited to 10 attempts a minute per IP. Keys created this way are named OAuth: <app name> in the user's dashboard, and revoking one there cuts your app off immediately.