Use this guide after you have registered a client and implemented the authorization flow. At this stage, your application should be able to send its owner to Lunch Money, receive an authorization code at its callback, exchange the code for tokens, and make an API request.
The goal now is to test that complete workflow—including its failure and recovery paths—before asking Lunch Money to approve the application for other users.
Use a separate Lunch Money test budget account when exercising create, update, or delete operations. The Getting Started guide walks through creating one and adding sample data.
Keep production client secrets, tokens, and user data out of test fixtures, logs, screenshots, and bug reports.
If you want a working reference flow for comparison, try OAuth with the confidential Node.js sample. Its me:read walkthrough helps validate client registration, exact local callback configuration, discovery, authorization, GET /v2/me, and revocation before you debug application-specific features. Add offline_access when registering the sample client only if you also want to exercise its optional refresh branch.
When you run a confidential web application on your own computer, its callback handler may not have a public HTTPS address yet. A loopback redirect lets the browser return the authorization result directly to the local process you are developing.
For a client in development, register an HTTP redirect using a supported loopback host and the port and path where your application listens:
http://localhost:43821/callbackhttp://127.0.0.1:43821/callbackhttp://[::1]:43821/callbackYou may choose any available port, but the complete redirect URI sent during authorization must match the registered value exactly. localhost and 127.0.0.1 are different hosts, so register the form your application sends. Non-loopback HTTP hosts, embedded credentials, and URI fragments are not supported.
The user's browser—not Lunch Money's server—connects to the loopback listener. Keep PKCE and state protections in place just as you would for a hosted callback. Before requesting review, also register the HTTPS callback used by the deployed application; the loopback URI can remain available for local testing. After approval, you can add or keep a loopback redirect as long as that production HTTPS callback remains. See after approval.
During development, the client owner can run authorization again whenever they want to repeat the sign-in, budget-account selection, consent, and callback flow. They do not need to revoke the current token first. The authorization server may reuse the current browser login or let the person continue with a different Lunch Money user. Treat the validated /v2/me user/account pair—not previous browser state—as the completed authorization's identity.
To test how the application responds after access is revoked, revoke the current token and make another API request with it. Lunch Money should reject the request, and the application should discard its saved credentials and begin authorization again. The token revocation guide includes copyable curl requests for development testing.
Test with one Lunch Money user authorizing multiple budget accounts, then with a second Lunch Money user authorizing through the same browser or device. For a client registered with me:read, strictly validate the returned id and account_id after every exchange. Store credentials under the authenticated application user and that Lunch Money user/account pair. For a standalone app without its own accounts, use the Lunch Money user/account pair as the local connection identity.
state value, save it with the application user's session, and verify that Lunch Money returns the same value to the callback. Rejecting a missing, changed, or reused value prevents a callback started elsewhere from being attached to the wrong session.scope field and confirm that it contains the complete scope set registered for the client. Do not inspect or parse the access token itself.state, callback errors, and interrupted authorization attempts. Confirm that denial or a failed /v2/me validation leaves all existing connections unchanged.GET /v2/me fail or return an invalid shape after a successful exchange. Confirm that the application saves no unidentified or partial connection.account_id. Confirm that the application stores separate credentials keyed by Lunch Money user id and account_id, without overwriting either connection.budget_name. Confirm that they remain separate by account_id and that the UI disambiguates them only where needed without using the name as a key.First make sure your application can recover without a refresh token. Record when the token response arrives and use expires_in to determine when the access token is expected to expire. After it expires, make a harmless API request and confirm that Lunch Money returns an authentication failure identifying the token as invalid.
Your application should discard the unusable token for that connection and start authorization again. Confirm that the same application user can complete the flow, select the intended budget account, and continue using that connection with the replacement token. This recovery path is required when a client does not have offline_access, and it remains the fallback when a refresh token expires, is revoked, or otherwise stops working. Keep other connections usable while this one recovers.
After reauthorization works, clients registered with offline_access can add and test refresh-token handling. Verify replacement-token storage, concurrent-refresh protection, revocation, and terminal refresh recovery before relying on unattended operation. See token lifecycle and recovery.
Finally, add a production HTTPS redirect and complete the review checklist.
Next: Operate securely.