You need a backend (a server, serverless function, or a Replit/Render-style host). The flow stores access and refresh tokens, which must never live in browser-only code. Pure front-end apps (e.g. a Lovable site with no backend) can’t hold tokens safely — pair them with an edge/serverless function.
What you’re integrating against
- Provider: WorkOS AuthKit at
https://connect.pickfu.com - Flow: OpenID Connect with PKCE — public client, no shared secret
- Client provisioning: RFC 7591 Dynamic Client Registration — your app registers itself at boot. There’s no dashboard to pre-create a client.
- API base:
https://api.pickfu.com/v1(notwww.pickfu.com)
Endpoints
All endpoints come from the discovery document — fetch it once and cache it:Scopes
Minimal implementation
One self-contained module (Node, framework-agnostic). Swapfetch/crypto for your platform’s equivalents. encrypt/decrypt are your own AES-256-GCM-at-rest helpers; db is any store.
Token lifecycle & security
- Access tokens expire in ~1 hour. Refresh proactively (within 60s of expiry), not reactively on a 401.
- A refresh response may include a new refresh token — replace the stored one when it does.
- Encrypt both tokens at rest (AES-256-GCM) — they grant full PickFu account access. Never log raw tokens.
Gotchas
Discovery path
Discovery path
Use
/.well-known/oauth-authorization-server — the canonical WorkOS path. /.well-known/openid-configuration also resolves.PKCE must be S256
PKCE must be S256
code_challenge_method=S256 only. plain is rejected. Verifier ~64 bytes base64url; challenge = SHA-256(verifier).redirect_uri must match character-for-character
redirect_uri must match character-for-character
The URI registered via DCR must exactly match what you send at authorization time. If your public URL changes (custom domain), delete the cached client registration and let DCR re-run.
Public client, but a secret may appear
Public client, but a secret may appear
token_endpoint_auth_method: "none" means no secret is required. WorkOS may still return a client_secret — store it encrypted and include it if present; it isn’t mandatory.Creating surveys with this token (draft → publish,
mediaUrl options, AI image generation) is covered in the API Reference and Guides — those rules are the same regardless of how you authenticate.