@lunch-money/developer-docs 2.11.1-preview.8 → 2.11.2-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,10 +45,22 @@ const intro = fs.readFileSync(path.join(docsRoot, 'docs/getting-started.md'), 'u
45
45
  }
46
46
  ],
47
47
  "redirects": [ /* { from, to, status } */ ],
48
- "sidebar": { "docs": [ /* … */ ], "v1": [ /* … */ ] }
48
+ "sidebar": {
49
+ "docs": [
50
+ {
51
+ "section": "OAUTH",
52
+ "collapsed": true, // optional; initially collapse this section
53
+ "items": [ /* { label, path, external? } */ ]
54
+ }
55
+ ],
56
+ "v1": [ /* … */ ]
57
+ }
49
58
  }
50
59
  ```
51
60
 
61
+ Sidebar sections initially appear expanded unless their optional `collapsed`
62
+ property is `true`.
63
+
52
64
  ## Versioning
53
65
 
54
66
  The package version tracks the newest API version this content documents (e.g. `2.11.x`
@@ -0,0 +1,84 @@
1
+ # Documentation style guide
2
+
3
+ Use this guide for hand-written Markdown in `docs/` and `v2/docs/`. Preserve
4
+ intentional conventions in generated pages, the v1 Slate reference, and version
5
+ history entries.
6
+
7
+ ## Voice and structure
8
+
9
+ - Address the reader as “you” and use direct, practical language.
10
+ - Start with the reader's goal before introducing protocol or API details.
11
+ - Use one H1 per page and keep heading levels in logical order.
12
+ - Use sentence case for prose headings. Preserve official names, initialisms,
13
+ endpoint paths, property names, and exact UI labels.
14
+ - Add a next step when a guide belongs to a longer reader journey. Use
15
+ `## Need help?` only when the page provides support options.
16
+
17
+ ## Terminology
18
+
19
+ - Use “Lunch Money” for the product and “Lunchbag Labs, Inc.” only when the
20
+ legal company name is required.
21
+ - Use “Developer Portal,” “Developers page,” and “API reference” consistently.
22
+ Preserve different capitalization only for an exact UI label.
23
+ - Write “v1” and “v2” in prose. Use “V2 API” only where it is an established
24
+ proper label, such as the rendered reference title.
25
+ - Distinguish authentication from authorization, personal access tokens from
26
+ OAuth access tokens, and applications from their registered OAuth clients.
27
+
28
+ ## Code and placeholders
29
+
30
+ - Format endpoints, properties, headers, status codes, commands, filenames,
31
+ scope names, and literal values as code.
32
+ - Use `YOUR_ACCESS_TOKEN` as the generic access-token placeholder. Environment
33
+ variable examples may use `LUNCH_MONEY_ACCESS_TOKEN`.
34
+ - For equivalent multi-language examples, order tabs as JavaScript/Node.js,
35
+ Python, then cURL. Comparison tabs may follow the order that best teaches the
36
+ difference.
37
+ - Keep examples fictional and never include or request real credentials.
38
+
39
+ ## Callouts
40
+
41
+ Use the supported blockquote form:
42
+
43
+ ```markdown
44
+ > [!NOTE] Optional title
45
+ > Supporting content.
46
+ ```
47
+
48
+ - Use `NOTE` for context that affects understanding.
49
+ - Use `TIP` for optional advice or a more effective workflow.
50
+ - Use `WARNING` for credible security, privacy, data-loss, breaking-change, or
51
+ operational risk.
52
+ - Use sentence case for optional callout titles. Do not use HTML line breaks to
53
+ separate callout paragraphs.
54
+
55
+ ## Tabs
56
+
57
+ Use tabs when equivalent examples in multiple languages or a focused comparison
58
+ are easier to understand together:
59
+
60
+ ```markdown
61
+ :::tabs
62
+ @tab JavaScript/Node.js
63
+ JavaScript example
64
+
65
+ @tab Python
66
+ Python example
67
+ :::
68
+ ```
69
+
70
+ Use an `@tab` label for each panel and close the container with `:::`. For
71
+ equivalent language examples, order tabs as JavaScript/Node.js, Python, then
72
+ cURL. Comparison tabs may use the order that best teaches the difference.
73
+
74
+ ## Links and presentation
75
+
76
+ - Use canonical documentation paths from `manifest.json`. Keep aliases only for
77
+ compatibility; do not introduce new links to aliases.
78
+ - Use normal Markdown links for internal navigation. Keep HTML only when it adds
79
+ behavior Markdown cannot express, such as opening an external link in a new
80
+ tab.
81
+ - Avoid deeply nested headings, very wide tables, and long unbroken text that is
82
+ difficult to use in the constrained content column.
83
+ - Remove trailing whitespace and use blank lines, not `<br>`, for Markdown
84
+ structure unless a verified rendering requirement needs HTML.
@@ -1,4 +1,4 @@
1
- # Amounts & Balances
1
+ # Amounts & balances
2
2
 
3
3
  The Lunch Money API uses four properties — `amount`, `balance`, `currency`, and `to_base` — consistently across all objects that deal with money. Understanding how they work will help you build accurate, multi-currency-aware integrations.
4
4
 
@@ -24,7 +24,7 @@ Like `amount`, `balance` is always in the `currency` of the same object and foll
24
24
 
25
25
  ## `currency`
26
26
 
27
- `currency` is an ISO 4217 currency code (e.g., `"usd"`, `"eur"`, `"gbp"`). It is present on every object that carries an `amount` or `balance` and tells you what currency those values are in. See the [Supported Currencies guide](/v2/currencies) for the full list.
27
+ `currency` is an ISO 4217 currency code (e.g., `"usd"`, `"eur"`, `"gbp"`). It is present on every object that carries an `amount` or `balance` and tells you what currency those values are in. See the [Supported currencies guide](/currencies) for the full list.
28
28
 
29
29
  ## `to_base`
30
30
 
@@ -42,7 +42,7 @@ Like `amount`, `balance` is always in the `currency` of the same object and foll
42
42
  - Display amounts and balances in a single consistent currency across a multi-currency account
43
43
  - Perform arithmetic across transactions or accounts in different currencies
44
44
 
45
- ## Sign Convention
45
+ ## Sign convention
46
46
 
47
47
  ### Transaction amounts
48
48
 
@@ -70,10 +70,10 @@ A negative balance indicates the reversed state for that account type:
70
70
  - A savings account in overdraft has a negative `balance`
71
71
  - A credit card where the issuer owes you money (e.g., after a refund or overpayment) has a negative `balance`
72
72
 
73
- > [!NOTE] App Display Setting
73
+ > [!NOTE] App display setting
74
74
  > The Lunch Money app has a setting — **"Show Debits as Negative, Credits as Positive"** — that can flip how amounts are displayed in the UI. This setting is exposed in the API as `debits_as_negative` on the User object. **It has no effect on the API.** The API always returns positive values for debits and negative values for credits regardless of this setting. Apps may read `debits_as_negative` to match the user's preferred display format when showing amounts in their own UI.
75
75
 
76
- ## Exception: Budget and Summary Amounts
76
+ ## Exception: budget and summary amounts
77
77
 
78
78
  Budget objects and summary response objects don't use the transaction sign convention. Direction is conveyed by the **structure of the response** rather than the sign of the value — amounts are always positive magnitudes, and the object type or category flag tells you whether that activity is income or expense.
79
79
 
@@ -1,4 +1,4 @@
1
- # Branding your App
1
+ # Branding your app
2
2
 
3
3
  Building a tool, plugin, or integration on top of Lunch Money? Use the official **Powered by Lunch Money** badge to credit the connection clearly — without implying that your app *is* Lunch Money.
4
4
 
@@ -45,7 +45,7 @@ A few common, low-friction ways to brand an integration:
45
45
 
46
46
  1. **README or docs** — a short "Built with Lunch Money" line plus the Powered by badge linking to <a href="https://lunchmoney.app/" target="_blank" rel="noopener noreferrer">lunchmoney.app</a>
47
47
  2. **App footer or about screen** — the Powered by badge next to your own branding
48
- 3. **Onboarding or connect flow** — official logo when prompting users to authorize or paste an access token
48
+ 3. **Onboarding or connect flow** — official logo when asking users to connect their Lunch Money account through OAuth. Applications intended for other users should not ask them to paste a personal access token; see the [OAuth overview](/oauth)
49
49
  4. **Community listings** — consistent naming ("My Tool for Lunch Money") so users can find and trust your project
50
50
 
51
51
  Keep your own product name primary. Lunch Money branding should signal the connection, not compete with your identity.
@@ -1,15 +1,15 @@
1
- # Supported Currencies
1
+ # Supported currencies
2
2
 
3
3
  Lunch Money supports a wide range of currencies for transactions and accounts. All currency values in the API use three-letter lowercase currency codes in ISO 4217 format.
4
4
 
5
- ## Currency Code Format
5
+ ## Currency code format
6
6
 
7
7
  Currency codes must be:
8
8
  - Three letters
9
9
  - Lowercase
10
10
  - Valid ISO 4217 currency codes
11
11
 
12
- ## Supported Currencies
12
+ ## Supported currencies
13
13
 
14
14
  The following currencies are currently supported in Lunch Money:
15
15
 
@@ -183,7 +183,7 @@ The following currencies are currently supported in Lunch Money:
183
183
  | `zmw` | Zambian Kwacha |
184
184
  | `zwl` | Zimbabwean Dollar |
185
185
 
186
- ## Using Currencies in the API
186
+ ## Using currencies in the API
187
187
 
188
188
  When creating or updating transactions, accounts, or other resources that include currency information, use the three-letter lowercase currency code:
189
189
 
@@ -247,11 +247,11 @@ curl -X POST 'https://api.lunchmoney.dev/v2/transactions' \
247
247
  ```
248
248
  :::
249
249
 
250
- ## Default Currency
250
+ ## Default currency
251
251
 
252
252
  If you don't specify a currency when creating a transaction or account, Lunch Money will default to your account's primary currency. You can check your primary currency by calling the `GET /v2/me` endpoint.
253
253
 
254
- ## Currency Validation
254
+ ## Currency validation
255
255
 
256
256
  The API validates that currency codes match the supported list. If you provide an unsupported currency code, you'll receive a validation error:
257
257
 
@@ -268,10 +268,9 @@ The API validates that currency codes match the supported list. If you provide a
268
268
  }
269
269
  ```
270
270
 
271
- ## Requesting New Currencies
271
+ ## Requesting new currencies
272
272
 
273
273
  If your currency is missing from the supported list, please let us know via email at [support@lunchmoney.app](mailto:support@lunchmoney.app) and we'll work on getting it added.
274
274
 
275
- > [!NOTE] Currency Support
275
+ > [!NOTE] Currency support
276
276
  > Currency support is continuously expanding. If you need a currency that's not currently listed, reach out to our support team and we'll prioritize adding it.
277
-
@@ -1,14 +1,14 @@
1
- # Getting Started with the API
1
+ # Getting started with the API
2
2
 
3
3
  Welcome to the Lunch Money developer API! This API has enabled the Lunch Money user community to build a broad set of tools and plug-ins to complement their Lunch Money experience and help other users. This guide will help you get started using the Lunch Money API.
4
4
 
5
5
  Most users interact with their Lunch Money data using the official web or mobile app. Making API calls is another way to interact with your Lunch Money data. You can make API calls that **get** your data for you, allowing you to do other things with it, like generating your own charts or simply archiving your data. You can also make API calls that **change** or **delete** your data. Any changes you make are permanent, just like they would be if you made changes using the web or mobile app.
6
6
 
7
7
  > [!WARNING]
8
- > Changes made via the API are permanent and cannot be undone!<br> Always use a test budget when getting started.
8
+ > Changes made via the API are permanent and cannot be undone. Always use a test budget when getting started.
9
9
 
10
10
 
11
- ## Create a Test Budgeting Account
11
+ ## Create a test budgeting account
12
12
 
13
13
  Since changes to your data made by the API are permanent, the best way to begin interacting with the API is to <a href="https://support.lunchmoney.app/miscellaneous/unlimited-budgeting-accounts" target="_blank" rel="noopener noreferrer">create a new test budgeting account</a> in your existing Lunch Money account. As you start using the API, you can interact with this test account and ensure that your real data is not modified.
14
14
 
@@ -27,9 +27,11 @@ Choose the option to "Set up Demo". This will add categories, accounts, tags and
27
27
  ![Add Demo Data](/images/DemoData.png)
28
28
  :::
29
29
 
30
- ## Getting an access token
30
+ ## Getting a personal access token
31
31
 
32
- Lunch Money API requests are authenticated using the Bearer Token authentication method. In plain English, this means that you will pass a token associated with your budgeting account to Lunch Money. This is so we know which account to operate on and that the request came from someone who can access that account.
32
+ Lunch Money API requests are authenticated using the Bearer Token authentication method. In plain English, this means that you will pass a personal access token associated with your budgeting account to Lunch Money. This is so we know which account to operate on and that the request came from someone who can access that account.
33
+
34
+ This guide uses a personal access token so you can explore the API with your own budgeting account. If you are building an application that other people will connect to Lunch Money, start with the [OAuth overview](/oauth) instead.
33
35
 
34
36
  :::tabs
35
37
 
@@ -39,45 +41,45 @@ Navigate to <a href="https://my.lunchmoney.app/developers" target="_blank" rel="
39
41
  ![Green Budgets Icon](/images/green_budget.png)
40
42
 
41
43
  @tab 2. Request Access Token
42
- In the upper right hand corner of the page, give your access token a label and specify what you are using it for. When you're done, hit the "Request Access Token" button.
44
+ In the upper right hand corner of the page, give your personal access token a label and specify what you are using it for. When you're done, hit the "Request Access Token" button.
43
45
  ![Request Token](/images/RequestAccessToken.png)
44
46
 
45
47
  @tab 3. Save Access Token
46
- After you do this, the web page will show you a long alphanumeric string. This is your access token. Hit the copy button and save this token somewhere safe. It is only shown to you when you create it.
48
+ After you do this, the web page will show you a long alphanumeric string. This is your personal access token. Hit the copy button and save this token somewhere safe. It is only shown to you when you create it.
47
49
  :::
48
50
 
49
- Congratulations! You've got an access token and are ready to make an API request! Later, when you are more comfortable with the API, you can repeat this process to create a new access token associated with your real budget.
51
+ Congratulations! You've got a personal access token and are ready to make an API request! Later, when you are more comfortable with the API, you can repeat this process to create a new personal access token associated with your real budget.
50
52
 
51
53
  > [!WARNING]
52
- > Treat your access tokens like passwords.<br>Don't share them with anyone that you don't trust.
54
+ > Treat your personal access tokens like passwords. Don't share them with anyone you don't trust.
53
55
 
54
- If you ever worry that your access token has been compromised, you can always come back to the Developers page and hit the Revoke button.
56
+ If you ever worry that your personal access token has been compromised, you can always come back to the Developers page and hit the Revoke button.
55
57
 
56
58
  > [!NOTE]
57
- > Give your access tokens descriptive names so you can easily identify and revoke them later if needed.
59
+ > Give your personal access tokens descriptive names so you can easily identify and revoke them later if needed.
58
60
 
59
61
 
60
- ## Using your access token
62
+ ## Using your personal access token
61
63
 
62
64
  When you start to write code that makes API calls, you will need to include this token in each request using an Authorization header. Here is an example curl request:
63
65
 
64
66
  ```bash
65
67
  curl --location 'https://api.lunchmoney.dev/v2/me' \
66
- --header 'Authorization: Bearer <YOUR_ACCESS_TOKEN>'
68
+ --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
67
69
  ```
68
70
 
69
- If this doesn't make sense yet, that's OK!
71
+ If this doesn't make sense yet, that's OK!
70
72
 
71
- There is an easier way to use your access token to make requests. Head over to the [API Reference Documentation](/v2/docs).
73
+ There is an easier way to use your personal access token to make requests. Head over to the [API Reference Documentation](/v2/docs).
72
74
 
73
75
  :::tabs
74
76
 
75
77
  @tab 1. Supply Your Token
76
- Paste your new token into the box that says "Bearer Token" in the server configuration in the upper right hand corner.
78
+ Paste your new token into the box that says "Bearer Token" in the server configuration in the upper right hand corner.
77
79
  ![Bearer Token](/images/PasteBearer.png)
78
80
 
79
81
  @tab 2. Make a Test Request
80
- Scroll down to the section called "Get Current User" and hit the "Test Request" button.
82
+ Scroll down to the section called "Get Current User" and hit the "Test Request" button.
81
83
  ![TestRequest.png](/images/TestRequest.png)
82
84
  :::
83
85
 
@@ -85,14 +87,16 @@ This will pop up a dialog box that you can use to send an API request. This is a
85
87
 
86
88
  From here, you can explore the rest of the Lunch Money API and start thinking about what you might do with it.
87
89
 
88
- ## What Can You Build?
90
+ When you are ready to build an application that other Lunch Money users can connect to, [learn how OAuth grants access without asking users to share personal access tokens](/oauth).
91
+
92
+ ## What can you build?
89
93
 
90
94
  The Lunch Money community has already built a wide variety of tools — automations, importers, dashboards, and more. Check out the <a href="https://lunchmoney.app/developers#community-projects" target="_blank" rel="noopener noreferrer">Developer Tools & Community Projects</a> list for inspiration, or drop by the <a href="https://discord.com/channels/842337014556262411/1134597088504729780" target="_blank" rel="noopener noreferrer">Show and Tell channel</a> on Discord to see what others are sharing.
91
95
 
92
96
  > [!NOTE]
93
97
  > Built something with the API? Let us know and we'll add it to the list!
94
98
 
95
- ## I still need help!
99
+ ## Need help?
96
100
 
97
101
  If you still aren't sure how to get started, we have other resources to help.
98
102
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Welcome to the Lunch Money developer documentation. This site covers the **v2 API** — the current generation of the Lunch Money API — along with guides, a reference for the legacy v1 API, and tools for exploring the API without touching real data.
4
4
 
5
- ## Getting Started
5
+ ## Getting started
6
6
 
7
7
  The v2 API is available at:
8
8
 
@@ -10,15 +10,15 @@ The v2 API is available at:
10
10
  https://api.lunchmoney.dev/v2
11
11
  ```
12
12
 
13
- Get your access token from the <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">Lunch Money app developers page</a> and include it as a Bearer token in every request:
13
+ To explore the API or work with your own budgeting account, create a personal access token on the <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">Developers page</a>. If you are building an application for other Lunch Money users, [use OAuth](/oauth) instead. Both kinds of access token are sent as a Bearer token with each request:
14
14
 
15
15
  ```http
16
16
  Authorization: Bearer YOUR_ACCESS_TOKEN
17
17
  ```
18
18
 
19
- See the [Getting Started guide](/v2/getting-started) for a full walkthrough, including how to create a test budget and make your first request.
19
+ See the [Getting started guide](/getting-started) for a full walkthrough, including how to create a test budget and make your first request.
20
20
 
21
- ## Trying the API Without Real Data
21
+ ## Trying the API without real data
22
22
 
23
23
  The <a href="/v2/docs">interactive API reference</a> lets you make live API requests directly from the documentation — including a **static mock server** you can use to explore the API without an access token or any risk to real data.
24
24
 
@@ -34,7 +34,7 @@ Set your Bearer Token to any string of **11 or more characters** — no real tok
34
34
 
35
35
  :::
36
36
 
37
- ## Client Libraries & SDKs
37
+ ## Client libraries & SDKs
38
38
 
39
39
  An official **TypeScript SDK** is available:
40
40
  - NPM: <a href="https://www.npmjs.com/package/@lunch-money/v2-api-spec" target="_blank" rel="noopener noreferrer">`@lunch-money/v2-api-spec`</a>
@@ -58,6 +58,7 @@ Join the conversation in the <a href="https://lunchmoney.app/discord" target="_b
58
58
 
59
59
  **Useful links:**
60
60
  - <a href="/v2/docs">Interactive API Reference</a>
61
- - [Getting Started Guide](/v2/getting-started)
61
+ - [Getting started guide](/getting-started)
62
+ - [OAuth overview](/oauth)
62
63
  - <a href="https://github.com/lunch-money/awesome-lunchmoney" target="_blank" rel="noopener noreferrer">Awesome Lunch Money Projects</a>
63
64
  - [Contact: devsupport@lunchmoney.app](mailto:devsupport@lunchmoney.app)
package/docs/locales.md CHANGED
@@ -1,4 +1,4 @@
1
- # Supported Locales
1
+ # Supported locales
2
2
 
3
3
  Lunch Money uses locale tags to format numbers and currency amounts in the web
4
4
  and mobile apps. Date presentation is controlled separately by the user-level
@@ -10,14 +10,14 @@ currency symbol or code placement and rendering. It does not change the
10
10
  account's selected currency, numeric values, or the representation of dates,
11
11
  numbers, and amounts in API responses.
12
12
 
13
- ## Locale Tag Format
13
+ ## Locale tag format
14
14
 
15
15
  Each supported value combines a language code and a region code, separated by a
16
16
  hyphen. For example, `en-US` selects English formatting conventions for the
17
17
  United States, while `en-GB` selects English formatting conventions for the
18
18
  United Kingdom.
19
19
 
20
- ## Supported Locales
20
+ ## Supported locales
21
21
 
22
22
  The examples format `123456789` as USD. An account's primary currency determines
23
23
  the currency symbol and number of fraction digits. Exact spacing and symbol
@@ -111,7 +111,7 @@ implementation.
111
111
  | `uk-UA` | Ukrainian | Ukraine | `123 456 789,00 USD` |
112
112
  | `vi-VN` | Vietnamese | Vietnam | `123.456.789,00 US$` |
113
113
 
114
- ## Legacy Locale Tags
114
+ ## Legacy locale tags
115
115
 
116
116
  The supported list retains two legacy language codes for compatibility:
117
117
 
@@ -0,0 +1,80 @@
1
+ # Implement the authorization-code flow
2
+
3
+ After you [register an OAuth client](/oauth/register-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](/oauth), 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.
4
+
5
+ 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](/oauth/native-apps) instead.
6
+
7
+ ## Choose an OAuth library
8
+
9
+ 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:
10
+
11
+ - the authorization-code flow with Proof Key for Code Exchange (PKCE);
12
+ - OAuth authorization-server metadata discovery;
13
+ - secure `state` generation and validation; and
14
+ - confidential-client authentication with HTTP Basic.
15
+
16
+ For Node.js and TypeScript, [`openid-client`](https://github.com/panva/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.
17
+
18
+ ## Configure Lunch Money with discovery
19
+
20
+ 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:
21
+
22
+ `https://api.lunchmoney.dev`
23
+
24
+ Then have it load the OAuth authorization-server metadata document:
25
+
26
+ `https://api.lunchmoney.dev/.well-known/oauth-authorization-server`
27
+
28
+ 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.
29
+
30
+ > [!TIP]
31
+ > 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.
32
+
33
+ ## 1. Start authorization
34
+
35
+ On your server, generate:
36
+
37
+ - a cryptographically random `state` value bound to the user's session;
38
+ - a PKCE `code_verifier`; and
39
+ - its `S256` `code_challenge`.
40
+
41
+ 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`.
42
+
43
+ > [!NOTE] Scopes come from the client registration
44
+ > 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.
45
+
46
+ ## 2. Handle the callback
47
+
48
+ The callback receives either `code` and `state`, or an OAuth `error` and the original `state`. Before exchanging a code:
49
+
50
+ 1. compare `state` with the one-time value stored in the initiating session;
51
+ 2. reject missing, mismatched, or reused state;
52
+ 3. reject unexpected issuer or callback parameters;
53
+ 4. consume the stored state and PKCE verifier once; and
54
+ 5. remove authorization parameters from the visible browser URL before rendering a page.
55
+
56
+ Treat `access_denied` as a normal user decision. Do not log the callback query string.
57
+
58
+ ## 3. Exchange the code
59
+
60
+ 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.
61
+
62
+ 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.
63
+
64
+ ## 4. Call the API
65
+
66
+ Send the access token in the header:
67
+
68
+ ```http
69
+ GET /v2/me HTTP/1.1
70
+ Host: api.lunchmoney.dev
71
+ Authorization: Bearer YOUR_ACCESS_TOKEN
72
+ ```
73
+
74
+ 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](/oauth/scopes).
75
+
76
+ ## 5. Continue or recover
77
+
78
+ Use the response's `expires_in` value to schedule renewal slightly before expiry. Read [token lifecycle and recovery](/oauth/tokens) before implementing refresh, logout, or revocation.
79
+
80
+ Next: [Develop and test your OAuth application](/oauth/development).
@@ -0,0 +1,46 @@
1
+ # OAuth concepts
2
+
3
+ These terms describe who participates in Lunch Money OAuth and what each credential can do.
4
+
5
+ ## Parties in the flow
6
+
7
+ - **User (resource owner):** the Lunch Money user who authorizes a third-party application to make API requests on their behalf for one budgeting account.
8
+ - **Application:** the complete product or service the developer builds. It may contain many features unrelated to Lunch Money; only its Lunch Money OAuth client is managed in the Developer Portal.
9
+ - **Client:** the application's OAuth registration with Lunch Money: its `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.
10
+ - **Authorization server:** the Lunch Money-owned service that presents the Lunch Money sign-in and consent screens, records the user's decision, and issues authorization codes and tokens. The user signs in directly with Lunch Money; the third-party application never receives or sees their Lunch Money login credentials.
11
+ - **Lunch Money API service:** the Lunch Money-owned V2 API, which receives the application's API requests, accepts access tokens, and checks that each request is permitted by the client's scopes.
12
+
13
+ ## Client types and credentials
14
+
15
+ 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**.
16
+
17
+ - **Confidential web client:** Runs on a server and can securely store client secrets. In OAuth terminology, this is called a *confidential client*. Choose this type for a web application—or any other application architecture with a centralized server. Its client secret helps Lunch Money verify that a token request came from the application that registered the client. The client secret and refresh tokens must stay on the server. The application must protect access tokens wherever its architecture uses them, and associate each authorization with the correct application user and authorized Lunch Money budgeting account.
18
+ - **Native or public client:** Runs on a user-controlled device and uses PKCE without a client secret because installed application code cannot keep a secret secure. In OAuth terminology, this is called a *native public client*. Choose this type for a standalone mobile or desktop application. The app stores each user's tokens securely on that user's device—for example, in Keychain on Apple platforms or appropriate Keystore-backed storage on Android—and must avoid exposing them through backups, logs, or application data shared with other apps.
19
+
20
+ 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.
21
+
22
+ ## Redirect URIs
23
+
24
+ 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.
25
+
26
+ 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.
27
+
28
+ ## Scopes and least privilege
29
+
30
+ 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`.
31
+
32
+ The [V2 API reference](/v2/docs) identifies the scope required by each API endpoint. Use it together with the [scope catalog](/oauth/scopes) to select the permissions your application's features require.
33
+
34
+ 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.
35
+
36
+ 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.
37
+
38
+ ## Codes and tokens
39
+
40
+ - An **authorization code** is the short-lived, single-use value Lunch Money sends to the application's callback after the user approves access. The code cannot make API requests by itself. Every client exchanges it at Lunch Money's token endpoint using its PKCE verifier. A confidential client must also authenticate that request with its client ID and client secret. Lunch Money then returns an access token and, when applicable, a refresh token.
41
+ - An **access token** is a credential the application sends as part of each V2 API request. It is relatively short-lived. The token response includes `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.
42
+ - A **refresh token** is a longer-lived but non-permanent credential available only to clients that selected `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.
43
+
44
+ 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.
45
+
46
+ Next: [Register an OAuth client](/oauth/register-client).
@@ -0,0 +1,57 @@
1
+ # Develop and test an OAuth application
2
+
3
+ Use this guide after you have [registered a client](/oauth/register-client) and implemented the [authorization flow](/oauth/authorization-code). 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.
4
+
5
+ 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.
6
+
7
+ > [!NOTE] Development access is owner-only
8
+ > While an OAuth client is in development, only the Lunch Money user who owns it can authorize the application. Your team should have the developer doing most of the initial Lunch Money work create and own the client so they can test the complete flow with their budgeting accounts. Other team members cannot authorize the application until the client has been reviewed and approved.
9
+
10
+ ## Set up a safe test environment
11
+
12
+ Use a separate Lunch Money test budgeting account when exercising create, update, or delete operations. The [Getting Started guide](/getting-started#create-a-test-budgeting-account) walks through creating one and adding sample data.
13
+
14
+ Keep production client secrets, tokens, and user data out of test fixtures, logs, screenshots, and bug reports.
15
+
16
+ ## Local loopback callbacks
17
+
18
+ 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.
19
+
20
+ For a client in development, register an HTTP redirect using a supported loopback host and the port and path where your application listens:
21
+
22
+ - Hostname: `http://localhost:43821/callback`
23
+ - IPv4: `http://127.0.0.1:43821/callback`
24
+ - IPv6: `http://[::1]:43821/callback`
25
+
26
+ You 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.
27
+
28
+ 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.
29
+
30
+ > [!NOTE] Test an approved client with your development team
31
+ > After a client is approved, other team members can continue developing and testing the application's Lunch Money functionality. If the approved client has a loopback redirect registered, each developer who can run the application locally may authorize access to their own Lunch Money budgeting account. The client ID is public, but developers working on a confidential web client also need access to its client secret through your team's secure credential-management process. Do not share access tokens or refresh tokens between developers.
32
+
33
+ ## Repeat or reset authorization
34
+
35
+ During development, the client owner can run authorization again whenever they want to repeat the sign-in, budgeting-account selection, consent, and callback flow. They do not need to revoke the current token first; a new successful authorization replaces their previous active authorization for that client.
36
+
37
+ 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](/oauth/tokens#revoke-access) includes copyable `curl` requests for development testing.
38
+
39
+ ## Test the complete client
40
+
41
+ 1. Complete authorization. For each attempt, your application should create a random `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.
42
+ 2. Keep the PKCE verifier with that same authorization attempt and use it when exchanging the returned code. Confirm that an exchange with a missing or changed verifier fails; this prevents someone who intercepts the code from using it.
43
+ 3. Read the token response's `scope` field and confirm that it contains the complete scope set registered for the client. Do not inspect or parse the access token itself.
44
+ 4. Call every scope-dependent feature, including negative permission cases.
45
+ 5. Test user denial, missing or changed `state`, callback errors, and interrupted authorization attempts.
46
+
47
+ ## Test reauthorization before refresh
48
+
49
+ 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.
50
+
51
+ Your application should discard the unusable token and start authorization again. Confirm that the same application user can complete the flow, select a budgeting account, and continue using the application 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.
52
+
53
+ 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](/oauth/tokens).
54
+
55
+ Finally, add a production HTTPS redirect and complete the [review checklist](/oauth/review-and-approval).
56
+
57
+ Next: [Operate securely](/oauth/security).
@@ -0,0 +1,28 @@
1
+ # OAuth for Lunch Money integrations
2
+
3
+ OAuth lets your application access Lunch Money on behalf of a user without asking that person to copy and share a personal access token. **If you are building an application for anyone other than yourself, use OAuth.** It gives each user a familiar Lunch Money sign-in and consent experience while keeping their personal access token out of your application.
4
+
5
+ ![OAuth authorization-code flow across your application, the Lunch Money user, and Lunch Money. The application redirects the user's browser, Lunch Money handles sign-in and presents the budgeting-account and permission choices, the user approves access, Lunch Money returns an authorization code, and the application exchanges it for tokens and calls the API.](/v2/images/oauth-authorization-flow.svg)
6
+
7
+ ## Choose OAuth or a personal access token
8
+
9
+ | Question | Personal access token | OAuth client |
10
+ | --- | --- | --- |
11
+ | Whose data can it access? | One budgeting account belonging to the user who created the token | One budgeting account selected by each user who authorizes the application |
12
+ | Best fit | API exploration, one-off scripts, and short-lived work on your own account | Persistent integrations and applications intended for other users |
13
+ | How is access granted? | The user creates a token on the [Developers page](https://my.lunchmoney.app/developers) in the Lunch Money web app | The user signs in and approves the permissions requested by the application |
14
+ | Credential handling | The user keeps the token and sends it with their own API requests; third-party applications should use OAuth instead of asking users to share one | The authorization flow delivers application-specific tokens without asking for a personal token |
15
+ | Permissions | Full access to the Lunch Money APIs available for that budgeting account, with no fine-grained permission controls | Only the permissions selected when the OAuth client was registered |
16
+ | Lifecycle | Created and revoked by the user | Short-lived access tokens and optional finite refresh access; the user can revoke the application's access |
17
+
18
+ Personal access tokens remain useful for quick work on your own account. OAuth is the recommended model for applications and integrations that other Lunch Money users will connect to, as well as automations that need to run over time.
19
+
20
+ ## What limits access
21
+
22
+ An OAuth client is an application's registration with Lunch Money. When a developer registers the client, they select the scopes—the specific permissions—the application needs. Later, when a Lunch Money user authorizes the application, Lunch Money shows them that complete permission set before they approve access. Choose only the permissions the application's features require. A focused permission request is easier for users to understand and trust, and reduces the risk of the application reading or changing data it does not need.
23
+
24
+ ## Before you start
25
+
26
+ You need an active Lunch Money account to [register and manage an OAuth client](/oauth/applications) for your application. During development, only the client owner can authorize the application. Approval is required before other Lunch Money users can authorize it.
27
+
28
+ Start with [OAuth concepts](/oauth/concepts), [register a client](/oauth/register-client), and then [implement the authorization-code flow](/oauth/authorization-code). Use the [scope catalog](/oauth/scopes) to plan permissions and [troubleshooting](/oauth/troubleshooting) when a flow fails.