Open source · MIT · Build an AI front desk, part 6
quickbooks-online-kit
QuickBooks Online: keeping the connection alive. Access tokens last an hour and every refresh replaces your refresh token. How to refresh once, save before use, and never double-invoice.
- TypeScript
- Next.js
- QuickBooks Online
Early (v0.x), written with Claude Code and directed and reviewed by me. Not on npm yet: clone the repository to use it.
Connecting an app to QuickBooks Online is a one-time consent screen. Keeping it connected is the real job: Intuit access tokens last about an hour, and every time you refresh one, the response includes a new refresh token that replaces the old one.
- Connect (OAuth2)
- Token store
- Refresh-token rotation
- Typed REST client
- Audit log
Three ways this goes wrong
- Five requests arrive at the same moment the token expires. Each refreshes, the first wins, the others hold a dead token, and the customer has to reconnect.
- You get a new refresh token, crash before saving it, and the old one is gone.
- Two servers refresh at once and one loses the race.
What the token manager does
- Concurrent callers in one process share one refresh request.
- The rotated refresh token is saved before the new access token is handed out.
- If a refresh is rejected but another process already stored a newer token, it adopts that one instead of failing.
- Sandbox tokens are never used against production.
Watch it happen
A fake Intuit server runs in your browser. Let an hour pass, make five calls at once, and count the refresh requests.
QuickBooks Online: keeping the connection alive
Intuit access tokens last an hour and every refresh hands back a new refresh token. Lose it and the customer has to reconnect. Let an hour pass, then fire five calls at once: the real quickbooks-online-kit (opens in a new tab) token manager shares one refresh. A fake Intuit server runs in your browser; no QuickBooks account is touched.
- Access token
- at-1
- Refresh token
- rt-1
- Access token valid for
- 60 more minutes
- Refresh requests so far
- 0
- Try: let an hour pass, then make 5 calls at once.
Never double-invoice
The client turns an estimate into an invoice once, and a repeat is refused with an ALREADY_INVOICED error. The repository quickstart runs the whole flow offline against an in-process fake of Intuit's OAuth and REST endpoints.
invoice total 300 | second conversion: ALREADY_INVOICEDWhat this does not do
- It is a v0.1 reference implementation extracted from an internal integration. Read the README for what has and has not been run against the live service.
- It defaults to the sandbox environment; anything other than production resolves to sandbox.
- In this demo's browser copy, file-based audit logging is removed.
Get it
git clone https://github.com/27colab/quickbooks-online-kit.git
cd quickbooks-online-kit && npm ci && npm testUsed in
Want this built into your product? Get in touch.