These terms describe who participates in Lunch Money OAuth and what each credential can do.
client_id, type, redirect URIs, selected scopes, and—when applicable—client secret. The developer must register this client in the Developer Portal before the application can ask Lunch Money users to authorize API access.A Lunch Money user is the person who signs in to Lunch Money. One user can have access to multiple budget accounts, such as a personal budget, a household budget, and a test budget. Each budget account contains its own financial data. Here, “budget account” means that collection of data, not an individual bank or manually managed account within it.
During OAuth authorization, the user selects one budget account and approves your client's permissions. The resulting OAuth access token is specific to that Lunch Money user and budget account pair, for your client. It does not grant access to every budget account the user can access.
For example, Alex can access both “Household” and “API testing.” If Alex selects “API testing” during authorization, your application's access token operates on that budget account. It cannot use the same token to read or update “Household.” Scopes determine which operations the application may perform within the selected account; they do not add access to other budget accounts.
When applications store OAuth credentials, they should associate the authorization with the application user who started the flow and identify the connection by the Lunch Money user and budget account pair. Two Lunch Money users can both authorize access to the same shared budget account, so account_id alone is not a complete connection identity.
If your client has the me:read scope, call GET /v2/me with the access token. The response identifies both sides of the connection:
| Field | Meaning |
|---|---|
id |
The Lunch Money user's ID |
account_id |
The selected budget account's ID |
budget_name |
The selected budget account's display name |
Use account_id as the stable identifier for the budget account and id as the identifier for the Lunch Money user who completed authorization. Together they identify the Lunch Money side of the connection. For an application with its own accounts, store that pair within the authenticated application user's ownership boundary. A standalone native application without its own account system uses the id and account_id pair as its local connection identity.
Show budget_name so the application user can see which budget they are using, but do not use it as a key: two budget accounts can have the same name. When names collide, add a secondary label such as the account ID only where the UI needs to distinguish them. Access tokens are opaque credentials; obtain this information from the API response rather than parsing the token.
Lunch Money may reuse an existing browser login session, and the authorization screen may let the person continue with a different Lunch Money user. Shared browser state therefore means that a login can be reused when available; it does not guarantee which user will complete authorization. A fresh or ephemeral browser request is also only an intent, not proof of identity.
After every successful code exchange, call and strictly validate GET /v2/me. Treat its id as the Lunch Money user who actually completed authorization and its account_id as the selected budget account. Do not infer that identity from browser cookies, callback fields, budget_name, the user who was active before authorization, or token contents.
Applications that may retain more than one Lunch Money identity should show the active Lunch Money user and which saved connection is the active budget. Provide two distinct actions:
To connect to a new, previously unauthorized, budget account, send the user through authorization again and have them select it. Changing a locally stored account ID does not change which account an existing token can access. Refreshing a token renews access for its existing authorization; it does not select another budget account.
Applications do not need a separate client-side “use another user” action. The ordinary Authorize another budget action starts authorization; Lunch Money handles any login reuse or user switching. After /v2/me identifies the result, make that Lunch Money identity active and show only its connections. Clear or partition the previously displayed profile, configuration, and cached financial data before showing the new identity.
Authorizing a second budget account for the same Lunch Money user creates or reuses that user's connection and does not revoke the first one. Update each connection's credentials and identity together, and keep cached data from one account separate from data loaded for another.
If authorization returns the same Lunch Money user id and budget-account account_id as an existing owned connection, treat it as a reconnection. Atomically replace that connection's stored access-token and refresh-token set with the credentials from the successful exchange. A different Lunch Money user authorizing the same shared account_id creates or updates a separate connection; it must not overwrite the first user's credentials.
When the user chooses to switch between existing authorized budgets, select a saved connection only from the active Lunch Money identity and use that connection's stored access token to make API calls. All account-specific actions must use the active connection. Clear or partition cached financial data when the active connection changes so data from the previous budget is not shown under the new selection. If the active connection is removed, select a documented remaining connection for the same Lunch Money user or enter a disconnected state. Never fall back to another user's hidden connection.
An application may retain credentials for a Lunch Money user who is not currently active when its application-user ownership model permits it. Switching identities should hide the previous user's connections and clear or partition that user's displayed data, but hiding a connection does not revoke it or delete its stored credentials. If that Lunch Money user authorizes again later, the application may make the user's retained connections visible again.
An application may instead delete stored credentials as part of its own sign-out or user-switch policy. Make that policy understandable in the interface. In particular, distinguish disconnecting or remotely revoking a budget-account authorization from forgetting its local credential without revoking remote access.
When a developer registers a client, they must choose a client type based on whether the application code can keep a client secret secure. This choice cannot be changed after the client is registered. The developer selects either Confidential web client or Native or public client.
These client families are not interchangeable. A confidential server-side sample cannot be moved into a native application by embedding its client secret or server-held credentials; use a native-client flow and platform secure storage instead.
Every client receives a client ID that identifies its Lunch Money registration. The client ID is not secret. Both client types also use Proof Key for Code Exchange (PKCE) to bind the authorization response to the application that started the flow.
A redirect URI is the callback address where the Lunch Money authorization server returns control to the application after the user approves or denies access. Lunch Money redirects the user's browser to that address with either a temporary authorization code or information about why authorization did not complete.
The developer registers each permitted redirect URI in advance. For a confidential web client, the URI sent at the start of authorization must exactly match one of those registered values, including its scheme, host, port, path, and query string. A native client's loopback redirect follows the same rule except that its ephemeral port is ignored. Fragments are not allowed. These checks prevent an authorization result from being redirected to an unexpected destination. The application's callback must also avoid acting as an open redirect to another location.
Resource scopes such as transactions:read authorize specific ways of working with Lunch Money data. A scope generally applies to a particular kind of action—such as reading or updating a resource—and only to the relevant API endpoints. Permissions are independent: for example, transactions:update does not also grant transactions:read.
The V2 API reference identifies the scope required by each API endpoint. Use it together with the scope catalog to select the permissions your application's features require.
Scopes are selected when the client is created and cannot be edited later. Every user who authorizes that client sees and grants all—and only—the scopes the developer selected. To change them, create and test a replacement client, complete review when applicable, update your integration, and ask existing users to authorize again. Existing authorizations and tokens do not move to the replacement client.
Select offline_access when your application needs to continue making API requests on a user's behalf for longer than the brief period covered by the initial access token. It allows the application to receive a refresh token, which it can use to maintain access without repeatedly asking the user to sign in and authorize the application. It does not add permission to read or change any Lunch Money data; the client still needs the relevant resource scopes.
expires_in, the number of seconds for which the access token is expected to remain valid, so the application can record when it will expire and obtain a replacement when needed.offline_access. The application sends it to Lunch Money's token endpoint to request a new access token and replacement refresh token without asking the user to authorize again.An application can refresh its access token shortly before it expires or wait until an API response indicates that the access token is no longer valid. If the application does not have a refresh token—or if that token expires, is revoked, or otherwise stops working—it must ask the user to authorize again.
Next: Register an OAuth client.