Contractbook API "401" on token refresh - how to fix
Fixes Contractbook API 401 on token refresh. Use when a contract automation loses auth and the refresh grant fails. Key trigger: the refresh token expired or was rotated, so re-run the full auth flow.
TL;DR: The refresh grant is dead - refresh tokens expire, get rotated to single-use, or die when the user changes their password. Re-run the full authorization flow to get a fresh token pair, store the new refresh token (the old one will not work again), and retry. Do not loop the refresh call; it will never succeed with a dead grant.
401Stop retrying the refresh - confirm the failing call is the token endpoint using the refresh grant. Expected: repeated 401s on the same grant; the grant is invalid, not the network.
Check the usual killers: did the password change, was the integration re-authorized elsewhere, or did the refresh token pass its lifetime? Expected: one of these is true - that is your cause.
Run the full OAuth or login flow again to obtain a new access and refresh token pair. Expected: 200 with fresh tokens.
Persist the NEW refresh token immediately, replacing the old one everywhere (env, secret store, database). Expected: subsequent refreshes use the new grant and succeed.
Add handling for 401 on refresh: treat it as "re-authenticate", not "retry". Expected: the next expiry triggers a clean re-auth instead of a retry storm.
Use this when
- token refresh returns 401 while other API calls used to work
- the failure started after a password change or re-authorization
- the integration sat idle past the refresh token's lifetime
Not for this skill when
- the 401 is on regular API calls with a fresh access token (check scopes or token expiry instead)
- the error is 429 (rate limiting - back off, do not re-auth)
- you never had a working token (fix the initial auth flow first)
Variant phrasings
contractbook api 401 refresh token expired
contractbook oauth token refresh unauthorized
contractbook api re-authenticate 401
Why it happens
Refresh tokens are long-lived but not immortal: they expire, many providers rotate them so each is single-use, and a password change or explicit revocation kills them. The token endpoint answers a dead grant with 401, which looks like a credentials problem but is really a lifecycle problem.
Edge cases
- If your code stored the old refresh token after a successful rotation, the stored copy is already dead - always persist the newest one.
- Concurrent refreshes can race: two workers refresh at once and the loser's new token is invalid - serialize refreshes.
- Clock skew rarely causes 401 on refresh, but check it if re-auth also fails.
- Log token lifetimes at issuance so expiry never surprises you again.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_QOuCYNtxit-3seNcZYpNgA