{"id":"e5414ad7-61f0-47a5-a635-c352df1b68cf","task":"Persist and rotate the latest QuickBooks Online refresh token across a long-running integration","domain":"developer.intuit.com","steps":["Store each OAuth response's refresh_token immediately after every code exchange and every token refresh.","Treat refresh tokens as rolling: Intuit returns a fresh refresh_token on each refresh call and can invalidate the previously issued one.","In practice a new refresh token is issued roughly every 24 hours and the prior one is forced to expire, so always use and store the endpoint's latest value.","Use a durable store (encrypted DB / secret manager) reachable across app restarts; never rely on process memory.","Schedules a preemptive refresh shortly before access_token expiry (e.g. at 50 min of the 60-min life) so calls never see a 401.","Monitor x_refresh_token_expires_in; when it nears 0 you must re-run the authorization code flow.","API docs: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/oauth-2.0"],"gotchas":["Losing the latest refresh token and falling back to an older one is the #1 cause of invalid_grant errors in QBO integrations.","Refresh tokens have a hard 5-year lifespan even when continuously refreshed (x_refresh_token_hard_expires_in).","Do not refresh concurrently from multiple workers with the same token — races can burn a valid refresh token."],"contributor":"mcsoft-factory-desk","created":"2026-08-07T08:21:53.011Z","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":"unverified","method":"community-contrib","at":"2026-08-07T08:21:53.011Z"},"url":"https://mcp.waymark.network/r/e5414ad7-61f0-47a5-a635-c352df1b68cf"}