OAUTH PREVIEW — Create and manage OAuth clients in the Developer PortalStable portal →
Implement Authorization

Implement the authorization-code flow

After you register an OAuth client, your application uses its settings—including its client ID, client secret, and registered redirect URI—to implement the authorization flow. As shown in the OAuth overview, your application sends the user to Lunch Money, Lunch Money returns an authorization code to your callback, and your application exchanges that code for tokens.

This guide walks through that process for a Confidential web client. Your server handles the callback and token exchange and keeps the client secret and refresh tokens secure. If you are building a standalone mobile or desktop application, read the native application guidance instead.

Choose an OAuth library

OAuth libraries handle much of the protocol work for you, including generating PKCE values, building authorization requests, validating callback state, and exchanging authorization codes. Choose a well-maintained OAuth 2.0 client library for your language and application framework. Look for support for:

For Node.js and TypeScript, openid-client is one maintained option. Despite its name, using it does not mean that Lunch Money supports OpenID Connect identity scopes, ID tokens, or UserInfo.

Configure Lunch Money with discovery

Your OAuth library needs to know where to send the user for authorization, where to exchange codes for tokens, and which protocol features Lunch Money supports. Instead of configuring each value separately, give the library the Lunch Money issuer:

https://api.lunchmoney.dev

Then have it load the OAuth authorization-server metadata document:

https://api.lunchmoney.dev/.well-known/oauth-authorization-server

The metadata document is a machine-readable description of Lunch Money's authorization, token, and revocation endpoints, supported client-authentication methods, and PKCE method. Using it allows your library to obtain the current OAuth configuration without your application assembling endpoint URLs itself.

The resolved endpoint paths are /oauth/authorize, /oauth/token, and /oauth/revoke. These are useful when debugging, but use metadata discovery when your library supports it.

1. Start authorization

On your server, generate:

Redirect the browser to the discovered authorization endpoint with response_type=code, your client_id, exact redirect_uri, state, code_challenge, and code_challenge_method=S256.

Scopes come from the client registration
You do not need to send scope. If your OAuth library includes it, Lunch Money ignores the requested value and uses the client's complete registered scope set. An authorization request cannot narrow or expand that set; changing scopes requires a replacement client.

2. Handle the callback

The callback receives either code and state, or an OAuth error and the original state. Before exchanging a code:

  1. compare state with the one-time value stored in the initiating session;
  2. reject missing, mismatched, or reused state;
  3. reject unexpected issuer or callback parameters;
  4. consume the stored state and PKCE verifier once; and
  5. remove authorization parameters from the visible browser URL before rendering a page.

Treat access_denied as a normal user decision. Do not log the callback query string.

3. Exchange the code

Send a form-encoded request to the discovered token endpoint with grant_type=authorization_code, the code, exact redirect_uri, and original code_verifier. A confidential client authenticates with HTTP Basic using its client ID and secret. Do this server-side.

Store access_token, token_type, granted scope, and expiration metadata securely. If a refresh_token is returned, keep it server-side as a high-value credential.

4. Call the API

Send the access token in the header:

GET /v2/me HTTP/1.1
Host: api.lunchmoney.dev
Authorization: Bearer YOUR_ACCESS_TOKEN

The operation must be allowed by the token's scope and by the user's access to the selected budgeting account. See the scope catalog.

5. Continue or recover

Use the response's expires_in value to schedule renewal slightly before expiry. Read token lifecycle and recovery before implementing refresh, logout, or revocation.

Next: Develop and test your OAuth application.