Qeet Docs
OIDC / OAuth provider

Authorization Code + PKCE

The browser login flow — authorize, hosted login & consent, callback, and code exchange — with PKCE (S256) required.

The Authorization Code flow with PKCE (S256) is the standard way browser and native apps sign users in through Qeet ID's hosted login. PKCE is required for public clients and recommended for all.

The flow

Redirect to authorize

Your app sends the user to the authorize endpoint with a code_challenge. If there's no SSO session, Qeet ID renders the hosted login (password + passkey + social), then a consent screen for the requested scopes.

GET/v1/oauth/authorizeStart the flow
Text
GET /v1/oauth/authorize
  ?response_type=code
  &client_id=qci_…
  &redirect_uri=https://app.acme.com/api/auth/callback
  &scope=openid%20profile%20email
  &state=<csrf>
  &code_challenge=<base64url(sha256(verifier))>
  &code_challenge_method=S256

User authenticates & consents

Qeet ID's hosted login handles authentication and MFA. The consent decision is posted back internally:

POST/v1/oauth/authorize/decisionRecord consent

Callback with the code

Qeet ID redirects to your redirect_uri with code and state. Validate state.

Exchange the code for tokens

Your server exchanges the code (plus the PKCE code_verifier) at the token endpoint.

POST/v1/oauth/token-codeExchange authorization_code
Bash
curl -X POST https://api.qeetid.com/v1/oauth/token-code \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=https://app.acme.com/api/auth/callback \
  -d client_id=$CLIENT_ID \
  -d code_verifier=$VERIFIER

The response is an OAuth token response with access_token, id_token (ES256), and refresh_token. See Tokens for the shape, userinfo, refresh rotation, introspection, and revocation.

Let the SDK do it

@qeetid/nextjs runs this entire flow — PKCE, hosted login, callback, code exchange, encrypted cookie, and silent refresh — from a single route handler. See SDKs → TypeScript & Next.js.

Hosted login context

The hosted-login UI fetches the pending request's client and scope info to render the right screen:

GET/v1/oauth/login-contextPending authorize context

On this page