@lunch-money/developer-docs 2.11.0 → 2.11.1-docs.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.
@@ -6,10 +6,10 @@ The Lunch Money API uses offset-based pagination for the `GET /transactions` end
6
6
 
7
7
  When retrieving transactions using `GET /transactions`, the API supports pagination through the `limit` and `offset` query parameters. By default, the endpoint returns up to 1000 transactions per request. If more transactions match your filter criteria, the response includes a `has_more` property set to `true`, indicating that additional pages are available.
8
8
 
9
- > [!NOTE] Pagination Scope
9
+ > [!NOTE] Pagination scope
10
10
  > Pagination works with all filter parameters including date ranges, account IDs, categories, tags, and status filters. The pagination applies to the filtered result set.
11
11
 
12
- ## How Pagination Works
12
+ ## How pagination works
13
13
 
14
14
  ### Parameters
15
15
 
@@ -24,13 +24,13 @@ When retrieving transactions using `GET /transactions`, the API supports paginat
24
24
  - Minimum: `0`
25
25
  - Use this to fetch subsequent pages of results
26
26
 
27
- ### Response Property
27
+ ### Response property
28
28
 
29
29
  - **`has_more`**: A boolean property in the response indicating whether more transactions are available
30
30
  - `true`: More transactions match your filter criteria and are available on subsequent pages
31
31
  - `false`: All matching transactions have been returned
32
32
 
33
- ### Basic Pagination Flow
33
+ ### Basic pagination flow
34
34
 
35
35
  1. Make your first request (optionally with `limit` specified, defaults to 1000)
36
36
  2. Check the `has_more` property in the response
@@ -39,7 +39,7 @@ When retrieving transactions using `GET /transactions`, the API supports paginat
39
39
 
40
40
  ## Examples
41
41
 
42
- ### Basic Pagination
42
+ ### Basic pagination
43
43
 
44
44
  Here's how to fetch transactions page by page:
45
45
 
@@ -61,10 +61,10 @@ async function getAllTransactions(accessToken, limit = 1000) {
61
61
 
62
62
  const data = await response.json();
63
63
  allTransactions.push(...data.transactions);
64
-
64
+
65
65
  hasMore = data.has_more;
66
66
  offset += limit;
67
-
67
+
68
68
  console.log(`Fetched ${data.transactions.length} transactions (total: ${allTransactions.length})`);
69
69
  }
70
70
 
@@ -84,22 +84,22 @@ def get_all_transactions(access_token, limit=1000):
84
84
  all_transactions = []
85
85
  offset = 0
86
86
  has_more = True
87
-
87
+
88
88
  headers = {
89
89
  'Authorization': f'Bearer {access_token}'
90
90
  }
91
-
91
+
92
92
  while has_more:
93
93
  url = f'https://api.lunchmoney.dev/v2/transactions?limit={limit}&offset={offset}'
94
94
  response = requests.get(url, headers=headers)
95
95
  data = response.json()
96
-
96
+
97
97
  all_transactions.extend(data['transactions'])
98
98
  has_more = data['has_more']
99
99
  offset += limit
100
-
100
+
101
101
  print(f"Fetched {len(data['transactions'])} transactions (total: {len(all_transactions)})")
102
-
102
+
103
103
  return all_transactions
104
104
 
105
105
  # Usage
@@ -119,18 +119,18 @@ ALL_TRANSACTIONS="[]"
119
119
 
120
120
  while [ "$HAS_MORE" = "true" ]; do
121
121
  echo "Fetching transactions with offset=$OFFSET, limit=$LIMIT..."
122
-
122
+
123
123
  RESPONSE=$(curl -s -X GET \
124
124
  "https://api.lunchmoney.dev/v2/transactions?limit=$LIMIT&offset=$OFFSET" \
125
125
  -H "Authorization: Bearer $ACCESS_TOKEN")
126
-
126
+
127
127
  TRANSACTIONS=$(echo $RESPONSE | jq -r '.transactions')
128
128
  HAS_MORE=$(echo $RESPONSE | jq -r '.has_more')
129
-
129
+
130
130
  # Merge transactions (simplified - in practice you'd want proper JSON merging)
131
131
  COUNT=$(echo $TRANSACTIONS | jq 'length')
132
132
  echo "Fetched $COUNT transactions"
133
-
133
+
134
134
  OFFSET=$((OFFSET + LIMIT))
135
135
  done
136
136
 
@@ -138,7 +138,7 @@ echo "All transactions fetched"
138
138
  ```
139
139
  :::
140
140
 
141
- ### Pagination with Date Filters
141
+ ### Pagination with date filters
142
142
 
143
143
  Pagination works seamlessly with date range filters:
144
144
 
@@ -166,7 +166,7 @@ async function getTransactionsByDateRange(accessToken, startDate, endDate) {
166
166
 
167
167
  const data = await response.json();
168
168
  allTransactions.push(...data.transactions);
169
-
169
+
170
170
  hasMore = data.has_more;
171
171
  offset += limit;
172
172
  }
@@ -192,9 +192,9 @@ def get_transactions_by_date_range(access_token, start_date, end_date):
192
192
  offset = 0
193
193
  has_more = True
194
194
  limit = 1000
195
-
195
+
196
196
  headers = {'Authorization': f'Bearer {access_token}'}
197
-
197
+
198
198
  while has_more:
199
199
  params = {
200
200
  'start_date': start_date,
@@ -202,15 +202,15 @@ def get_transactions_by_date_range(access_token, start_date, end_date):
202
202
  'limit': limit,
203
203
  'offset': offset
204
204
  }
205
-
205
+
206
206
  url = f"https://api.lunchmoney.dev/v2/transactions?{urlencode(params)}"
207
207
  response = requests.get(url, headers=headers)
208
208
  data = response.json()
209
-
209
+
210
210
  all_transactions.extend(data['transactions'])
211
211
  has_more = data['has_more']
212
212
  offset += limit
213
-
213
+
214
214
  return all_transactions
215
215
 
216
216
  # Usage: Get all transactions for January 2024
@@ -236,17 +236,17 @@ while [ "$HAS_MORE" = "true" ]; do
236
236
  RESPONSE=$(curl -s -X GET \
237
237
  "https://api.lunchmoney.dev/v2/transactions?start_date=$START_DATE&end_date=$END_DATE&limit=$LIMIT&offset=$OFFSET" \
238
238
  -H "Authorization: Bearer $ACCESS_TOKEN")
239
-
239
+
240
240
  HAS_MORE=$(echo $RESPONSE | jq -r '.has_more')
241
241
  COUNT=$(echo $RESPONSE | jq -r '.transactions | length')
242
242
  echo "Fetched $COUNT transactions (offset=$OFFSET)"
243
-
243
+
244
244
  OFFSET=$((OFFSET + LIMIT))
245
245
  done
246
246
  ```
247
247
  :::
248
248
 
249
- ### Handling the `has_more` Flag
249
+ ### Handling the `has_more` flag
250
250
 
251
251
  Always check the `has_more` property to determine if you need to fetch more pages:
252
252
 
@@ -262,7 +262,7 @@ async function fetchTransactionsPage(accessToken, limit = 1000, offset = 0) {
262
262
  });
263
263
 
264
264
  const data = await response.json();
265
-
265
+
266
266
  return {
267
267
  transactions: data.transactions,
268
268
  hasMore: data.has_more,
@@ -288,10 +288,10 @@ import requests
288
288
  def fetch_transactions_page(access_token, limit=1000, offset=0):
289
289
  url = f'https://api.lunchmoney.dev/v2/transactions?limit={limit}&offset={offset}'
290
290
  headers = {'Authorization': f'Bearer {access_token}'}
291
-
291
+
292
292
  response = requests.get(url, headers=headers)
293
293
  data = response.json()
294
-
294
+
295
295
  return {
296
296
  'transactions': data['transactions'],
297
297
  'has_more': data['has_more'],
@@ -335,9 +335,9 @@ fi
335
335
  ```
336
336
  :::
337
337
 
338
- ## Best Practices
338
+ ## Best practices
339
339
 
340
- ### 1. Use Appropriate Limit Values
340
+ ### 1. Use appropriate limit values
341
341
 
342
342
  Choose a `limit` value that balances performance and number of requests:
343
343
 
@@ -353,7 +353,7 @@ const response = await fetch('/v2/transactions?limit=1000');
353
353
  const response = await fetch('/v2/transactions?limit=500');
354
354
  ```
355
355
 
356
- ### 2. Always Check `has_more`
356
+ ### 2. Always check `has_more`
357
357
 
358
358
  Don't assume you've received all results. Always check the `has_more` property:
359
359
 
@@ -375,7 +375,7 @@ while (hasMore) {
375
375
  }
376
376
  ```
377
377
 
378
- ### 3. Combine with Date Ranges When Possible
378
+ ### 3. Combine with date ranges when possible
379
379
 
380
380
  If you know the date range you need, use `start_date` and `end_date` parameters to reduce the result set size:
381
381
 
@@ -387,12 +387,12 @@ const response = await fetch(
387
387
 
388
388
  // ❌ Less efficient: Fetches all transactions then filters client-side
389
389
  const allTransactions = await fetchAllTransactions();
390
- const janTransactions = allTransactions.filter(t =>
390
+ const janTransactions = allTransactions.filter(t =>
391
391
  t.date >= '2024-01-01' && t.date <= '2024-01-31'
392
392
  );
393
393
  ```
394
394
 
395
- ### 4. Handle Edge Cases
395
+ ### 4. Handle edge cases
396
396
 
397
397
  - **Empty results**: The `transactions` array will be empty, and `has_more` will be `false`
398
398
  - **Exact page boundary**: If the number of results is exactly divisible by your limit, `has_more` will be `false` on the last page
@@ -406,24 +406,24 @@ async function safeFetchTransactions(accessToken, limit = 1000, offset = 0) {
406
406
  headers: { 'Authorization': `Bearer ${accessToken}` }
407
407
  }
408
408
  );
409
-
409
+
410
410
  if (!response.ok) {
411
411
  throw new Error(`API error: ${response.status}`);
412
412
  }
413
-
413
+
414
414
  const data = await response.json();
415
-
415
+
416
416
  // Handle empty results
417
417
  if (data.transactions.length === 0 && !data.has_more) {
418
418
  console.log('No transactions found');
419
419
  return [];
420
420
  }
421
-
421
+
422
422
  return data;
423
423
  }
424
424
  ```
425
425
 
426
- ### 5. Implement Rate Limit Awareness
426
+ ### 5. Implement rate limit awareness
427
427
 
428
428
  When paginating through many pages, be mindful of rate limits. Consider adding delays between requests:
429
429
 
@@ -439,7 +439,7 @@ async function getAllTransactionsWithRateLimit(accessToken) {
439
439
  allTransactions.push(...data.transactions);
440
440
  hasMore = data.has_more;
441
441
  offset += limit;
442
-
442
+
443
443
  // Small delay to avoid hitting rate limits
444
444
  if (hasMore) {
445
445
  await new Promise(resolve => setTimeout(resolve, 100));
@@ -452,7 +452,7 @@ async function getAllTransactionsWithRateLimit(accessToken) {
452
452
 
453
453
  ## Troubleshooting
454
454
 
455
- ### Common Issues
455
+ ### Common issues
456
456
 
457
457
  **Issue**: Getting duplicate transactions across pages
458
458
 
@@ -506,7 +506,7 @@ const data = await fetch('/v2/transactions?start_date=2024-01-01&end_date=2024-0
506
506
  // data.transactions.length might be 200, and has_more will be false
507
507
  ```
508
508
 
509
- ## Need Help?
509
+ ## Need help?
510
510
 
511
511
  If you're experiencing pagination issues that can't be resolved through the techniques described above:
512
512
 
@@ -514,4 +514,3 @@ If you're experiencing pagination issues that can't be resolved through the tech
514
514
  - Verify that you're checking the `has_more` property on each response
515
515
  - Consider using date range filters to reduce the result set size
516
516
  - [Email our developer advocate](mailto:jp@lunchmoney.app) if you need assistance with pagination implementation
517
-
@@ -1,4 +1,4 @@
1
- # Rate Limiting
1
+ # Rate limiting
2
2
 
3
3
  The Lunch Money API implements rate limiting to ensure fair usage and prevent abuse of API resources. This guide explains how rate limiting works and how to monitor your rate limit status using response headers.
4
4
 
@@ -9,20 +9,20 @@ Rate limiting is applied to all requests to the `/v1/` and `/v2/` endpoints and
9
9
 
10
10
  If you exceed this limit, you will receive a `429 Too Many Requests` response.
11
11
 
12
- > [!NOTE] Rate Limit Scope
12
+ > [!NOTE] Rate limit scope
13
13
  > Rate limiting is applied per IP address. Requests from the same IP address share the same rate limit quotas.
14
14
 
15
- ## Rate Limit Response
15
+ ## Rate limit response
16
16
 
17
17
  When you exceed a rate limit, the API returns a `429 Too Many Requests` response:
18
18
 
19
- ### HTTP Status Code
19
+ ### HTTP status code
20
20
 
21
21
  ```
22
22
  429 Too Many Requests
23
23
  ```
24
24
 
25
- ### Response Body
25
+ ### Response body
26
26
 
27
27
  The response body follows the standard v2 error format:
28
28
 
@@ -37,11 +37,11 @@ The response body follows the standard v2 error format:
37
37
  }
38
38
  ```
39
39
 
40
- ### Response Headers
40
+ ### Response headers
41
41
 
42
42
  The API includes rate limit information in response headers for all requests (both successful and rate-limited). You can inspect these headers to monitor your current rate limit status and determine when you can make additional requests.
43
43
 
44
- #### Standard Headers (RFC Draft 7)
44
+ #### Standard headers (RFC Draft 7)
45
45
 
46
46
  The API includes standard rate limit headers in all responses:
47
47
 
@@ -56,12 +56,12 @@ RateLimit-Remaining: 3
56
56
  RateLimit-Reset: 1704067200
57
57
  ```
58
58
 
59
- #### Legacy Headers
59
+ #### Legacy headers
60
60
 
61
61
  For backward compatibility, the API also includes legacy `X-RateLimit-*` headers:
62
62
 
63
63
  - **`X-RateLimit-Limit`**: The maximum number of requests allowed per window
64
- - **`X-RateLimit-Remaining`**: The number of requests remaining in the current window
64
+ - **`X-RateLimit-Remaining`**: The number of requests remaining in the current window
65
65
  - **`X-RateLimit-Reset`**: The time (in seconds since Unix epoch) when the rate limit window resets
66
66
 
67
67
  Example headers:
@@ -71,7 +71,7 @@ X-RateLimit-Remaining: 3
71
71
  X-RateLimit-Reset: 1704067200
72
72
  ```
73
73
 
74
- #### Retry-After Header
74
+ #### `Retry-After` header
75
75
 
76
76
  When you receive a `429 Too Many Requests` response, the API includes a `Retry-After` header indicating how many seconds you should wait before retrying:
77
77
 
@@ -81,12 +81,12 @@ Retry-After: 45
81
81
 
82
82
  This value represents the time until the rate limit window resets (rounded up to the nearest second).
83
83
 
84
- > [!TIP] Using Retry-After
84
+ > [!TIP] Using `Retry-After`
85
85
  > Always respect the `Retry-After` header value when implementing retry logic. Waiting for the specified duration ensures you don't waste requests on premature retries.
86
86
 
87
- ## Monitoring Rate Limits
87
+ ## Monitoring rate limits
88
88
 
89
- ### Reading Rate Limit Headers
89
+ ### Reading rate limit headers
90
90
 
91
91
  You can monitor your rate limit status by inspecting the headers in every API response, even successful ones. This allows you to proactively slow down your request rate before hitting the limit.
92
92
 
@@ -95,12 +95,12 @@ You can monitor your rate limit status by inspecting the headers in every API re
95
95
  ```javascript
96
96
  async function makeRequest(url, options) {
97
97
  const response = await fetch(url, options);
98
-
98
+
99
99
  // Check rate limit status from headers
100
100
  const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');
101
101
  const limit = parseInt(response.headers.get('X-RateLimit-Limit') || '0');
102
102
  const resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0');
103
-
103
+
104
104
  if (remaining < 5) {
105
105
  console.warn(`Rate limit warning: ${remaining}/${limit} requests remaining`);
106
106
  const waitTime = resetTime - Math.floor(Date.now() / 1000);
@@ -108,13 +108,13 @@ async function makeRequest(url, options) {
108
108
  console.log(`Rate limit resets in ${waitTime} seconds`);
109
109
  }
110
110
  }
111
-
111
+
112
112
  if (response.status === 429) {
113
113
  const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
114
114
  console.error(`Rate limited! Retry after ${retryAfter} seconds`);
115
115
  throw new Error(`Rate limited: retry after ${retryAfter}s`);
116
116
  }
117
-
117
+
118
118
  return response;
119
119
  }
120
120
  ```
@@ -126,23 +126,23 @@ import time
126
126
 
127
127
  def make_request(url, headers):
128
128
  response = requests.get(url, headers=headers)
129
-
129
+
130
130
  # Check rate limit status
131
131
  remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
132
132
  limit = int(response.headers.get('X-RateLimit-Limit', 0))
133
133
  reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
134
-
134
+
135
135
  if remaining < 5:
136
136
  print(f"Rate limit warning: {remaining}/{limit} requests remaining")
137
137
  wait_time = reset_time - int(time.time())
138
138
  if wait_time > 0:
139
139
  print(f"Rate limit resets in {wait_time} seconds")
140
-
140
+
141
141
  if response.status_code == 429:
142
142
  retry_after = int(response.headers.get('Retry-After', 60))
143
143
  print(f"Rate limited! Retry after {retry_after} seconds")
144
144
  raise Exception(f"Rate limited: retry after {retry_after}s")
145
-
145
+
146
146
  return response
147
147
  ```
148
148
 
@@ -150,7 +150,7 @@ def make_request(url, headers):
150
150
  ```bash
151
151
  # Make a request and capture headers
152
152
  response=$(curl -s -D /tmp/headers.txt -o /tmp/body.txt -w "%{http_code}" \
153
- -H "Authorization: Bearer YOUR_TOKEN" \
153
+ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
154
154
  "https://api.lunchmoney.dev/v2/me")
155
155
 
156
156
  # Extract rate limit headers
@@ -170,7 +170,7 @@ fi
170
170
  ```
171
171
  :::
172
172
 
173
- ### Implementing Exponential Backoff
173
+ ### Implementing exponential backoff
174
174
 
175
175
  When you receive a `429` response, implement exponential backoff with jitter to avoid overwhelming the API:
176
176
 
@@ -178,28 +178,28 @@ When you receive a `429` response, implement exponential backoff with jitter to
178
178
  async function makeRequestWithRetry(url, options, maxRetries = 3) {
179
179
  for (let attempt = 0; attempt < maxRetries; attempt++) {
180
180
  const response = await fetch(url, options);
181
-
181
+
182
182
  if (response.status !== 429) {
183
183
  return response;
184
184
  }
185
-
185
+
186
186
  // Get retry-after header or use exponential backoff
187
187
  const retryAfter = parseInt(response.headers.get('Retry-After') || '0');
188
- const waitTime = retryAfter > 0
188
+ const waitTime = retryAfter > 0
189
189
  ? retryAfter * 1000 // Convert seconds to milliseconds
190
190
  : Math.min(1000 * Math.pow(2, attempt) + Math.random() * 1000, 30000);
191
-
191
+
192
192
  console.log(`Rate limited. Waiting ${waitTime}ms before retry ${attempt + 1}/${maxRetries}`);
193
193
  await new Promise(resolve => setTimeout(resolve, waitTime));
194
194
  }
195
-
195
+
196
196
  throw new Error('Max retries exceeded due to rate limiting');
197
197
  }
198
198
  ```
199
199
 
200
- ## Best Practices
200
+ ## Best practices
201
201
 
202
- ### 1. Monitor Headers Proactively
202
+ ### 1. Monitor headers proactively
203
203
 
204
204
  Don't wait for a `429` response. Check rate limit headers on every request and adjust your request rate accordingly:
205
205
 
@@ -211,7 +211,7 @@ if (remaining < threshold) {
211
211
  }
212
212
  ```
213
213
 
214
- ### 2. Implement Request Queuing
214
+ ### 2. Implement request queuing
215
215
 
216
216
  For applications that need to make many requests, implement a queue system that respects rate limits:
217
217
 
@@ -222,14 +222,14 @@ class RateLimitedQueue {
222
222
  this.remaining = 100; // Start with max
223
223
  this.resetTime = Date.now() + (15 * 60 * 1000);
224
224
  }
225
-
225
+
226
226
  async enqueue(requestFn) {
227
227
  return new Promise((resolve, reject) => {
228
228
  this.queue.push({ requestFn, resolve, reject });
229
229
  this.processQueue();
230
230
  });
231
231
  }
232
-
232
+
233
233
  async processQueue() {
234
234
  if (this.queue.length === 0 || this.remaining <= 0) {
235
235
  if (this.remaining <= 0 && this.resetTime > Date.now()) {
@@ -238,15 +238,15 @@ class RateLimitedQueue {
238
238
  }
239
239
  return;
240
240
  }
241
-
241
+
242
242
  const { requestFn, resolve, reject } = this.queue.shift();
243
243
  try {
244
244
  const response = await requestFn();
245
-
245
+
246
246
  // Update rate limit status from headers
247
247
  this.remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0');
248
248
  this.resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000;
249
-
249
+
250
250
  resolve(response);
251
251
  this.processQueue(); // Process next item
252
252
  } catch (error) {
@@ -256,7 +256,7 @@ class RateLimitedQueue {
256
256
  }
257
257
  ```
258
258
 
259
- ### 3. Cache Responses When Possible
259
+ ### 3. Cache responses when possible
260
260
 
261
261
  Reduce the number of API calls by caching responses locally:
262
262
 
@@ -267,24 +267,24 @@ const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
267
267
  async function getCachedRequest(url, options) {
268
268
  const cacheKey = `${url}:${JSON.stringify(options)}`;
269
269
  const cached = cache.get(cacheKey);
270
-
270
+
271
271
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
272
272
  return cached.data;
273
273
  }
274
-
274
+
275
275
  const response = await fetch(url, options);
276
276
  const data = await response.json();
277
-
277
+
278
278
  cache.set(cacheKey, {
279
279
  data,
280
280
  timestamp: Date.now()
281
281
  });
282
-
282
+
283
283
  return data;
284
284
  }
285
285
  ```
286
286
 
287
- ### 4. Batch Operations When Available
287
+ ### 4. Batch operations when available
288
288
 
289
289
  Use bulk endpoints when available to reduce the number of requests:
290
290
 
@@ -309,7 +309,7 @@ await fetch('/v2/categories', {
309
309
  ```
310
310
  :::
311
311
 
312
- ### 5. Limit Crypto Refresh Polling
312
+ ### 5. Limit crypto refresh polling
313
313
 
314
314
  Crypto refresh requests can be bursty if you poll too often. For `POST /v2/crypto/synced/{id}/refresh`:
315
315
 
@@ -319,14 +319,14 @@ Crypto refresh requests can be bursty if you poll too often. For `POST /v2/crypt
319
319
 
320
320
  ## Troubleshooting
321
321
 
322
- ### Common Issues
322
+ ### Common issues
323
323
 
324
324
  **Issue**: Rate limits resetting unexpectedly
325
325
 
326
326
  **Solution**: Rate limits are tracked per IP address. If you're behind a proxy or load balancer, multiple clients may share the same IP and exhaust the shared quota.
327
327
 
328
328
 
329
- ## Need Help?
329
+ ## Need help?
330
330
 
331
331
  If you're experiencing rate limiting issues that can't be resolved through the techniques described above:
332
332
 
@@ -73,7 +73,7 @@ const token = process.env.LUNCH_MONEY_ACCESS_TOKEN;
73
73
  > [!WARNING]
74
74
  > Avoid pasting your access token directly into an AI chat window. Treat it like a password — store it in an environment variable, a `.env` file excluded from source control, or your operating system's secret store.
75
75
 
76
- ## Best Practices
76
+ ## Best practices
77
77
 
78
78
  1. **Start with a test budget** — API changes are permanent. Use a test budget while you're learning so your real data stays safe. See the [Getting Started guide](/getting-started) for instructions.
79
79
 
@@ -97,7 +97,7 @@ If you want to experiment, here are a few low-risk starting points:
97
97
 
98
98
  Start small, and use a test budget while you're learning.
99
99
 
100
- ## Need Help?
100
+ ## Need help?
101
101
 
102
102
  - Join the <a href="https://lunchmoney.app/discord" target="_blank" rel="noopener noreferrer">Lunch Money Discord</a> and ask in the **#developer-api** channel
103
103
  - [Email our developer advocate](mailto:jp@lunchmoney.app)
package/manifest.json CHANGED
@@ -41,6 +41,14 @@
41
41
  "type": "markdown",
42
42
  "aliases": ["/v2/currencies"]
43
43
  },
44
+ {
45
+ "path": "/locales",
46
+ "file": "docs/locales.md",
47
+ "title": "Supported Locales",
48
+ "section": "GUIDES",
49
+ "type": "markdown",
50
+ "aliases": ["/v2/locales"]
51
+ },
44
52
  {
45
53
  "path": "/amounts-and-balances",
46
54
  "file": "docs/amounts-and-balances.md",
@@ -57,6 +65,14 @@
57
65
  "type": "markdown",
58
66
  "aliases": ["/v2/using-with-ai"]
59
67
  },
68
+ {
69
+ "path": "/branding-your-app",
70
+ "file": "docs/branding-your-app.md",
71
+ "title": "Branding your App",
72
+ "section": "GUIDES",
73
+ "type": "markdown",
74
+ "aliases": ["/v2/branding-your-app"]
75
+ },
60
76
  {
61
77
  "path": "/v2/overview",
62
78
  "file": "v2/docs/intro-to-v2.md",
@@ -191,7 +207,9 @@
191
207
  { "label": "Pagination", "path": "/pagination" },
192
208
  { "label": "Rate Limiting", "path": "/rate-limits" },
193
209
  { "label": "Supported Currencies", "path": "/currencies" },
194
- { "label": "Using the API with AI", "path": "/using-with-ai" }
210
+ { "label": "Supported Locales", "path": "/locales" },
211
+ { "label": "Using the API with AI", "path": "/using-with-ai" },
212
+ { "label": "Branding your App", "path": "/branding-your-app" }
195
213
  ]},
196
214
  { "section": "REFERENCE", "items": [
197
215
  { "label": "v2 API Overview", "path": "/v2/overview" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunch-money/developer-docs",
3
- "version": "2.11.0",
3
+ "version": "2.11.1-docs.1",
4
4
  "description": "Developer documentation content for Lunch Money APIs",
5
5
  "exports": {
6
6
  ".": "./package.json",
package/v1/_user.md CHANGED
@@ -11,8 +11,8 @@ This API (v1) will not progress to a generally available state. For new projects
11
11
  | user_id | number | false | Unique identifier for user |
12
12
  | user_name | string | false | User's name |
13
13
  | user_email | string | false | User's email |
14
- | account_id | number | false | Unique identifier for the associated budgeting account |
15
- | budget_name | string | false | Name of the associated budgeting account |
14
+ | account_id | number | false | Unique identifier for the associated budget account |
15
+ | budget_name | string | false | Name of the associated budget account |
16
16
  | primary_currency|string | false | Primary currency from user's settings |
17
17
  | api_key_label | string | true | User-defined label of the developer API key used. Returns null if nothing has been set. |
18
18