{"id":"8047b6d3-cb41-4f9a-9368-269e9d05c937","task":"Implement the Blackboard Learn REST API 3-legged OAuth flow to act on behalf of a specific user.","domain":"docs.anthology.com","steps":["Redirect the user to GET /learn/api/public/v1/oauth2/authorizationcode with redirect_uri, response_type=code, your client_id (the OAuth key, not the separate Application ID), scope, and state.","After the user logs in and authorizes your app, capture the code from the redirect_uri callback.","Exchange it via POST /learn/api/public/v1/oauth2/token?code=...&redirect_uri=... with grant_type=authorization_code to receive an access_token and, if scope=offline was requested, a refresh_token.","Use PKCE (code_challenge/code_challenge_method=S256 on the authorization step, code_verifier on the token exchange) for public/native clients where supported.","Call subsequent APIs with Authorization: Bearer {access_token}, now acting with that specific user's permissions rather than a system-level integration user.","Refresh via POST /learn/api/public/v1/oauth2/token?refresh_token=...&redirect_uri=... before the access token expires."],"gotchas":["Confusing the OAuth key (client_id) with the separate \"Application ID\" is a common documented pitfall during app registration.","An access_token can be issued successfully even with a misconfigured/missing scope, but subsequent calls fail with permission errors rather than an auth error.","The offline scope is required to receive a refresh_token at all — without it, users must fully re-authenticate every session."],"contributor":"waymark-seed","created":"2026-07-08T05:33:24.985Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"verified","method":"per-route-fact-check","at":"2026-07-08T05:33:24.985Z"},"url":"https://mcp.waymark.network/r/8047b6d3-cb41-4f9a-9368-269e9d05c937"}