@lunch-money/v2-api-spec 2.11.0-preview.1 → 2.11.0-preview.15

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.
@@ -2,50 +2,40 @@ openapi: 3.0.2
2
2
  info:
3
3
  title: Lunch Money API - v2
4
4
  description: |-
5
- Welcome to the documentation for the "next version" of the Lunch Money v2 API.This documentation includes proposed updates to the API design that have not yet been released.<p>
6
- This documentation is for the **v2.11.0** release of the API.<p>
7
-
8
- See the [version history](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/version-history) for what is new in this release.
9
- New functionality may only be available in the Mock Service until the release is finalized. <br><br>
10
-
11
- The latest complete implementation of the spec is for the **v2.8.5** release and can be found [here](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/). <br><br>
12
- Feedback on any of the API design is welcome, but we are particularly interested in getting feedback on most recent changes in the [version history](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/version-history).
5
+ Welcome to the Lunch Money v2 API reference. This is the **v2.11.0** spec.
13
6
 
14
- ------------------------------------------------------------------------------------------------
15
- Welcome to the Lunch Money v2 API.
7
+ ### Introduction
16
8
 
17
- A working version of this API is now available through these docs, or directly at:
9
+ The API is available at `https://api.lunchmoney.dev/v2`. Get your access token from the [Lunch Money developers page](https://my.lunchmoney.app/developers).
18
10
 
19
- `https://api.lunchmoney.dev/v2`
20
-
21
- <span class="red-text"><strong>This is in alpha launch of a major API update. It is still subject to change during this alpha review
22
- period and bugs may still exist. We strongly encourage users to use the mock service or create a test budget with sample data as the first step to interacting with the v2 API.</strong></span>
23
- See the [Getting Started Guide](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/getting-started) for more information on using a test budget.<p>
11
+
12
+ **Try it from these docs**
24
13
 
25
- If you are new to the v2 API, you may wish to review the [v2 API Overview of Changes](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/changelog).
14
+ These docs are interactive — use **Test request** on any endpoint to call the API from this page.
15
+ Choose a LIVE or MOCK service from the Server dropdown.
16
+ Requests sent to `https://api.lunchmoney.dev/v2` can <span class="red-text"><strong>change or delete</strong></span> your data and are <span class="red-text"><strong>permanent</strong></span>.
17
+ See the [Getting Started Guide](https://lunchmoney.dev/v2/getting-started) before using the live API.
18
+
19
+ **Static mock server**
26
20
 
27
- ### Static Mock Server
21
+ Explore without risk to real data. Select `http://mock.lunchmoney.dev/v2` in the Server dropdown to work with static mock data.
22
+ POST, PUT, and DELETE requests will return realistic responses, but do not change the mock data.
23
+
28
24
 
29
- You may also use these docs to explore the API using a static mock server endpoint.<p>
30
- This will allow you to become familiar with the API without having to create an access token, and eliminates the possibility of changing real data. <p>
31
- To access this endpoint, select the second endpoint in the "Server" dropdown to the right. When selected, you should see "Static Mock v2 Lunch Money API Server".<br>
32
- When using this server, set your Bearer token to any string with 11 or more characters.
25
+ **Client Libraries & SDKs**
33
26
 
34
- ### Migrating from V1
27
+ An official TypeScript SDK is available on [NPM](https://www.npmjs.com/package/@lunch-money/v2-api-spec) and [GitHub](https://github.com/lunch-money/lunch-money-js-v2). For Python or other languages, see [lunchmoney-clients](https://github.com/juftin/lunchmoney-clients) or generate a client from [this OpenAPI spec](/v2/openapi).
35
28
 
36
- The v2 API is NOT backwards compatible with the v1 API. We encourage developers to review the [Migration Guide](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/migration-guide) to understand the changes and plan their migration.
29
+ **Migrating from v1**
37
30
 
38
- ### Acknowledgments
31
+ The v2 API is not backwards compatible with v1. See the [Migration Guide](https://lunchmoney.dev/v2/migration-guide) for details.
39
32
 
40
- If you have provided feedback on the API during our ongoing design process, **THANK YOU**. We are thrilled that you can finally interact with the working API we built based on your feedback.
41
-
42
- ### Useful links:
43
- - [Getting Started](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/getting-started)
44
- - [v2 API Changelog](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/changelog)
45
- - [Migration Guide](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/migration-guide)
46
- - [Rate Limits](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/rate-limits)
47
- - [Current v1 Lunch Money API Documentation](https://lunchmoney.dev)
48
- - [Awesome Lunch Money Projects](https://github.com/lunch-money/awesome-lunchmoney?tab=readme-ov-file)
33
+ **Useful links**
34
+ - [Getting Started Guide](https://lunchmoney.dev/v2/getting-started)
35
+ - [v2 API Overview](https://lunchmoney.dev/v2/overview)
36
+ - [Version History](https://lunchmoney.dev/v2/version-history)
37
+ - [Migration Guide](https://lunchmoney.dev/v2/migration-guide)
38
+ - [Rate Limits](https://lunchmoney.dev/v2/rate-limits)
49
39
  termsOfService: https://lunchmoney.dev/#current-status
50
40
  contact:
51
41
  email: devsupport@lunchmoney.app
@@ -56,10 +46,9 @@ info:
56
46
 
57
47
  servers:
58
48
  - url: https://api.lunchmoney.dev/v2
59
- description: v2 Lunch Money API Server - changes will affect real data!
60
- # - url: https://mock.lunchmoney.dev/v2
61
- - url: https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/
62
- description: Static mock version of the v2 Lunch Money API Server
49
+ description: ⚠ LIVE — changes real Lunch Money data
50
+ - url: http://mock.lunchmoney.dev/v2
51
+ description: MOCK — static demo data, no API key required
63
52
 
64
53
  tags:
65
54
  - name: me
@@ -126,8 +115,10 @@ tags:
126
115
  description: Learn more about transactions
127
116
  url: https://support.lunchmoney.app/finances/transactions
128
117
  - name: budgets
129
- description: View settings and modify budget amounts.<p> Use the
130
- [/summary](#tag/summary) endpoint to view the budget details performance.
118
+ description: View settings and modify budget amounts.<p> Use
119
+ [/budgets/settings](#tag/budgets/GET/budgets/settings) to view budget
120
+ period settings.<p> Use the [/summary](#tag/summary) endpoint to view
121
+ the budget details performance.
131
122
  externalDocs:
132
123
  description: Learn more about budgets
133
124
  url: https://support.lunchmoney.app/finances/budgets
@@ -155,12 +146,12 @@ components:
155
146
  account_id:
156
147
  type: integer
157
148
  format: int64
158
- description: Unique ID for the linked budgeting account
149
+ description: Unique ID for the current budgeting account
159
150
  budget_name:
160
151
  type: string
161
- description: Name of the linked budgeting account
152
+ description: Name of the current budgeting account
162
153
  primary_currency:
163
- description: Primary currency set in the user's settings
154
+ description: Primary currency for the current budgeting account
164
155
  allOf:
165
156
  - $ref: "#/components/schemas/currencyEnum"
166
157
  api_key_label:
@@ -679,7 +670,6 @@ components:
679
670
  cryptoManualObject:
680
671
  type: object
681
672
  title: manual crypto object
682
- x-internal: true
683
673
  additionalProperties: false
684
674
  properties:
685
675
  id:
@@ -719,13 +709,22 @@ components:
719
709
  description: CoinGecko identifier associated with this balance
720
710
  to_base:
721
711
  type: number
722
- description: Balance converted to the user's primary currency
712
+ nullable: true
713
+ description: Balance converted to the user's primary currency. May be null if no conversion was available.
723
714
  balance_as_of:
724
715
  type: string
725
716
  format: date-time
726
717
  nullable: true
727
- description: Date/time the balance was last updated in ISO 8601
728
- extended format
718
+ description: Date/time the manual balance record was last updated in
719
+ ISO 8601 extended format. This is currently based on the manual
720
+ crypto record's updated_at timestamp.
721
+ exchange_rate_as_of:
722
+ type: string
723
+ format: date-time
724
+ nullable: true
725
+ description: Date/time the exchange rate used to calculate to_base was
726
+ last updated in ISO 8601 extended format. Null when no exchange rate was
727
+ used or no conversion was available.
729
728
  created_by_name:
730
729
  type: string
731
730
  nullable: true
@@ -750,6 +749,7 @@ components:
750
749
  - coingecko_id
751
750
  - to_base
752
751
  - balance_as_of
752
+ - exchange_rate_as_of
753
753
  - created_by_name
754
754
  - created_at
755
755
  - updated_at
@@ -758,14 +758,18 @@ components:
758
758
  cryptoSyncedBalance:
759
759
  type: object
760
760
  title: synced crypto balance object
761
- x-internal: true
762
761
  additionalProperties: false
763
762
  properties:
764
763
  name:
765
764
  type: string
766
765
  minLength: 1
767
766
  maxLength: 45
768
- description: The name of the crypto asset
767
+ description: The asset name for this balance, typically the uppercased currency symbol (e.g. ETH).
768
+ display_name:
769
+ type: string
770
+ nullable: true
771
+ description: Optional display name for the synced crypto asset as set by the user. If `null`,
772
+ clients may derive a display name from syncedCryptoAccount's `provider` + `name`.
769
773
  balance:
770
774
  type: string
771
775
  pattern: ^-?\d+(\.\d{1,18})?$
@@ -783,13 +787,21 @@ components:
783
787
  description: CoinGecko identifier associated with this balance
784
788
  to_base:
785
789
  type: number
786
- description: Balance converted to the user's primary currency
790
+ nullable: true
791
+ description: Balance converted to the user's primary currency. May be null if no conversion was available.
787
792
  balance_as_of:
788
793
  type: string
789
794
  format: date-time
790
795
  nullable: true
791
796
  description: Date/time the balance was last updated in ISO 8601
792
- extended format
797
+ extended format.
798
+ exchange_rate_as_of:
799
+ type: string
800
+ format: date-time
801
+ nullable: true
802
+ description: Date/time the exchange rate used to calculate to_base was
803
+ last updated in ISO 8601 extended format. Null when no exchange rate was
804
+ used or no conversion was available.
793
805
  updated_at:
794
806
  type: string
795
807
  format: date-time
@@ -797,17 +809,18 @@ components:
797
809
  extended format
798
810
  required:
799
811
  - name
812
+ - display_name
800
813
  - balance
801
814
  - symbol
802
815
  - coingecko_id
803
816
  - to_base
804
817
  - balance_as_of
818
+ - exchange_rate_as_of
805
819
  - updated_at
806
820
 
807
821
  syncedCryptoAccount:
808
822
  type: object
809
823
  title: synced crypto account
810
- x-internal: true
811
824
  additionalProperties: false
812
825
  properties:
813
826
  id:
@@ -1072,8 +1085,16 @@ components:
1072
1085
  type: string
1073
1086
  format: date-time
1074
1087
  nullable: true
1075
- description: System defined date/time the balance was last updated in
1076
- ISO 8601 extended format. Ignored if set
1088
+ description: System defined date/time the manual balance record was
1089
+ last updated in ISO 8601 extended format. Ignored if set
1090
+ x-updatable: false
1091
+ exchange_rate_as_of:
1092
+ type: string
1093
+ format: date-time
1094
+ nullable: true
1095
+ description: System defined date/time the exchange rate used to
1096
+ calculate to_base was observed in ISO 8601 extended format. Ignored
1097
+ if set
1077
1098
  x-updatable: false
1078
1099
  created_by_name:
1079
1100
  type: string
@@ -1353,10 +1374,13 @@ components:
1353
1374
  - $ref: "#/components/schemas/accountTypeEnum"
1354
1375
  subtype:
1355
1376
  type: string
1356
- description: If set, an optional account subtype. Examples include<br>
1377
+ nullable: true
1378
+ description: If set, an optional account subtype. Set to `null` to clear it.
1379
+ Examples include<br>
1357
1380
  - retirement - checking - savings - prepaid credit card
1358
1381
  minLength: 1
1359
1382
  maxLength: 100
1383
+ example: prepaid credit card
1360
1384
  x-updatable: true
1361
1385
  balance:
1362
1386
  oneOf:
@@ -1614,6 +1638,7 @@ components:
1614
1638
  type: object
1615
1639
  description: Source information for a manual account balance history entry.
1616
1640
  additionalProperties: false
1641
+ x-internal: true
1617
1642
  properties:
1618
1643
  type:
1619
1644
  type: string
@@ -1631,6 +1656,7 @@ components:
1631
1656
  type: object
1632
1657
  description: Source information for a Plaid-synced account balance history entry.
1633
1658
  additionalProperties: false
1659
+ x-internal: true
1634
1660
  properties:
1635
1661
  type:
1636
1662
  type: string
@@ -1648,6 +1674,7 @@ components:
1648
1674
  type: object
1649
1675
  description: Source information for a manually-tracked cryptocurrency balance history entry.
1650
1676
  additionalProperties: false
1677
+ x-internal: true
1651
1678
  properties:
1652
1679
  type:
1653
1680
  type: string
@@ -1750,9 +1777,10 @@ components:
1750
1777
  - subtype
1751
1778
  - mask
1752
1779
  - symbol
1780
+
1753
1781
  balanceHistoryAccountObject:
1754
1782
  type: object
1755
- title: balance history account object
1783
+ title: balance history for an account object
1756
1784
  additionalProperties: false
1757
1785
  description: Historical balance entries grouped under a single account source.
1758
1786
  properties:
@@ -1776,7 +1804,10 @@ components:
1776
1804
  deleted: "#/components/schemas/balanceHistorySourceDeleted"
1777
1805
  balances:
1778
1806
  type: array
1779
- description: One or more monthly balance history entries for the source account.
1807
+ description: >
1808
+ Monthly balance history entries for the source account. On GET responses,
1809
+ this includes all entries in the requested range. On PUT upsert responses,
1810
+ this includes only the entries modified by that request.
1780
1811
  items:
1781
1812
  $ref: "#/components/schemas/balanceHistoryObject"
1782
1813
  required:
@@ -1787,6 +1818,7 @@ components:
1787
1818
  type: object
1788
1819
  title: balance history entry object
1789
1820
  additionalProperties: false
1821
+ x-internal: true
1790
1822
  description: A historical balance entry for a single account on a single date.
1791
1823
  properties:
1792
1824
  id:
@@ -1800,7 +1832,7 @@ components:
1800
1832
  balance:
1801
1833
  type: string
1802
1834
  pattern: ^-?\d+(\.\d{1,4})?$
1803
- description: Historical balance stored for this entry. For manual and Plaid accounts this is in the account currency. For crypto accounts this is in the user's primary currency.
1835
+ description: Historical balance stored for this entry, as a numeric string with up to four decimal places. Trailing zeros and decimal places are not guaranteed in responses. For manual and Plaid accounts this is in the account currency. For crypto accounts this is in the user's primary currency.
1804
1836
  currency:
1805
1837
  allOf:
1806
1838
  - $ref: "#/components/schemas/currencyEnum"
@@ -1847,7 +1879,7 @@ components:
1847
1879
  date:
1848
1880
  type: string
1849
1881
  format: date
1850
- description: Month to update, in YYYY-MM-DD format. This must be the first day of a month and must not be in the future.
1882
+ description: Month to update, in YYYY-MM-DD format. This must be the first day of a month and must be in a past month.
1851
1883
  balance:
1852
1884
  oneOf:
1853
1885
  - type: number
@@ -1898,37 +1930,6 @@ components:
1898
1930
  required:
1899
1931
  - balances
1900
1932
 
1901
- balanceHistoryUpdateErrorObject:
1902
- type: object
1903
- x-internal: true
1904
- additionalProperties: true
1905
- properties:
1906
- request_balances_index:
1907
- type: integer
1908
- format: int32
1909
- description: Zero-based index into the `balances` request array
1910
- message:
1911
- type: string
1912
- description: Error message describing why the row could not be updated
1913
- required:
1914
- - request_balances_index
1915
- - message
1916
-
1917
- upsertBalanceHistoryResponseObject:
1918
- type: object
1919
- x-internal: true
1920
- additionalProperties: false
1921
- properties:
1922
- updated_balance_history:
1923
- $ref: "#/components/schemas/balanceHistoryAccountObject"
1924
- errors:
1925
- type: array
1926
- items:
1927
- $ref: "#/components/schemas/balanceHistoryUpdateErrorObject"
1928
- required:
1929
- - updated_balance_history
1930
- - errors
1931
-
1932
1933
  updateBalanceHistoryDetailsRequestObject:
1933
1934
  type: object
1934
1935
  x-internal: true
@@ -2467,14 +2468,9 @@ components:
2467
2468
  external_id:
2468
2469
  type: string
2469
2470
  nullable: true
2470
- description: A user-defined external ID for any transaction that was
2471
- added via csv import, `POST /transactions` API call, or manually
2472
- added via the Lunch Money app. No external ID exists for
2473
- transactions associated with synced accounts, and they cannot be
2474
- added. For transactions associated with manual accounts, the
2475
- external ID must be unique as attempts to add a subsequent
2476
- transaction with the same external_id and manual_account_id will be
2477
- flagged as duplicates and fail.
2471
+ description: A user-defined external ID associated with the transaction.
2472
+ For transactions belonging to manual accounts, the
2473
+ external ID must be unique for each transaction associated with the account.
2478
2474
  minLength: 0
2479
2475
  maxLength: 75
2480
2476
  tag_ids:
@@ -2495,8 +2491,6 @@ components:
2495
2491
  Any transaction notes set by the user or by
2496
2492
  a matched recurring item. This will match the value
2497
2493
  displayed in notes field on the transactions page in the Lunch Money app.
2498
- minLength: 0
2499
- maxLength: 350
2500
2494
  status:
2501
2495
  type: string
2502
2496
  # description: >
@@ -2732,8 +2726,6 @@ components:
2732
2726
  Any transaction notes set by the user or by
2733
2727
  a matched recurring item. This will match the value
2734
2728
  displayed in notes field on the transactions page in the Lunch Money app.
2735
- minLength: 0
2736
- maxLength: 350
2737
2729
  status:
2738
2730
  type: string
2739
2731
  description: >
@@ -2875,14 +2867,9 @@ components:
2875
2867
  external_id:
2876
2868
  type: string
2877
2869
  nullable: true
2878
- description: A user-defined external ID for any transaction that was
2879
- added via csv import, `POST /transactions` API call, or manually
2880
- added via the Lunch Money app. No external ID exists for
2881
- transactions associated with synced accounts, and they cannot be
2882
- added. For transactions associated with manual accounts, the
2883
- external ID must be unique as attempts to add a subsequent
2884
- transaction with the same external_id and manual_account_id will be
2885
- flagged as duplicates and fail.
2870
+ description: A user-defined external ID associated with the transaction.
2871
+ For transactions belonging to manual accounts, the
2872
+ external ID must be unique for each transaction associated with the account.
2886
2873
  minLength: 0
2887
2874
  maxLength: 75
2888
2875
  plaid_metadata:
@@ -2952,7 +2939,7 @@ components:
2952
2939
  currency:
2953
2940
  description: Three-letter lowercase currency code of the transaction
2954
2941
  in ISO 4217 format. Must match one of the [supported
2955
- currencies](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/currencies). If not set
2942
+ currencies](https://lunchmoney.dev/v2/currencies). If not set
2956
2943
  defaults to the user account's primary currency.
2957
2944
  allOf:
2958
2945
  - $ref: "#/components/schemas/currencyEnum"
@@ -2978,8 +2965,6 @@ components:
2978
2965
  Any transaction notes set by the user or by
2979
2966
  a matched recurring item. This will match the value
2980
2967
  displayed in notes field on the transactions page in the Lunch Money app.
2981
- minLength: 0
2982
- maxLength: 350
2983
2968
  manual_account_id:
2984
2969
  type: integer
2985
2970
  format: int32
@@ -3117,8 +3102,6 @@ components:
3117
3102
  description: >
3118
3103
  New notes for the transaction. Set this to an empty string to clear
3119
3104
  the existing notes.
3120
- minLength: 0
3121
- maxLength: 350
3122
3105
  x-updatable: true
3123
3106
  manual_account_id:
3124
3107
  type: integer
@@ -3301,6 +3284,7 @@ components:
3301
3284
  amount.
3302
3285
  payee:
3303
3286
  type: string
3287
+ minLength: 0
3304
3288
  description: The payee for the child transaction. Will inherit the
3305
3289
  original payee from the parent if not defined.
3306
3290
  date:
@@ -3323,7 +3307,6 @@ components:
3323
3307
  format: int32
3324
3308
  notes:
3325
3309
  type: string
3326
- maxLength: 350
3327
3310
  description: Will inherit notes from parent if not defined.
3328
3311
  required:
3329
3312
  - amount
@@ -3633,10 +3616,11 @@ components:
3633
3616
 
3634
3617
  # Response body for GET /budgets/settings (200)
3635
3618
  budgetSettingsResponseObject:
3636
- x-internal: true
3637
3619
  type: object
3620
+ title: budget settings object
3638
3621
  additionalProperties: false
3639
- description: Budget period and display settings
3622
+ description: Budget period and display settings for the current budgeting
3623
+ account.
3640
3624
  properties:
3641
3625
  budget_period_granularity:
3642
3626
  type: string
@@ -3648,8 +3632,8 @@ components:
3648
3632
  - twice a month
3649
3633
  description: Budget period granularity
3650
3634
  budget_period_quantity:
3651
- type: number
3652
- format: double
3635
+ type: integer
3636
+ format: int32
3653
3637
  description: The number of `granularity` units that make up a single
3654
3638
  budgeting period.
3655
3639
  budget_period_anchor_date:
@@ -4005,7 +3989,9 @@ components:
4005
3989
  while processing the request.<br> If multiple errors were
4006
3990
  encountered, the list will contain multiple objects.<br> Each
4007
3991
  `error` object is guaranteed to have an `errMsg`, but it may also
4008
- contain other error specific properties.
3992
+ contain other error-specific properties such as `code` (for example
3993
+ `VALIDATION_ERROR`), or other properties that are useful to map
3994
+ the error to the relevant part of the request.
4009
3995
  type: array
4010
3996
  items:
4011
3997
  type: object
@@ -4114,6 +4100,7 @@ components:
4114
4100
  # - `cad`: Canadian Dollar
4115
4101
  # - `cdf`: Congolese Franc
4116
4102
  # - `chf`: Swiss Franc
4103
+ # - `clf`: Chilean Unit of Account (UF)
4117
4104
  # - `clp`: Chilean Peso
4118
4105
  # - `cny`: Chinese Yuan
4119
4106
  # - `cop`: Colombian Peso
@@ -4129,6 +4116,7 @@ components:
4129
4116
  # - `egp`: Egyptian Pound
4130
4117
  # - `ern`: Eritrean Nakfa
4131
4118
  # - `etb`: Ethiopian Birr
4119
+ # - `eth`: Ethereum
4132
4120
  # - `eur`: Euro
4133
4121
  # - `fjd`: Fijian Dollar
4134
4122
  # - `fkp`: Falkland Islands Pound
@@ -4236,10 +4224,13 @@ components:
4236
4224
  # - `uyu`: Uruguayan Peso
4237
4225
  # - `uzs`: Uzbekistan Som
4238
4226
  # - `vef`: Venezuelan Bolívar
4227
+ # - `ves`: Venezuelan Bolívar Sotiemas
4239
4228
  # - `vnd`: Vietnamese Dong
4240
4229
  # - `vuv`: Vanuatu Vatu
4241
4230
  # - `wst`: Samoan Tala
4242
4231
  # - `xaf`: CFA Franc BEAC
4232
+ # - `xag`: Silver (troy ounce)
4233
+ # - `xau`: Gold (troy ounce)
4243
4234
  # - `xcd`: East Caribbean Dollar
4244
4235
  # - `xof`: CFA Franc BCEAO
4245
4236
  # - `xpf`: CFP Franc
@@ -4277,6 +4268,7 @@ components:
4277
4268
  - cad
4278
4269
  - cdf
4279
4270
  - chf
4271
+ - clf
4280
4272
  - clp
4281
4273
  - cny
4282
4274
  - cop
@@ -4292,6 +4284,7 @@ components:
4292
4284
  - egp
4293
4285
  - ern
4294
4286
  - etb
4287
+ - eth
4295
4288
  - eur
4296
4289
  - fjd
4297
4290
  - fkp
@@ -4399,10 +4392,13 @@ components:
4399
4392
  - uyu
4400
4393
  - uzs
4401
4394
  - vef
4395
+ - ves
4402
4396
  - vnd
4403
4397
  - vuv
4404
4398
  - wst
4405
4399
  - xaf
4400
+ - xag
4401
+ - xau
4406
4402
  - xcd
4407
4403
  - xof
4408
4404
  - xpf
@@ -4454,22 +4450,10 @@ components:
4454
4450
  securitySchemes:
4455
4451
  bearerSecurity:
4456
4452
  type: http
4457
- # TODO Make this shorter?
4458
- # description: The Lunch Money API uses API keys to authenticate requests. To use
4459
- # the v1 API you can view and manage your API keys on the [developers page
4460
- # in the Lunch Money app](https://my.lunchmoney.app/developers). <p> To
4461
- # interact with the Static Mock Server simply enter an API key of 11
4462
- # characters or more. <p> To interact with the v2 service implemented on
4463
- # top of the v1 API paste in a real API token associated with a Lunch
4464
- # Money Budget.
4465
- description: To interact with the Static Mock Server simply enter an API
4466
- key of 11 characters or more.
4453
+ description: >-
4454
+ Required for the LIVE server. Optional for MOCK.
4467
4455
  scheme: bearer
4468
4456
  bearerFormat: JWT
4469
- cookieAuth:
4470
- type: apiKey
4471
- in: cookie
4472
- name: _lm_access_token
4473
4457
 
4474
4458
  paths:
4475
4459
  /me:
@@ -5749,12 +5733,9 @@ paths:
5749
5733
  tags:
5750
5734
  - crypto-manual
5751
5735
  summary: Get all supported cryptocurrencies
5752
- description: >
5736
+ description: |-
5753
5737
  Retrieve the list of cryptocurrencies currently supported for manual tracking.<p>
5754
-
5755
- When creating a new manual crypto balance via `POST /crypto/manual`, the
5756
- `symbol` you specify must match the `symbol` of one of the entries
5757
- returned by this endpoint.
5738
+ When creating a new manual crypto balance via `POST /crypto/manual`, the `symbol` you specify must match the `symbol` of one of the entries returned by this endpoint.
5758
5739
  operationId: getAllCryptocurrencies
5759
5740
  responses:
5760
5741
  "200":
@@ -5792,16 +5773,9 @@ paths:
5792
5773
  - crypto-manual
5793
5774
  summary: Add a new supported cryptocurrency
5794
5775
  operationId: createCryptocurrency
5795
- description: >-
5776
+ description: |-
5796
5777
  Adds a new cryptocurrency to the supported manual-crypto list.<br><br>
5797
-
5798
- Lunch Money uses [CoinGecko](https://www.coingecko.com/us/coins/ethereum)
5799
- to convert crypto balances to the user's primary currency. Users add a
5800
- new supported cryptocurrency by submitting a CoinGecko coin-page URL.
5801
- The server validates the URL, extracts the id from `/coins/{id}`,
5802
- checks for an existing supported `coingecko_id`, validates the id
5803
- against CoinGecko, then confirms the resolved symbol is not already
5804
- supported before creating the new entry.
5778
+ Lunch Money uses [CoinGecko](https://www.coingecko.com/us/coins/ethereum) to convert crypto balances to the user's primary currency. Users add a new supported cryptocurrency by submitting a CoinGecko coin-page URL. The server validates the URL, extracts the id from `/coins/{id}`, checks for an existing supported `coingecko_id`, validates the id against CoinGecko, then confirms the resolved symbol is not already supported before creating the new entry.
5805
5779
  requestBody:
5806
5780
  required: true
5807
5781
  content:
@@ -5880,8 +5854,8 @@ paths:
5880
5854
  tags:
5881
5855
  - crypto-manual
5882
5856
  summary: Get all manual crypto balances
5883
- description: Retrieve all manually managed crypto balances associated with
5884
- the user's account.
5857
+ description: |-
5858
+ Retrieve all manually managed crypto balances associated with the user's account.
5885
5859
  operationId: getAllCryptoManual
5886
5860
  responses:
5887
5861
  "200":
@@ -5901,6 +5875,7 @@ paths:
5901
5875
  coingecko_id: bitcoin
5902
5876
  to_base: 53124.72
5903
5877
  balance_as_of: "2026-02-25T14:22:10.000Z"
5878
+ exchange_rate_as_of: "2026-02-25T14:10:00.000Z"
5904
5879
  created_by_name: User 1
5905
5880
  created_at: "2025-11-12T20:14:32.000Z"
5906
5881
  updated_at: "2026-02-25T14:22:10.000Z"
@@ -5914,11 +5889,9 @@ paths:
5914
5889
  tags:
5915
5890
  - crypto-manual
5916
5891
  summary: Create a manual crypto balance
5917
- description: >-
5892
+ description: |-
5918
5893
  Create a manually managed crypto asset.<br><br>
5919
-
5920
- If `display_name` is `null`, clients may derive one from
5921
- `institution_name` + `name`.
5894
+ If `display_name` is `null`, clients may derive one from `institution_name` + `name`.
5922
5895
  operationId: createCryptoManual
5923
5896
  requestBody:
5924
5897
  required: true
@@ -5958,6 +5931,7 @@ paths:
5958
5931
  coingecko_id: ethereum
5959
5932
  to_base: 28998.44
5960
5933
  balance_as_of: "2026-03-01T09:20:41.000Z"
5934
+ exchange_rate_as_of: "2026-03-01T09:15:00.000Z"
5961
5935
  created_by_name: User 1
5962
5936
  created_at: "2026-03-01T09:20:41.000Z"
5963
5937
  updated_at: "2026-03-01T09:20:41.000Z"
@@ -5970,11 +5944,22 @@ paths:
5970
5944
  examples:
5971
5945
  missing required properties:
5972
5946
  value:
5973
- message: Request Validation Failure
5947
+ message: Invalid Request Body
5974
5948
  errors:
5975
5949
  - errMsg: "Missing required property 'name' in request body."
5976
5950
  - errMsg: "Missing required property 'balance' in request body."
5977
5951
  - errMsg: "Missing required property 'symbol' in request body."
5952
+ invalid balance:
5953
+ value:
5954
+ message: Invalid Request Body
5955
+ errors:
5956
+ - errMsg: "Invalid value for property 'balance'. 'abc' cannot be converted to a number"
5957
+ - errMsg: "Invalid value for property 'balance'. Invalid input"
5958
+ invalid property:
5959
+ value:
5960
+ message: Invalid Request Body
5961
+ errors:
5962
+ - errMsg: "Invalid property 'coingecko_id' in request body."
5978
5963
  unsupported symbol:
5979
5964
  value:
5980
5965
  message: Request Validation Failure
@@ -5991,7 +5976,8 @@ paths:
5991
5976
  tags:
5992
5977
  - crypto-manual
5993
5978
  summary: Get a single manual crypto balance
5994
- description: Retrieve a single manually managed crypto balance by ID.
5979
+ description: |-
5980
+ Retrieve a single manually managed crypto balance by ID.
5995
5981
  operationId: getCryptoManualById
5996
5982
  parameters:
5997
5983
  - name: id
@@ -6025,6 +6011,7 @@ paths:
6025
6011
  coingecko_id: bitcoin
6026
6012
  to_base: 53124.72
6027
6013
  balance_as_of: "2026-02-25T14:22:10.000Z"
6014
+ exchange_rate_as_of: "2026-02-25T14:10:00.000Z"
6028
6015
  created_by_name: User 1
6029
6016
  created_at: "2025-11-12T20:14:32.000Z"
6030
6017
  updated_at: "2026-02-25T14:22:10.000Z"
@@ -6058,11 +6045,9 @@ paths:
6058
6045
  tags:
6059
6046
  - crypto-manual
6060
6047
  summary: Update a manual crypto balance
6061
- description: >-
6048
+ description: |-
6062
6049
  Modify a manually managed crypto balance.<br><br>
6063
-
6064
- You may submit the response from `GET /crypto/manual/{id}` as the request body. System-defined properties
6065
- are accepted according to the `x-updatable` metadata in the update schema.
6050
+ You may submit the response from `GET /crypto/manual/{id}` as the request body. System-defined properties are accepted according to the `x-updatable` metadata in the update schema.
6066
6051
  operationId: updateCryptoManual
6067
6052
  parameters:
6068
6053
  - name: id
@@ -6102,6 +6087,7 @@ paths:
6102
6087
  coingecko_id: bitcoin
6103
6088
  to_base: 56011.12
6104
6089
  balance_as_of: "2026-03-01T09:41:18.000Z"
6090
+ exchange_rate_as_of: "2026-03-01T09:35:00.000Z"
6105
6091
  created_by_name: User 1
6106
6092
  created_at: "2025-11-12T20:14:32.000Z"
6107
6093
  updated_at: "2026-02-25T14:22:10.000Z"
@@ -6122,6 +6108,7 @@ paths:
6122
6108
  coingecko_id: bitcoin
6123
6109
  to_base: 56011.12
6124
6110
  balance_as_of: "2026-03-01T09:41:18.000Z"
6111
+ exchange_rate_as_of: "2026-03-01T09:35:00.000Z"
6125
6112
  created_by_name: User 1
6126
6113
  created_at: "2025-11-12T20:14:32.000Z"
6127
6114
  updated_at: "2026-03-01T09:41:18.000Z"
@@ -6157,10 +6144,8 @@ paths:
6157
6144
  tags:
6158
6145
  - crypto-manual
6159
6146
  summary: Delete a manual crypto balance
6160
- description: Delete a single manually managed crypto asset by ID.<p> If
6161
- this crypto asset has a balance history, and you do not explicitly set
6162
- the query parameter`keep_history`, a 422 response will be returned
6163
- requesting you to explicitly set `keep_history` to `true` or `false`.
6147
+ description: |-
6148
+ Delete a single manually managed crypto asset by ID.<p> If this crypto asset has a balance history, and you do not explicitly set the query parameter`keep_history`, a 422 response will be returned requesting you to explicitly set `keep_history` to `true` or `false`.
6164
6149
  operationId: deleteCryptoManual
6165
6150
  parameters:
6166
6151
  - name: id
@@ -6225,8 +6210,8 @@ paths:
6225
6210
  tags:
6226
6211
  - crypto-synced
6227
6212
  summary: Get all synced crypto accounts
6228
- description: Retrieves all synced crypto accounts
6229
- associated with the user's account.
6213
+ description: |-
6214
+ Retrieves all synced crypto accounts associated with the user's account.
6230
6215
  operationId: getAllCryptoSynced
6231
6216
  responses:
6232
6217
  "200":
@@ -6251,6 +6236,7 @@ paths:
6251
6236
  coingecko_id: ethereum
6252
6237
  to_base: 28998.44
6253
6238
  balance_as_of: "2026-02-25T14:25:00.000Z"
6239
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6254
6240
  updated_at: "2026-02-25T14:25:01.000Z"
6255
6241
  - name: BTC
6256
6242
  balance: "0.100020003000400050"
@@ -6258,6 +6244,7 @@ paths:
6258
6244
  coingecko_id: bitcoin
6259
6245
  to_base: 6231.28
6260
6246
  balance_as_of: "2026-02-25T14:25:00.000Z"
6247
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6261
6248
  updated_at: "2026-02-25T14:25:01.000Z"
6262
6249
  - id: 33005
6263
6250
  provider: kraken
@@ -6273,6 +6260,7 @@ paths:
6273
6260
  coingecko_id: ripple
6274
6261
  to_base: 1287.50
6275
6262
  balance_as_of: "2026-02-26T07:22:30.000Z"
6263
+ exchange_rate_as_of: "2026-02-26T07:10:00.000Z"
6276
6264
  updated_at: "2026-02-26T07:22:30.000Z"
6277
6265
  "401":
6278
6266
  $ref: "#/components/responses/unauthorizedToken"
@@ -6285,8 +6273,8 @@ paths:
6285
6273
  tags:
6286
6274
  - crypto-synced
6287
6275
  summary: Get a single synced crypto account
6288
- description: Retrieves the synced crypto account and all nested balances
6289
- for the specified synced crypto account ID.
6276
+ description: |-
6277
+ Retrieves the synced crypto account and all nested balances for the specified synced crypto account ID.
6290
6278
  operationId: getCryptoSyncedById
6291
6279
  parameters:
6292
6280
  - name: id
@@ -6325,6 +6313,7 @@ paths:
6325
6313
  coingecko_id: ethereum
6326
6314
  to_base: 28998.44
6327
6315
  balance_as_of: "2026-02-25T14:25:00.000Z"
6316
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6328
6317
  updated_at: "2026-02-25T14:25:01.000Z"
6329
6318
  - name: BTC
6330
6319
  balance: "0.100020003000400050"
@@ -6332,6 +6321,7 @@ paths:
6332
6321
  coingecko_id: bitcoin
6333
6322
  to_base: 6231.28
6334
6323
  balance_as_of: "2026-02-25T14:25:00.000Z"
6324
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6335
6325
  updated_at: "2026-02-25T14:25:01.000Z"
6336
6326
  "400":
6337
6327
  description: Bad Request
@@ -6364,8 +6354,8 @@ paths:
6364
6354
  tags:
6365
6355
  - crypto-synced
6366
6356
  summary: Get a synced crypto balance by symbol
6367
- description: Retrieves a single balance from the specified synced crypto
6368
- account using the crypto symbol.
6357
+ description: |-
6358
+ Retrieves a single balance from the specified synced crypto account using the crypto symbol.
6369
6359
  operationId: getCryptoSyncedBalanceBySymbol
6370
6360
  parameters:
6371
6361
  - name: id
@@ -6397,6 +6387,7 @@ paths:
6397
6387
  coingecko_id: ethereum
6398
6388
  to_base: 28998.44
6399
6389
  balance_as_of: "2026-02-25T14:25:00.000Z"
6390
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6400
6391
  updated_at: "2026-02-25T14:25:01.000Z"
6401
6392
  "400":
6402
6393
  description: Bad Request
@@ -6443,8 +6434,8 @@ paths:
6443
6434
  tags:
6444
6435
  - crypto-synced
6445
6436
  summary: Refresh balances for a synced crypto account
6446
- description: Trigger a balance refresh for the specified synced crypto
6447
- account. Returns the refreshed synced crypto account.
6437
+ description: |-
6438
+ Trigger a balance refresh for the specified synced crypto account. Returns the refreshed synced crypto account.
6448
6439
  operationId: refreshCryptoSynced
6449
6440
  parameters:
6450
6441
  - name: id
@@ -6482,6 +6473,7 @@ paths:
6482
6473
  coingecko_id: ethereum
6483
6474
  to_base: 28998.44
6484
6475
  balance_as_of: "2026-02-25T14:25:00.000Z"
6476
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6485
6477
  updated_at: "2026-02-25T14:25:01.000Z"
6486
6478
  - name: BTC
6487
6479
  balance: "0.100020003000400050"
@@ -6489,6 +6481,7 @@ paths:
6489
6481
  coingecko_id: bitcoin
6490
6482
  to_base: 6231.28
6491
6483
  balance_as_of: "2026-02-25T14:25:00.000Z"
6484
+ exchange_rate_as_of: "2026-02-25T14:20:00.000Z"
6492
6485
  updated_at: "2026-02-25T14:25:01.000Z"
6493
6486
  "401":
6494
6487
  $ref: "#/components/responses/unauthorizedToken"
@@ -6511,24 +6504,11 @@ paths:
6511
6504
  tags:
6512
6505
  - balance_history
6513
6506
  summary: Get balance history
6514
- description: >-
6507
+ description: |-
6515
6508
  Retrieve historical balance entries.<br><br>
6516
-
6517
- Balance history is monthly. When `start_date` and `end_date` are both provided,
6518
- they must be first-of-month dates. `start_date` must not be in the future,
6519
- while `end_date` may be in the future. If one of `start_date` or `end_date`
6520
- is provided, the other is required. If neither is provided, all available
6521
- balance history is returned.<br><br>
6522
-
6523
- The response groups entries by source account. Each item in
6524
- `balance_history` contains a `source` object plus a `balances` array
6525
- containing one balance entry per month in the requested range, or all
6526
- stored entries when no range is provided.<br><br>
6527
-
6528
- Historical entries for accounts that have been deleted may still
6529
- be returned. These entries use `source.type: deleted` and include
6530
- `deleted_account_id`, archived display fields, and account metadata on the
6531
- `source` object.
6509
+ Balance history is monthly. When `start_date` and `end_date` are both provided, they must be first-of-month dates. `start_date` must not be in the future, while `end_date` may be in the future. If one of `start_date` or `end_date` is provided, the other is required. If neither is provided, all available balance history is returned.<br><br>
6510
+ The response groups entries by source account. Each item in `balance_history` contains a `source` object plus a `balances` array containing one balance entry per month in the requested range, or all stored entries when no range is provided.<br><br>
6511
+ Historical entries for accounts that have been deleted may still be returned. These entries use `source.type: deleted` and include `deleted_account_id`, archived display fields, and account metadata on the `source` object.
6532
6512
  operationId: getBalanceHistory
6533
6513
  parameters:
6534
6514
  - name: start_date
@@ -6711,7 +6691,7 @@ paths:
6711
6691
  value:
6712
6692
  message: Request Validation Failure
6713
6693
  errors:
6714
- - errMsg: "`start_date` must be less than or equal to `end_date`."
6694
+ - errMsg: "`start_date` must be before or equal to `end_date`."
6715
6695
  not first of month:
6716
6696
  value:
6717
6697
  message: Request Validation Failure
@@ -6733,17 +6713,10 @@ paths:
6733
6713
  tags:
6734
6714
  - balance_history
6735
6715
  summary: Get balance history for an account
6736
- description: >-
6737
- Retrieve historical balance entries for one manual, Plaid, manual crypto,
6738
- or deleted account. Crypto synced accounts require an additional `symbol` path parameter.<br><br>
6739
-
6740
- The `account_type` path parameter identifies the type of account and the
6741
- `account_id` path parameter identifies the specific id for that account type.<br><br>
6742
-
6743
- When `start_date` and `end_date` are both provided, they must be first-of-month
6744
- dates. `start_date` must not be in the future, while `end_date` may be in the future.
6745
- If one of `start_date` or `end_date` is provided, the other is required. If neither is
6746
- provided, all available history for the source is returned.
6716
+ description: |-
6717
+ Retrieve historical balance entries for one manual, Plaid, manual crypto, or deleted account. Crypto synced accounts require an additional `symbol` path parameter.<br><br>
6718
+ The `account_type` path parameter identifies the type of account and the `account_id` path parameter identifies the specific id for that account type.<br><br>
6719
+ When `start_date` and `end_date` are both provided, they must be first-of-month dates. `start_date` must not be in the future, while `end_date` may be in the future. If one of `start_date` or `end_date` is provided, the other is required. If neither is provided, all available history for the source is returned.
6747
6720
  operationId: getBalanceHistoryForAccount
6748
6721
  parameters:
6749
6722
  - name: account_type
@@ -6837,7 +6810,7 @@ paths:
6837
6810
  value:
6838
6811
  message: Request Validation Failure
6839
6812
  errors:
6840
- - errMsg: "`start_date` must be less than or equal to `end_date`."
6813
+ - errMsg: "`start_date` must be before or equal to `end_date`."
6841
6814
  "401":
6842
6815
  $ref: "#/components/responses/unauthorizedToken"
6843
6816
  "404":
@@ -6856,7 +6829,7 @@ paths:
6856
6829
  value:
6857
6830
  message: Not Found
6858
6831
  errors:
6859
- - errMsg: "There is no deleted balance history source with the id: 99999999."
6832
+ - errMsg: "Deleted balance history source 99999999 was not found."
6860
6833
  "429":
6861
6834
  $ref: "#/components/responses/rateLimited"
6862
6835
  "500":
@@ -6865,31 +6838,15 @@ paths:
6865
6838
  tags:
6866
6839
  - balance_history
6867
6840
  summary: Upsert balance history for an account
6868
- description: >-
6869
- Upsert one or more historical balance entries for a single manual, Plaid,
6870
- manual crypto, or deleted acount. Crypto synced accounts require an additional `symbol` path parameter.<br><br>
6871
-
6872
- The `account_type` path parameter identifies the the type of account and the
6873
- `account_id` path parameter identifies the specific id for that account type.<br><br>
6874
-
6875
- Submit one or more entries in the `balances` array. Each entry must specify
6876
- a `date` and `balance` value.<br><br>
6877
-
6878
- Balance history is monthly. Each entry's `date` must be the first day of
6879
- a month and must not be in the future.<br><br>
6880
-
6881
- `currency` may be provided for any balance entry. If omitted, it defaults
6882
- to the account currency for manual/Plaid accounts, or the user's primary
6883
- currency for crypto/deleted accounts.<br><br>
6884
-
6885
- `symbol` is optional for `crypto_manual` accounts, tolerated for `deleted`
6886
- accounts, and invalid for `manual` or `plaid` accounts.<br><br>
6887
-
6888
- `crypto_balance` may be provided for `crypto_manual` and `deleted` accounts,
6889
- and is invalid for `manual` or `plaid` accounts.<br><br>
6890
-
6891
- Use `PUT /v2/balance_history/deleted/{account_id}/details` to update
6892
- deleted-source metadata.
6841
+ description: |-
6842
+ Upsert one or more historical balance entries for a single manual, Plaid, manual crypto, or deleted account. Crypto synced accounts require an additional `symbol` path parameter.<br><br>
6843
+ The `account_type` path parameter identifies the type of account and the `account_id` path parameter identifies the specific id for that account type.<br><br>
6844
+ Submit one or more entries in the `balances` array. Each entry must specify a `date` and `balance` value.<br><br>
6845
+ Balance history is monthly. Each entry's `date` must be the first day of a month and must be in a past month.<br><br>
6846
+ `currency` may be provided for any balance entry. If omitted, it defaults to the account currency for manual/Plaid accounts, or the user's primary currency for crypto/deleted accounts.<br><br>
6847
+ `symbol` may only be set when `account_type` is `crypto_manual` or `crypto_synced`. It is optional for `crypto_manual` accounts and tolerated for `deleted` accounts.<br><br>
6848
+ `crypto_balance` may be provided for `crypto_manual`, `crypto_synced`, and `deleted` accounts, and is invalid for `manual` or `plaid` accounts.<br><br>
6849
+ The response contains only the balance entries that were submitted in this request.
6893
6850
  operationId: upsertBalanceHistoryForAccount
6894
6851
  parameters:
6895
6852
  - name: account_type
@@ -6934,7 +6891,7 @@ paths:
6934
6891
  symbol: btc
6935
6892
  crypto_balance: "0.020000000000000000"
6936
6893
  currency: usd
6937
- balance: "1255.0000"
6894
+ balance: "1255"
6938
6895
  get-shaped balance entry input:
6939
6896
  value:
6940
6897
  balances:
@@ -6944,60 +6901,71 @@ paths:
6944
6901
  currency: usd
6945
6902
  to_base: 41500
6946
6903
  crypto_balance: null
6947
- partial success request:
6948
- value:
6949
- balances:
6950
- - date: "2026-03-01"
6951
- balance: "41500.0000"
6952
- - date: "2026-04-01"
6953
- balance: "41625.5000"
6954
- symbol: btc
6955
6904
  responses:
6956
6905
  "200":
6957
- description: One or more balance history entries were processed
6906
+ description: Returns the modified balance entries only. Other historical
6907
+ entries for the account are omitted from `balances`.
6958
6908
  content:
6959
6909
  application/json:
6960
6910
  schema:
6961
- $ref: "#/components/schemas/upsertBalanceHistoryResponseObject"
6911
+ $ref: "#/components/schemas/balanceHistoryAccountObject"
6962
6912
  examples:
6963
- balances updated:
6913
+ manual account bulk upsert:
6914
+ summary: Two upserted rows returned (not full account history)
6964
6915
  value:
6965
- updated_balance_history:
6966
- source:
6967
- type: manual
6968
- manual_account_id: 119807
6969
- balances:
6970
- - id: 601
6971
- date: "2026-03-01"
6972
- balance: "41500.0000"
6973
- currency: usd
6974
- to_base: 41500
6975
- crypto_balance: null
6976
- - id: 602
6977
- date: "2026-04-01"
6978
- balance: "41625.5000"
6979
- currency: usd
6980
- to_base: 41625.5
6981
- crypto_balance: null
6982
- errors: []
6983
- partial success:
6984
- value:
6985
- updated_balance_history:
6986
- source:
6987
- type: manual
6988
- manual_account_id: 119807
6989
- balances:
6990
- - id: 601
6991
- date: "2026-03-01"
6992
- balance: "41500.0000"
6993
- currency: usd
6994
- to_base: 41500
6995
- crypto_balance: null
6996
- errors:
6997
- - request_balances_index: 1
6998
- message: "`symbol` may not be set when `account_type` is `manual` or `plaid`."
6916
+ source:
6917
+ type: manual
6918
+ manual_account_id: 119807
6919
+ balances:
6920
+ - id: 601
6921
+ date: "2026-03-01"
6922
+ balance: "41500.0000"
6923
+ currency: usd
6924
+ to_base: 41500
6925
+ crypto_balance: null
6926
+ - id: 602
6927
+ date: "2026-04-01"
6928
+ balance: "41625.5000"
6929
+ currency: usd
6930
+ to_base: 41625.5
6931
+ crypto_balance: null
6932
+ crypto manual balance with symbol:
6933
+ summary: Single upserted row returned
6934
+ value:
6935
+ source:
6936
+ type: crypto_manual
6937
+ crypto_manual_id: 22001
6938
+ symbol: btc
6939
+ balances:
6940
+ - id: 603
6941
+ date: "2026-03-01"
6942
+ balance: "56011.1200"
6943
+ currency: usd
6944
+ to_base: 56011.12
6945
+ crypto_balance: "0.852341920145782301"
6946
+ deleted account bulk upsert:
6947
+ summary: Single upserted row returned
6948
+ value:
6949
+ source:
6950
+ type: deleted
6951
+ deleted_account_id: 91
6952
+ name: Savings
6953
+ institution_name: Old Bank
6954
+ display_name: Closed Savings
6955
+ account_type: savings
6956
+ subtype: savings
6957
+ mask: "1234"
6958
+ symbol: btc
6959
+ balances:
6960
+ - id: 504
6961
+ date: "2026-03-01"
6962
+ balance: "1255"
6963
+ currency: usd
6964
+ to_base: 1255
6965
+ crypto_balance: "0.020000000000000000"
6999
6966
  "400":
7000
- description: Bad Request
6967
+ description: Bad Request. The entire request is rejected if any row in
6968
+ `balances` fails validation; no rows are updated.
7001
6969
  content:
7002
6970
  application/json:
7003
6971
  schema:
@@ -7008,6 +6976,11 @@ paths:
7008
6976
  message: Invalid Request Body
7009
6977
  errors:
7010
6978
  - errMsg: "Missing required property 'balances' in request body."
6979
+ empty balances array:
6980
+ value:
6981
+ message: Invalid Request Body
6982
+ errors:
6983
+ - errMsg: "Invalid value for property 'balances'. Array must contain at least 1 element(s)"
7011
6984
  invalid property:
7012
6985
  value:
7013
6986
  message: Invalid Request Body
@@ -7018,16 +6991,26 @@ paths:
7018
6991
  message: Request Validation Failure
7019
6992
  errors:
7020
6993
  - errMsg: "`date` must be the first day of a month."
6994
+ request_balances_index: 0
6995
+ code: VALIDATION_ERROR
7021
6996
  future date:
7022
6997
  value:
7023
6998
  message: Request Validation Failure
7024
6999
  errors:
7025
- - errMsg: "`date` must not be in the future."
7000
+ - errMsg: "`date` must be in a past month."
7001
+ request_balances_index: 1
7026
7002
  crypto balance not allowed:
7027
7003
  value:
7028
7004
  message: Request Validation Failure
7029
7005
  errors:
7030
- - errMsg: "`crypto_balance` may only be set when `account_type` is `crypto_manual` or `deleted`."
7006
+ - errMsg: "`crypto_balance` may only be set when `account_type` is `crypto_manual`, `crypto_synced`, or `deleted`."
7007
+ request_balances_index: 0
7008
+ invalid row in bulk request:
7009
+ value:
7010
+ message: Request Validation Failure
7011
+ errors:
7012
+ - errMsg: "`symbol` may only be set when `account_type` is `crypto_manual` or `crypto_synced`."
7013
+ request_balances_index: 1
7031
7014
  "401":
7032
7015
  $ref: "#/components/responses/unauthorizedToken"
7033
7016
  "404":
@@ -7048,9 +7031,8 @@ paths:
7048
7031
  tags:
7049
7032
  - balance_history
7050
7033
  summary: Delete all balance history for an account
7051
- description: >-
7052
- Delete all historical balance entries for a single manual, Plaid,
7053
- manual crypto, or deleted account. Crypto synced accounts require an additional `symbol` path parameter.
7034
+ description: |-
7035
+ Delete all historical balance entries for a single manual, Plaid, manual crypto, or deleted account. Crypto synced accounts require an additional `symbol` path parameter.
7054
7036
  operationId: deleteBalanceHistoryForAccount
7055
7037
  parameters:
7056
7038
  - name: account_type
@@ -7093,16 +7075,10 @@ paths:
7093
7075
  tags:
7094
7076
  - balance_history
7095
7077
  summary: Get balance history for a synced crypto symbol
7096
- description: >-
7078
+ description: |-
7097
7079
  Retrieve historical balance entries for a single synced crypto symbol stream.<br><br>
7098
-
7099
- Use the `crypto_synced` account id together with a `symbol` path parameter
7100
- to select one balance stream within that synced crypto account.<br><br>
7101
-
7102
- When `start_date` and `end_date` are both provided, they must be first-of-month
7103
- dates. `start_date` must not be in the future, while `end_date` may be in the future.
7104
- If one of `start_date` or `end_date` is provided, the other is required. If neither is
7105
- provided, all available history for the symbol stream is returned.
7080
+ Use the `crypto_synced` account id together with a `symbol` path parameter to select one balance stream within that synced crypto account.<br><br>
7081
+ When `start_date` and `end_date` are both provided, they must be first-of-month dates. `start_date` must not be in the future, while `end_date` may be in the future. If one of `start_date` or `end_date` is provided, the other is required. If neither is provided, all available history for the symbol stream is returned.
7106
7082
  operationId: getBalanceHistoryForCryptoSynced
7107
7083
  parameters:
7108
7084
  - name: account_id
@@ -7170,7 +7146,7 @@ paths:
7170
7146
  value:
7171
7147
  message: Request Validation Failure
7172
7148
  errors:
7173
- - errMsg: "`start_date` must be less than or equal to `end_date`."
7149
+ - errMsg: "`start_date` must be before or equal to `end_date`."
7174
7150
  "401":
7175
7151
  $ref: "#/components/responses/unauthorizedToken"
7176
7152
  "404":
@@ -7189,7 +7165,7 @@ paths:
7189
7165
  value:
7190
7166
  message: Not Found
7191
7167
  errors:
7192
- - errMsg: "There is no synced crypto balance history stream for symbol 'doge' on account id: 33004."
7168
+ - errMsg: "There is no balance history for symbol 'doge' on this account."
7193
7169
  "429":
7194
7170
  $ref: "#/components/responses/rateLimited"
7195
7171
  "500":
@@ -7198,24 +7174,15 @@ paths:
7198
7174
  tags:
7199
7175
  - balance_history
7200
7176
  summary: Upsert balance history for a synced crypto symbol
7201
- description: >-
7202
- Upsert one or more historical balance entries for a single synced crypto
7203
- symbol stream.<br><br>
7204
-
7177
+ description: |-
7178
+ Upsert one or more historical balance entries for a single synced crypto symbol stream.<br><br>
7205
7179
  The path identifies both the synced crypto account and the symbol being updated.<br><br>
7206
-
7207
- Submit one or more entries in the `balances` array. Each entry must specify
7208
- a `date` and `balance` value.<br><br>
7209
-
7210
- Balance history is monthly. Each entry's `date` must be the first day of
7211
- a month and must not be in the future.<br><br>
7212
-
7213
- The request body must not include `symbol`; the symbol is supplied by the path.<br><br>
7214
-
7215
- `currency` may be provided for any balance entry. If omitted, it defaults
7216
- to the user's primary currency for synced crypto balances.<br><br>
7217
-
7218
- `crypto_balance` may be provided for synced crypto balances.
7180
+ Submit one or more entries in the `balances` array. Each entry must specify a `date` and `balance` value.<br><br>
7181
+ Balance history is monthly. Each entry's `date` must be the first day of a month and must be in a past month.<br><br>
7182
+ The request body may include an optional `symbol` on each balance entry. If provided, it must match the `symbol` path parameter. Omit `symbol` to use the path value.<br><br>
7183
+ `currency` may be provided for any balance entry. If omitted, it defaults to the user's primary currency for synced crypto balances.<br><br>
7184
+ `crypto_balance` may be provided for synced crypto balances.<br><br>
7185
+ The response contains only the balance entries that were submitted in this request.
7219
7186
  operationId: upsertBalanceHistoryForCryptoSynced
7220
7187
  parameters:
7221
7188
  - name: account_id
@@ -7249,62 +7216,38 @@ paths:
7249
7216
  - date: "2026-04-01"
7250
7217
  balance: "6500.0000"
7251
7218
  crypto_balance: "0.100020003000400050"
7252
- partial success request:
7253
- value:
7254
- balances:
7255
- - date: "2026-03-01"
7256
- balance: "6400.0000"
7257
- crypto_balance: "0.100020003000400050"
7258
- - date: "2026-04-01"
7259
- balance: "not-a-number"
7260
7219
  responses:
7261
7220
  "200":
7262
- description: One or more balance history entries were processed
7221
+ description: Returns the modified balance entries only. Other historical
7222
+ entries for the symbol stream are omitted from `balances`.
7263
7223
  content:
7264
7224
  application/json:
7265
7225
  schema:
7266
- $ref: "#/components/schemas/upsertBalanceHistoryResponseObject"
7226
+ $ref: "#/components/schemas/balanceHistoryAccountObject"
7267
7227
  examples:
7268
- balances updated:
7228
+ synced crypto bulk upsert:
7229
+ summary: Two upserted rows returned (not full symbol history)
7269
7230
  value:
7270
- updated_balance_history:
7271
- source:
7272
- type: crypto_synced
7273
- crypto_synced_id: 33004
7274
- symbol: btc
7275
- balances:
7276
- - id: 604
7277
- date: "2026-03-01"
7278
- balance: "6400.0000"
7279
- currency: usd
7280
- to_base: 6400
7281
- crypto_balance: "0.100020003000400050"
7282
- - id: 605
7283
- date: "2026-04-01"
7284
- balance: "6500.0000"
7285
- currency: usd
7286
- to_base: 6500
7287
- crypto_balance: "0.100020003000400050"
7288
- errors: []
7289
- partial success:
7290
- value:
7291
- updated_balance_history:
7292
- source:
7293
- type: crypto_synced
7294
- crypto_synced_id: 33004
7295
- symbol: btc
7296
- balances:
7297
- - id: 604
7298
- date: "2026-03-01"
7299
- balance: "6400.0000"
7300
- currency: usd
7301
- to_base: 6400
7302
- crypto_balance: "0.100020003000400050"
7303
- errors:
7304
- - request_balances_index: 1
7305
- message: "`balance` must be a valid numeric string or number."
7231
+ source:
7232
+ type: crypto_synced
7233
+ crypto_synced_id: 33004
7234
+ symbol: btc
7235
+ balances:
7236
+ - id: 604
7237
+ date: "2026-03-01"
7238
+ balance: "6400.0000"
7239
+ currency: usd
7240
+ to_base: 6400
7241
+ crypto_balance: "0.100020003000400050"
7242
+ - id: 605
7243
+ date: "2026-04-01"
7244
+ balance: "6500.0000"
7245
+ currency: usd
7246
+ to_base: 6500
7247
+ crypto_balance: "0.100020003000400050"
7306
7248
  "400":
7307
- description: Bad Request
7249
+ description: Bad Request. The entire request is rejected if any row in
7250
+ `balances` fails validation; no rows are updated.
7308
7251
  content:
7309
7252
  application/json:
7310
7253
  schema:
@@ -7315,16 +7258,35 @@ paths:
7315
7258
  message: Invalid Request Body
7316
7259
  errors:
7317
7260
  - errMsg: "Missing required property 'balances' in request body."
7261
+ empty balances array:
7262
+ value:
7263
+ message: Invalid Request Body
7264
+ errors:
7265
+ - errMsg: "Invalid value for property 'balances'. Array must contain at least 1 element(s)"
7318
7266
  invalid date:
7319
7267
  value:
7320
7268
  message: Request Validation Failure
7321
7269
  errors:
7322
7270
  - errMsg: "`date` must be the first day of a month."
7271
+ request_balances_index: 0
7323
7272
  future date:
7324
7273
  value:
7325
7274
  message: Request Validation Failure
7326
7275
  errors:
7327
- - errMsg: "`date` must not be in the future."
7276
+ - errMsg: "`date` must be in a past month."
7277
+ request_balances_index: 1
7278
+ symbol mismatch:
7279
+ value:
7280
+ message: Request Validation Failure
7281
+ errors:
7282
+ - errMsg: "`symbol` in request body (doge) does not match the path symbol (eth)."
7283
+ request_balances_index: 0
7284
+ invalid row in bulk request:
7285
+ value:
7286
+ message: Request Validation Failure
7287
+ errors:
7288
+ - errMsg: "`balance` must be a valid numeric string or number."
7289
+ request_balances_index: 1
7328
7290
  "401":
7329
7291
  $ref: "#/components/responses/unauthorizedToken"
7330
7292
  "404":
@@ -7343,7 +7305,7 @@ paths:
7343
7305
  value:
7344
7306
  message: Not Found
7345
7307
  errors:
7346
- - errMsg: "There is no synced crypto balance history stream for symbol 'doge' on account id: 33004."
7308
+ - errMsg: "There is no balance history for symbol 'doge' on this account."
7347
7309
  "429":
7348
7310
  $ref: "#/components/responses/rateLimited"
7349
7311
  "500":
@@ -7352,11 +7314,9 @@ paths:
7352
7314
  tags:
7353
7315
  - balance_history
7354
7316
  summary: Delete all balance history for a synced crypto symbol
7355
- description: >-
7317
+ description: |-
7356
7318
  Delete all historical balance entries for a single synced crypto symbol stream.<br><br>
7357
-
7358
- The path identifies both the synced crypto account and the symbol whose
7359
- history should be deleted.
7319
+ The path identifies both the synced crypto account and the symbol whose history should be deleted.
7360
7320
  operationId: deleteBalanceHistoryForCryptoSynced
7361
7321
  parameters:
7362
7322
  - name: account_id
@@ -7388,7 +7348,7 @@ paths:
7388
7348
  example:
7389
7349
  message: Not Found
7390
7350
  errors:
7391
- - errMsg: "There is no synced crypto balance history stream for symbol 'doge' on account id: 33004."
7351
+ - errMsg: "There is no balance history for symbol 'doge' on this account."
7392
7352
  "429":
7393
7353
  $ref: "#/components/responses/rateLimited"
7394
7354
  "500":
@@ -7398,7 +7358,7 @@ paths:
7398
7358
  tags:
7399
7359
  - balance_history
7400
7360
  summary: Delete a balance history entry
7401
- description: >-
7361
+ description: |-
7402
7362
  Delete a single monthly balance history entry by its id.
7403
7363
  operationId: deleteBalanceHistoryEntry
7404
7364
  parameters:
@@ -7412,6 +7372,16 @@ paths:
7412
7372
  responses:
7413
7373
  "204":
7414
7374
  description: The balance history entry was deleted
7375
+ "400":
7376
+ description: Bad Request
7377
+ content:
7378
+ application/json:
7379
+ schema:
7380
+ $ref: "#/components/schemas/errorResponseObject"
7381
+ example:
7382
+ message: Request Validation Failure
7383
+ errors:
7384
+ - errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'."
7415
7385
  "401":
7416
7386
  $ref: "#/components/responses/unauthorizedToken"
7417
7387
  "404":
@@ -7433,12 +7403,9 @@ paths:
7433
7403
  tags:
7434
7404
  - balance_history
7435
7405
  summary: Update details for a deleted account
7436
- description: >-
7406
+ description: |-
7437
7407
  Update archived metadata for a deleted balance history source.<br><br>
7438
-
7439
- Pass the `deleted` source id returned on `source.deleted_account_id`.
7440
- This endpoint updates the stored deleted-source metadata used for all
7441
- historical entries associated with that deleted source.
7408
+ Pass the `deleted` source id returned on `source.deleted_account_id`. This endpoint updates the stored deleted-source metadata used for all historical entries associated with that deleted source.
7442
7409
  operationId: updateBalanceHistoryDetails
7443
7410
  parameters:
7444
7411
  - name: account_id
@@ -7486,7 +7453,7 @@ paths:
7486
7453
  example:
7487
7454
  message: Invalid Request Body
7488
7455
  errors:
7489
- - errMsg: "Request body must include at least one of: name, institution_name, display_name, account_type, subtype, mask."
7456
+ - errMsg: "At least one property must be provided: name, institution_name, display_name, account_type, subtype, mask."
7490
7457
  "401":
7491
7458
  $ref: "#/components/responses/unauthorizedToken"
7492
7459
  "404":
@@ -7498,7 +7465,7 @@ paths:
7498
7465
  example:
7499
7466
  message: Not Found
7500
7467
  errors:
7501
- - errMsg: "There is no deleted balance history source with the id: 99999999."
7468
+ - errMsg: "Deleted balance history source 99999999 was not found."
7502
7469
  "429":
7503
7470
  $ref: "#/components/responses/rateLimited"
7504
7471
  "500":
@@ -8512,19 +8479,19 @@ paths:
8512
8479
  description: Sets the maximum number of transactions to return. If
8513
8480
  more match the filter criteria, the response will include a
8514
8481
  `has_more` attribute set to `true`. See
8515
- [Pagination](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/pagination)
8482
+ [Pagination](https://lunchmoney.dev/v2/pagination)
8516
8483
  - name: offset
8517
8484
  in: query
8518
8485
  schema:
8519
8486
  type: integer
8520
8487
  description: Sets the offset for the records returned. This is
8521
8488
  typically set automatically in the header. See
8522
- [Pagination](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/pagination)
8489
+ [Pagination](https://lunchmoney.dev/v2/pagination)
8523
8490
  responses:
8524
8491
  "200":
8525
8492
  description: Returns an array of transactions. <br><br>The `has_more`
8526
8493
  property is set to `true` if more transactions are available. See
8527
- [Pagination](https://lm-v2-api-next-a7fabcab8e9a.herokuapp.com/v2/pagination)
8494
+ [Pagination](https://lunchmoney.dev/v2/pagination)
8528
8495
  content:
8529
8496
  application/json:
8530
8497
  schema:
@@ -10190,7 +10157,7 @@ paths:
10190
10157
  description: |
10191
10158
  The payee for the new grouped transaction.
10192
10159
  minLength: 0
10193
- maxLength: 1000
10160
+
10194
10161
  category_id:
10195
10162
  type: integer
10196
10163
  format: int64
@@ -10205,8 +10172,6 @@ paths:
10205
10172
  nullable: true
10206
10173
  description: |
10207
10174
  Notes for the grouped transaction.
10208
- minLength: 0
10209
- maxLength: 350
10210
10175
  status:
10211
10176
  type: string
10212
10177
  description: If set, must be either `reviewed` or
@@ -10750,9 +10715,8 @@ paths:
10750
10715
  - transactions (files)
10751
10716
  summary: Attach a file to a transaction
10752
10717
  operationId: attachFileToTransaction
10753
- description: >-
10754
- Attaches a file to a transaction. The file must be less than 10MB in size.<br><br>
10755
- The file will be attached to the transaction and can be downloaded from the link returned by a `GET /transactions/attachments/{file_id}` request.
10718
+ description: |-
10719
+ Attaches a file to a transaction. The file must be less than 10MB in size.<br><br> The file will be attached to the transaction and can be downloaded from the link returned by a `GET /transactions/attachments/{file_id}` request.
10756
10720
  parameters:
10757
10721
  - name: transaction_id
10758
10722
  in: path
@@ -10835,8 +10799,8 @@ paths:
10835
10799
  /transactions/attachments/{file_id}:
10836
10800
  get:
10837
10801
  summary: Get a url to download a file attachment
10838
- description: Returns a signed url that can be used to download the file
10839
- attachment.
10802
+ description: |-
10803
+ Returns a signed url that can be used to download the file attachment.
10840
10804
  operationId: getTransactionAttachmentUrl
10841
10805
  tags:
10842
10806
  - transactions (files)
@@ -11569,12 +11533,15 @@ paths:
11569
11533
  get:
11570
11534
  tags:
11571
11535
  - budgets
11572
- summary: Get budget settings
11573
- description: Returns the budget-related settings for the user's account.
11536
+ summary: Get budget period settings
11537
+ description: |-
11538
+ Returns budget period and display settings for the budget
11539
+ associated with this API token.<p> These control how budget **periods** are calculated
11540
+ (granularity, anchor date, rollover, and related options).
11574
11541
  operationId: getBudgetSettings
11575
11542
  responses:
11576
11543
  "200":
11577
- description: Budget settings for the account
11544
+ description: Budget period settings for the current budget
11578
11545
  content:
11579
11546
  application/json:
11580
11547
  schema:
@@ -11597,7 +11564,7 @@ paths:
11597
11564
  Note that `start_date` **must** be a valid budget period start for the account (based on the account's
11598
11565
  budget period settings). If an invalid `start_date` is provided, the request will fail with an error that indicates what the previous and next valid start dates are.<p>
11599
11566
 
11600
- Use the [budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view the account's budget settings.<br>
11567
+ Use the [/budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view the budget period settings for the account.<br>
11601
11568
  To view details for existing budgets, use the [summary](#tag/summary) endpoint.
11602
11569
  operationId: upsertBudget
11603
11570
  requestBody:
@@ -11668,7 +11635,7 @@ paths:
11668
11635
  period settings). If an invalid `start_date` is provided, the request
11669
11636
  will fail with an error that indicates what the previous and next valid
11670
11637
  start dates are.<p> Use the
11671
- [budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view
11638
+ [/budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view
11672
11639
  the account's budget settings.<br> To view details for existing budgets,
11673
11640
  use the [summary](#tag/summary) endpoint.
11674
11641
  operationId: deleteBudget
@@ -11726,4 +11693,3 @@ paths:
11726
11693
 
11727
11694
  security:
11728
11695
  - bearerSecurity: []
11729
- - cookieAuth: []