Migrate an existing monday.com app from the old OAuth flow to the new OAuth 2.1 flow. Changes token endpoint from oauth2/token to oauth_ms/oauth/token, adds refresh token support, updates token storage, and optionally adds PKCE. ALWAYS use when someone mentions migrating monday OAuth, switching to the new OAuth flow, adding refresh tokens, updating the monday token endpoint, token expiration, or when code calls auth.monday.com/oauth2/token. Also trigger on OAuth deadline/deprecation announcements. Do NOT use for new OAuth from scratch, non-monday OAuth (Google, Slack, Spotify), client credentials flow, DCR, or general monday debugging.
Migrate an existing monday.com app from the old OAuth flow to the new OAuth 2.1 flow. Changes token endpoint from oauth2/token to oauth_ms/oauth/token, adds refresh token support, updates token storage, and optionally adds PKCE. ALWAYS use when someone mentions migrating monday OAuth, switching to the new OAuth flow, adding refresh tokens, updating the monday token endpoint, token expiration, or when code calls auth.monday.com/oauth2/token. Also trigger on OAuth deadline/deprecation announcements. Do NOT use for new OAuth from scratch, non-monday OAuth (Google, Slack, Spotify), client credentials flow, DCR, or general monday debugging.
You are migrating a monday.com app from the old OAuth flow to the new OAuth 2.1 flow. Follow these phases in order. Each phase has clear entry/exit criteria. Do not skip phases.
Phase 0: Detection — Does This App Need Migration?
Also search for partial patterns like oauth2/authorize and oauth2/token in case the base URL is constructed dynamically.
If NEITHER pattern is found:
Tell the developer:
"I didn't find any OAuth flow usage in this codebase (no calls to auth.monday.com/oauth2/authorize or auth.monday.com/oauth2/token). This app doesn't appear to be using the OAuth flow yet. This skill is specifically designed for migrating existing OAuth integrations. If you'd like to implement OAuth from scratch instead, I can help, but the migration workflow may not fit perfectly — want to continue anyway?"
If they want to continue, proceed but note that some steps (like finding need extra guidance.
If patterns ARE found: proceed to Phase 1.
Before moving on, report what you found: which files contain OAuth references, and give a brief summary of the current OAuth implementation structure you see (authorization redirect, callback handler, token exchange, token storage).
Phase 1: Enable OAuth in the Dev Center (Manual Step)
This step cannot be automated. Ask the developer to do the following manually:
You need to enable the new OAuth flow in the monday.com Developer Center:
Create a new draft version of your app (the toggle is per-version)
Enable the "New OAuth Flow" toggle for the draft version
Make sure the draft version is set to "Active for me" so you can test it
Your scopes and redirect URIs will be cloned from the previous version automatically — no need to reconfigure them.
Tell me when you've completed this step so I can start migrating your code.
Wait for the developer to confirm before proceeding. Do NOT start code changes until they confirm.
Phase 2: PKCE Decision
Use AskUserQuestion to ask:
Question: "Would you like to add PKCE (Proof Key for Code Exchange) to your OAuth flow? PKCE adds an extra layer of security that protects against authorization code interception attacks. It's recommended for all apps and required for DCR-registered clients."
Options:
Yes, add PKCE (Recommended) — Adds code_verifier generation and code_challenge to the authorization flow
No, skip PKCE — Keep the flow simple without PKCE
Remember their choice — it affects Phase 3 and Phase 4.
Phase 3: Migrate the Authorization Request (only if PKCE was chosen)
If the developer chose No PKCE — skip this phase entirely. The authorization endpoint (GET https://auth.monday.com/oauth2/authorize) stays exactly the same.
If the developer chose Yes PKCE, find where the authorization URL is constructed and add PKCE parameters:
What to add
Generate a code verifier — a cryptographically random string (43-128 characters):
Important: The app may already use state, scope, redirect_uri, or other query parameters in the authorization URL. Preserve ALL existing parameters exactly as they are. Only append code_challenge and code_challenge_method. Do not replace, rename, or restructure the URL construction — just add the two new params.
Store the code_verifier — it must be available when exchanging the code for tokens in the callback. Use whatever mechanism the app already uses to maintain state between the authorization redirect and the callback (session, database, cookie, etc.). If the app already passes a state parameter, you can key the verifier by that existing state value — do not generate a new state to replace it.
Adapt the code to match the language, framework, and patterns already used in the developer's codebase. Do not introduce new dependencies if the language's standard library already provides crypto primitives. Do not restructure or rename existing variables, routes, or functions — make the minimal additions needed.
Phase 4: Migrate the Token Exchange
This is the core migration step. Find the callback endpoint that:
Receives the authorization code from monday.com
Sends it (along with client_id and client_secret) to exchange for tokens
4a. Change the token exchange endpoint
Find the call to the old endpoint:
POST https://auth.monday.com/oauth2/token
Change it to the new endpoint:
POST https://auth.monday.com/oauth_ms/oauth/token
The request body parameters remain the same: client_id, client_secret, code, and optionally redirect_uri.
If PKCE was chosen: also include code_verifier in the request body — this is the same verifier generated in Phase 3.
4b. Handle the new response format
The old flow returned only an access_token (which never expired).
The new flow returns both an access_token (which expires) and a refresh_token:
This is critical. Find where the old access_token was being saved (database, file, env variable, key-value store, etc.) and ensure:
The refresh_token is also saved alongside the access token
Both tokens are associated with the same user/account context
The storage mechanism can handle updating both tokens (they will change on every refresh)
Look for patterns like:
Database columns (e.g., access_token column — add a refresh_token column)
Object/model properties storing the token
Key-value store entries
Environment variables or config files
If the developer stores tokens in a database, you may need to add a migration or alter the schema. If they use a simpler storage mechanism, just ensure both tokens are persisted.
Phase 5: Add Token Refresh Logic
This is entirely new functionality — the old flow had no token expiration, so there was no refresh mechanism.
5a. Create the refresh function
Create a function that refreshes an expired access token. It calls the same token endpoint but with different parameters:
Each refresh returns a new refresh_token. Always replace both the access token AND the refresh token in storage.
5b. Integrate refresh into the app's API call flow
Find where the app uses the access token to call the monday.com API (typically via Authorization: Bearer <token> header or the monday SDK). Add logic to handle token expiration:
Recommended pattern — proactive check before API calls:
Decode the JWT access token and check the exp (expiration) claim
If the token is expired or about to expire (within ~60 seconds), refresh it first
Then proceed with the API call using the new token
Alternative pattern — reactive refresh on 401:
Make the API call
If the response is 401 Unauthorized, attempt to refresh the token
Retry the original API call with the new token
If refresh also fails, the user needs to re-authorize
Choose whichever pattern best fits the existing codebase architecture. If the app already has middleware, interceptors, or a central API client, hook into that.
5c. Handle refresh failures
If a refresh call fails (e.g., refresh token was revoked or expired), the user must re-authorize through the full OAuth flow again. Make sure the app handles this gracefully — redirect to the authorization URL or show an appropriate error.
Phase 6: Token Revocation (Optional)
Use AskUserQuestion to ask:
Question: "Would you like to add a token revocation function? This lets your app revoke tokens when a user disconnects or uninstalls (e.g., cleanup on uninstall webhook)."
Options:
Yes, add revocation — Adds a function to revoke access or refresh tokens
No, skip — Skip revocation for now
If Yes, create a revocation function:
Endpoint:
POST https://auth.monday.com/oauth_ms/oauth/revoke