Choose an OAuth example for your backend, native app, or browser client.
Start after creating your application. Each example uses the same R+D authorization-code flow with S256 PKCE and reads only the connected user's profile. Choose the platform you registered, not just your preferred language.
| Example | Languages | What you get |
|---|---|---|
| Backend OAuth | TypeScript on Node.js 24, Python 3.11+ | Framework-independent helpers for authorization, callbacks, API calls, refresh, and revocation |
| Native / desktop | JavaScript on Node.js 24, Python 3.11+ | Runnable local demos using the system browser and an IP-loopback callback |
| Client-side browser | JavaScript, TypeScript | A runnable HTML demo with a public client, registered origin, and in-memory access token |
These examples use standard libraries and browser APIs. The backend helpers need your framework's authenticated session and storage adapter. The native and browser demos can be run after registering their callbacks and setting your own client ID. They are teaching examples, not an R+D SDK or a complete production application.
Watch: link and disconnect an account
Silent recording of the local app with synthetic accounts. The interface is in English; captions are available in English, German, French, and Dutch.
This walkthrough uses a backend app and an accepted tester. It shows consent, a real code exchange, and revocation; it does not demonstrate an API data request. The same consent and disconnect steps apply to native and browser clients.
Download video (WebM)
0:00 An accepted tester starts in the third-party app and chooses Link your R+D account.
0:08 R+D shows the app identity and requested permissions. Review these before allowing access.
0:14 Choose Allow selected permissions. The browser returns to the app callback.
0:19 The server validates the callback and exchanges the code with PKCE. Tokens stay on the server.
0:25 To review or remove access, open R+D Settings → Connected apps.
0:32 Choose Disconnect. The app can no longer use this connection for API access.
The exchange all platforms share
- Create fresh random
stateand a PKCE verifier for this connection attempt. Retain them in the initiating user's session. - Open your configured issuer's
/oauth/authorizewithresponse_type=code, client ID, callback, scope, state, and the S256 challenge. - At the callback, consume the pending transaction once. Check
stateandissbefore handling approval or denial. - Send the code, the exact callback, and the verifier to
/oauth/tokenusing form encoding. Backend clients also authenticate with their registered secret method. - Read the granted
scope. SendAuthorization: Bearer ...to the API only for features the user authorized.
Use one fixed issuer for each environment. Discover its endpoints through
/.well-known/oauth-authorization-server; never choose a token endpoint from an
unvalidated callback's iss. Staging and production registrations and tokens are
separate. OAuth tokens are opaque and are not OpenID Connect ID tokens.
Errors to handle
| Result | App behavior |
|---|---|
error=access_denied at callback | Validate state and issuer, consume the attempt, and return the user to an unconnected state |
| Unexpected state, issuer, duplicate callback parameters, or expired attempt | Reject the response without exchanging the code; start a new attempt |
| Token endpoint rejects the code | Do not reuse it; verify callback, PKCE, environment, and the registered client-authentication method |
API 401 | Access may have expired or been revoked; refresh once if you have a valid refresh token, otherwise reconnect |
API 403 | Check granted scopes and existing account/device permissions |
API 429 | Wait for Retry-After before sending another request |
| Refresh timeout or an ambiguous response | Do not retry the old refresh token; reconnect if you cannot recover the stored replacement |
Access tokens last ten minutes. The samples omit offline_access; the backend guide
explains how to add it when needed. OAuth API traffic is limited to 60 requests per
minute per app and user. See the protocol reference for the
complete scope and token lifecycle rules.