intercom oauth invalid authorization code error
For developers and agents building Intercom apps. Use when the code exchange fails. Not for credential or scope errors.
Fix Intercom OAuth failing with invalid authorization code
TL;DR
Invalid authorization code means the code Intercom sent was already used, expired, or never valid. Authorization codes are single-use and expire in minutes, so exchange each code immediately and exactly once. If your code retries the exchange, the retry is what fails.
The error
Intercom OAuth failed
{"error":"invalid_grant","error_description":"Invalid authorization code"}Use this skill
Agent? Search Vectle for this error:
curl -s "https://vectle.com/api/v1/search?q=intercom oauth invalid authorization code error"Fix it
Step 1: Check for double exchange in your code
Search your OAuth callback handler for the token exchange call and confirm it runs once per code.Expected: You find either a single call or a retry path that reuses the code.
Step 2: Remove code reuse and retries
Make the exchange fire exactly once; on failure, restart the whole authorization flow instead of retrying the code.Expected: Each authorization code is exchanged at most once.
Step 3: Exchange the code immediately
Keep the time between receiving the code and exchanging it as short as possible.Expected: Exchanges complete within seconds of receiving the code.
Step 4: Verify the redirect URI matches
Confirm the redirect_uri sent at exchange time matches the one sent at authorize time.Expected: Both values are identical.
Step 5: Test a fresh OAuth flow
Run the full flow again from authorization.Expected: The exchange returns tokens on the first try.
When this applies
- Intercom OAuth fails with invalid authorization code
- The flow works sometimes and fails other times
- You added retry logic to the OAuth callback
When it doesn't
- The error is invalid_client (check the app credentials)
- The code is never received (check the redirect URI registration)
- Tokens are issued but API calls fail (check scopes)
Compatibility
Intercom OAuth 2.0 for apps. Authorization code flow.
Variant phrasings
intercom invalid_grant authorization code
Same failure. invalid_grant is the wrapper; the description names the code as the problem.
oauth code already used intercom
Already-used is the top cause when retry logic replays the exchange.
intercom oauth code expired
Codes expire quickly. Slow exchanges, like ones waiting on a user step, die before they run.
Why it happens
Authorization codes are single-use, short-lived credentials by design. The first exchange consumes the code; anything after that, a retry, a double-submit, a replayed webhook, gets invalid authorization code. Expired codes fail the same way when the exchange happens too late.
Edge cases
- Browser back-button resubmits can double-fire the exchange; guard with a state check
- Load-balanced callback handlers can race on the same code; make the exchange idempotent at the flow level
- Logging the code is a security risk; log the state parameter instead
If it still fails
- Reproduce with one API call in isolation, outside the agent, to separate platform issues from agent issues.
- Check the platform status page and changelog; OAuth and webhook behaviors change without warning.
- Capture the full request and response with timestamps for the vendor ticket, redacting credentials.
- Test in a second workspace or sandbox to rule out workspace-specific policy blocks.
- If the integration is business-critical, build the fallback now: cached data, a manual trigger, or a second provider.
Prevention
- Store OAuth credentials in a secrets manager with rotation reminders.
- Build the reconnect flow before you need it; every integration gets revoked eventually.
- Log token ages so expiring grants are visible ahead of time.
- Keep a sandbox integration for testing config changes.
- Document the required scopes per integration so reinstalls request the right ones.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_osJIsJs0T7uBKAOD7ejUyg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.