@lunch-money/v2-api-spec 2.9.0 → 2.10.0-preview.2

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.
@@ -42,7 +42,7 @@ info:
42
42
  license:
43
43
  name: Apache 2.0
44
44
  url: http://www.apache.org/licenses/LICENSE-2.0.html
45
- version: 2.9.0
45
+ version: 2.10.0
46
46
 
47
47
  servers:
48
48
  - url: https://api.lunchmoney.dev/v2
@@ -68,6 +68,11 @@ tags:
68
68
  externalDocs:
69
69
  description: Learn more about synced accounts
70
70
  url: https://support.lunchmoney.app/setup/linked-accounts#how-often-should-i-expect-new-transactions-to-get-imported
71
+ - name: crypto
72
+ description: Work with manual and synced crypto assets
73
+ externalDocs:
74
+ description: Learn more about crypto assets
75
+ url: https://support.lunchmoney.app/setup/crypto
71
76
  - name: recurring_items
72
77
  description: Work with recurring items
73
78
  externalDocs:
@@ -155,116 +160,112 @@ components:
155
160
  - api_key_label
156
161
 
157
162
  categoryObject:
158
- type: object
159
- title: category object
160
- additionalProperties: false
161
- properties:
162
- id:
163
- type: integer
164
- format: int32
165
- nullable: false
166
- description: System defined unique ID for the category
167
- name:
168
- type: string
169
- nullable: false
170
- description: The name of the category.
171
- minLength: 1
172
- maxLength: 100
173
- description:
174
- type: string
175
- nullable: true
176
- description: The description of the category or `null` if not set.
177
- maxLength: 200
178
- is_income:
179
- type: boolean
180
- nullable: false
181
- description: 'If `true`, the transactions in this category will be treated as income. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)'
182
- exclude_from_budget:
183
- type: boolean
184
- nullable: false
185
- description: 'If `true`, the transactions in this category will be excluded from
186
- the budget. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)'
187
- exclude_from_totals:
188
- type: boolean
189
- nullable: false
190
- description: 'If `true`, the transactions in this category will be excluded from
191
- totals. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)'
192
- updated_at:
193
- type: string
194
- format: date-time
195
- nullable: false
196
- description: The date and time of when the category was last updated (in the ISO
197
- 8601 extended format).
198
- created_at:
199
- type: string
200
- format: date-time
201
- nullable: false
202
- description: The date and time of when the category was created (in the ISO 8601
203
- extended format).
204
- group_id:
205
- type: integer
206
- format: int64
207
- nullable: true
208
- description: The ID of the category group this category belongs to or `null` if
209
- the category doesn't belong to a group, or is itself a category
210
- group.
211
- is_group:
212
- type: boolean
213
- description: If `true`, the category is created as a category group.
214
- children:
215
- type: array
216
- items:
217
- $ref: "#/components/schemas/childCategoryObject"
218
- description: For category groups, this will populate with details about the
219
- categories that belong to this group. The objects in this array are
220
- similar to Category Objects but do not include the `is_income`,
221
- `exclude_from_budget`, and `exclude_from_totals` properties as these
222
- are inherited from the category group. In addition, the `is_group`
223
- property will always be `false`, and there will be no `children`
224
- attribute.
225
- archived:
226
- type: boolean
227
- description: If true, the category is archived and not displayed in relevant
228
- areas of the Lunch Money app.
229
- archived_at:
230
- type: string
231
- format: date-time
232
- nullable: true
233
- description: The date and time of when the category was last archived (in the
234
- ISO 8601 extended format).
235
- order:
236
- type: integer
237
- nullable: true
238
- default: null
239
- description: "An integer specifying the position in which the category is displayed
240
- on the categories page in the Lunch Money GUI. For categories within
241
- a category group the order is relative to the other categories
242
- within the group.<br>Categories with `order: null` will be displayed in
243
- alphabetical order by name, prior to any categories with an order"
244
- collapsed:
245
- type: boolean
246
- nullable: false
247
- default: false
248
- description: If `true`, the category is collapsed in the Lunch Money GUI.
249
- required:
250
- - id
251
- - name
252
- - description
253
- - is_income
254
- - exclude_from_budget
255
- - exclude_from_totals
256
- - updated_at
257
- - created_at
258
- - group_id
259
- - is_group
260
- - archived
261
- - archived_at
262
- - order
263
- - collapsed
264
-
265
- # The childCategoryObject is basically a categoryObject that has no
266
- # `children` attribute. We create this to ensure that no categories
267
- # are added to a category group if they have children and are a group
163
+ type: object
164
+ title: category object
165
+ additionalProperties: false
166
+ properties:
167
+ id:
168
+ type: integer
169
+ format: int32
170
+ nullable: false
171
+ description: System defined unique ID for the category
172
+ name:
173
+ type: string
174
+ nullable: false
175
+ description: Name of the category
176
+ minLength: 1
177
+ maxLength: 100
178
+ description:
179
+ type: string
180
+ nullable: true
181
+ description: Category description, or `null` if none is set
182
+ maxLength: 200
183
+ is_income:
184
+ type: boolean
185
+ nullable: false
186
+ description: 'If `true`, transactions in this category are treated as income. (See [Category Properties](https://support.lunchmoney.app/setup/categories/category-properties) for details)'
187
+ exclude_from_budget:
188
+ type: boolean
189
+ nullable: false
190
+ description: 'If `true`, transactions in this category are excluded from
191
+ the budget. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for details)'
192
+ exclude_from_totals:
193
+ type: boolean
194
+ nullable: false
195
+ description: 'If `true`, transactions in this category are excluded from
196
+ totals. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for details)'
197
+ updated_at:
198
+ type: string
199
+ format: date-time
200
+ nullable: false
201
+ description: Date and time the category was last updated (in the ISO
202
+ 8601 extended format).
203
+ created_at:
204
+ type: string
205
+ format: date-time
206
+ nullable: false
207
+ description: Date and time of when the category was created (ISO 8601
208
+ extended format).
209
+ group_id:
210
+ type: integer
211
+ format: int64
212
+ nullable: true
213
+ description: ID of the category group this category belongs to, or `null` if
214
+ It does not belong to a group, or is itself a
215
+ group.
216
+ is_group:
217
+ type: boolean
218
+ description: If `true`, this category is created as a category group
219
+ children:
220
+ type: array
221
+ items:
222
+ $ref: "#/components/schemas/childCategoryObject"
223
+ description: For category groups, contains details about the
224
+ categories in the group. These objects are
225
+ similar to Category Objects but the `is_group`
226
+ property will always be `false`, and there will be no `children`
227
+ attribute.
228
+ archived:
229
+ type: boolean
230
+ description: If true, the category is archived and hidden in relevant
231
+ areas of the Lunch Money app.
232
+ archived_at:
233
+ type: string
234
+ format: date-time
235
+ nullable: true
236
+ description: Date and time the category was last archived (
237
+ ISO 8601 extended format).
238
+ order:
239
+ type: integer
240
+ nullable: true
241
+ default: null
242
+ description: "Position of the category on the categories page in the Lunch Money app.
243
+ For grouped categories, the order is relative to others in the same group.<br>
244
+ Categories with `order: null` are shown alphabetically before ordered categories"
245
+ collapsed:
246
+ type: boolean
247
+ nullable: false
248
+ default: false
249
+ description: If `true`, the category appears collapsed in the Lunch Money app
250
+ required:
251
+ - id
252
+ - name
253
+ - description
254
+ - is_income
255
+ - exclude_from_budget
256
+ - exclude_from_totals
257
+ - updated_at
258
+ - created_at
259
+ - group_id
260
+ - is_group
261
+ - archived
262
+ - archived_at
263
+ - order
264
+ - collapsed
265
+
266
+ # The childCategoryObject is a categoryObject without a
267
+ # `children` attribute. This ensures that only non-group categories
268
+ # are added to a category group
268
269
  childCategoryObject:
269
270
  type: object
270
271
  x-internal: true # Don't display in schemas section of docs
@@ -274,79 +275,76 @@ components:
274
275
  type: integer
275
276
  format: int32
276
277
  nullable: false
277
- description: A system defined unique identifier for the category.
278
+ description: System defined unique ID for the category
278
279
  name:
279
280
  type: string
280
281
  nullable: false
281
- description: The name of the category.
282
+ description: The name of the category
282
283
  minLength: 1
283
284
  maxLength: 100
284
285
  description:
285
286
  type: string
286
287
  nullable: true
287
- description: The description of the category or `null` if not set.
288
+ description: Category description, or `null` if none is set
288
289
  maxLength: 200
289
290
  is_income:
290
291
  type: boolean
291
292
  nullable: false
292
- description: If true, the transactions in this category will be treated as
293
- income. Inherited from Category Group.
293
+ description: If true, transactions in this category are treated as
294
+ income. (Inherited from the Category Group).
294
295
  exclude_from_budget:
295
296
  type: boolean
296
297
  nullable: false
297
- description: If true, the transactions in this category will be excluded from
298
- the budget. Inherited from Category Group.
298
+ description: If true, transactions in this category are excluded from
299
+ the budget. (Inherited from Category Group).
299
300
  exclude_from_totals:
300
301
  type: boolean
301
302
  nullable: false
302
- description: If true, the transactions in this category will be excluded from
303
- totals. Inherited from Category Group.
303
+ description: If true, transactions in this category are excluded from
304
+ totals. (Inherited from Category Group).
304
305
  updated_at:
305
306
  type: string
306
307
  format: date-time
307
308
  nullable: false
308
- description: The date and time of when the category was last updated (in the ISO
309
+ description: Date and time the category was last updated (ISO
309
310
  8601 extended format).
310
311
  created_at:
311
312
  type: string
312
313
  format: date-time
313
314
  nullable: false
314
- description: The date and time of when the category was created (in the ISO 8601
315
+ description: Date and time the category was created (ISO 8601
315
316
  extended format).
316
317
  group_id:
317
318
  type: integer
318
319
  format: int64
319
320
  nullable: true
320
- description: The ID of the category group this category belongs to or `null` if
321
- the category doesn't belong to a group, or is itself a category
322
- group.
321
+ description: ID of the category group this category belongs to, or `null` if
322
+ it does not belong to a group, or is itself a group.
323
323
  is_group:
324
324
  type: boolean
325
325
  enum:
326
326
  - false
327
- description: Will always be false for a category that is part of category group.
327
+ description: Always false for categories that belong to a category group
328
328
  archived:
329
329
  type: boolean
330
- description: If true, the category is archived and not displayed in relevant
330
+ description: If true, the category is archived and hidden in relevant
331
331
  areas of the Lunch Money app.
332
332
  archived_at:
333
333
  type: string
334
334
  format: date-time
335
335
  nullable: true
336
- description: The date and time of when the category was last archived (in the
336
+ description: Date and time the category was last archived (
337
337
  ISO 8601 extended format).
338
338
  order:
339
339
  type: integer
340
340
  nullable: true
341
- description: An index specifying the position in which the category is displayed
342
- on the categories page in the Lunch Money GUI. For categories within
343
- a category group the order is relative to the other categories
344
- within the group.<br>
345
- API.
341
+ description: Position of the category
342
+ on the categories page in the Lunch Money app. For grouped categories, the order is
343
+ relative to the others in the same group.
346
344
  collapsed:
347
345
  type: boolean
348
- nullable: true
349
- description: If `true`, the category is collapsed in the Lunch Money GUI.
346
+ nullable: false
347
+ description: Always `false` for a child category. Child categories cannot be collapsed.
350
348
  required:
351
349
  - id
352
350
  - name
@@ -361,8 +359,9 @@ components:
361
359
  - archived
362
360
  - archived_at
363
361
  - order
362
+ - collapsed
364
363
 
365
- # The request object for POST /categories
364
+ # The request object for POST /categories
366
365
  # Prevent user from submitting any system created fields in a POST request
367
366
  createCategoryRequestObject:
368
367
  type: object
@@ -373,9 +372,9 @@ components:
373
372
  type: string
374
373
  nullable: false
375
374
  description: >-
376
- The name of the new category. Must be between 1 and 100 characters.
375
+ Name of the new category. Must be between 1 and 100 characters.
377
376
 
378
- Must not match the name of any existing categories or category
377
+ The name must not match the name of any existing categories or category
379
378
  groups.
380
379
  minLength: 1
381
380
  maxLength: 100
@@ -383,58 +382,53 @@ components:
383
382
  type: string
384
383
  nullable: true
385
384
  default: null
386
- description: The description of the category. Must not exceed 200 characters.
385
+ description: Description of the category. Maximum length is 200 characters.
387
386
  minLength: 0 # Allow empty strings
388
387
  maxLength: 200
389
388
  is_income:
390
389
  type: boolean
391
390
  nullable: false
392
391
  default: false
393
- description: If `true`, the transactions in this category will be treated as
394
- income. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
392
+ description: If `true`, transactions in this category are treated as
393
+ income. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for details)
395
394
  exclude_from_budget:
396
395
  type: boolean
397
396
  nullable: false
398
397
  default: false
399
- description: If `true`, the transactions in this category will be excluded from
398
+ description: If `true`, transactions in this category are excluded from
400
399
  the budget. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
401
400
  exclude_from_totals:
402
401
  type: boolean
403
402
  nullable: false
404
403
  default: false
405
- description: If `true`, the transactions in this category will be excluded from
404
+ description: If `true`, transactions in this category are excluded from
406
405
  totals. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
407
406
  is_group:
408
407
  type: boolean
409
408
  nullable: false
410
409
  default: false
411
- description: If `true`, the category is created as a category group.
410
+ description: If `true`, this category will be created as a category group.
412
411
  group_id:
413
412
  type: integer
414
413
  format: int64
415
414
  nullable: true
416
415
  default: null
417
- description: If set to the ID of an existing category group, this new category
418
- will be assigned to that group. Cannot be set if `is_group` is true.
416
+ description: If set to the ID of an existing category group, the new category
417
+ will be added to that group. Cannot be used if `is_group` is true.
419
418
  archived:
420
419
  type: boolean
421
420
  default: false
422
- description: If `true`, the category is archived and not displayed in relevant
421
+ description: If `true`, the category is archived and in relevant
423
422
  areas of the Lunch Money app.
424
423
  children:
425
424
  type: array
426
425
  nullable: false
427
- description: The list of existing category objects, or existing category IDs or
428
- names of new categories to add to the new category group. This
429
- attribute should only be set if `is_group` is also set to true.<br>
430
- The categories or IDs specified must already exist and may not be category groups themselves.
431
- Categories that already belong to
432
- another category group will be moved. If strings are specified, they
433
- will be used as the names of new categories that will be added to
434
- the new category group. The request will fail if any names are the
435
- same as the name of an existing category.<br> It is permissible to
436
- provide both full category objects and IDs as well as strings for
437
- names in the same request.
426
+ description: List of categories to include in the new category group. This
427
+ field should only be set if `is_group` is also set to true.<br> You may provide existing category objects, existing category IDs, or names of new categories to add to the new category group.
428
+ Categories or IDs specified must already exist and cannot be category groups.
429
+ Categories that already belong to another group will be moved. If strings are provided, they
430
+ will be used as names for new categories added to the group. The request will fail if any name already exists.<br>
431
+ You may mix category objects, IDs, and new category names in the same request.
438
432
  items:
439
433
  oneOf:
440
434
  - type: integer
@@ -446,18 +440,15 @@ components:
446
440
  order:
447
441
  type: integer
448
442
  nullable: true
449
- description: An index specifying the position in which the category is displayed
450
- on the categories page in the Lunch Money GUI. For categories within
451
- a category group the order is relative to the other categories
452
- within the group.<br>While this property can be set via the API it is generally set by the user in the Lunch Money GUI.
453
- API.
443
+ description: Position of the category on the categories page in the Lunch Money app. For grouped categories, the order is relative to other categories in the same group.<br>While this property can be set via the API, it is usually managed by the user in the Lunch Money app.
454
444
  collapsed:
455
445
  type: boolean
456
446
  nullable: true
457
- description: If `true`, the category is collapsed in the Lunch Money GUI.<br>While this property can be set via the API it is generally set by the user in the Lunch Money GUI.
447
+ description: If `true`, the category group appears collapsed in the Lunch Money app. Can only be set to `true` for category groups.<br>While this property can be set via the API, it is usually managed by the user in the Lunch Money app.
458
448
  required:
459
449
  - name
460
450
 
451
+
461
452
  # Request object for a PUT /categories/:id request
462
453
  # Tolerates a request object that includes system created fields from a
463
454
  # previous GET request, but these are essentially ignored
@@ -469,7 +460,7 @@ components:
469
460
  name:
470
461
  type: string
471
462
  nullable: false
472
- description: If set, the new name of the category. Must be between 1 and 100
463
+ description: If provided, updates the category name. Must be between 1 and 100
473
464
  characters.
474
465
  minLength: 1
475
466
  maxLength: 100
@@ -477,7 +468,7 @@ components:
477
468
  description:
478
469
  type: string
479
470
  nullable: true
480
- description: If set, the new description of the category. Must not exceed 200
471
+ description: If provided, updates the category description. Must not exceed 200
481
472
  characters.
482
473
  minLength: 0 # Allow empty strings
483
474
  maxLength: 200
@@ -485,38 +476,35 @@ components:
485
476
  is_income:
486
477
  type: boolean
487
478
  nullable: false
488
- description: If set, will indicate if this category will be treated as income. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
479
+ description: If set, determines whether transactions in this category are treated as income. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
489
480
  x-updatable: true
490
481
  exclude_from_budget:
491
482
  type: boolean
492
483
  nullable: false
493
- description: If set, will indicate if this category will be excluded from budgets. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
484
+ description: If provided, determines whether transactions in this category are excluded from budgets. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
494
485
  x-updatable: true
495
486
  exclude_from_totals:
496
487
  type: boolean
497
488
  nullable: false
498
- description: If set, will indicate if this category will be excluded from totals. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
489
+ description: If provided, determines whether transactions in this category are excluded from totals. (See <a href="https://support.lunchmoney.app/setup/categories/category-properties">Category Properties</a> for more details)
499
490
  x-updatable: true
500
491
  archived:
501
492
  type: boolean
502
- description: If set, will indicate if this category is archived.
493
+ description: If provided, determines whether this category is archived.
503
494
  x-updatable: true
504
495
  group_id:
505
496
  type: integer
506
497
  format: int64
507
498
  nullable: true
508
499
  description: If set to the ID of an existing category group, and this category
509
- is not itself a category group, this category will be a child of the
510
- specified group.
500
+ is not itself a category group, this category will be assigned to that group.
511
501
  x-updatable: true
512
502
  is_group:
513
503
  type: boolean
514
504
  nullable: true
515
505
  default: false
516
- description: This attribute may not be set to a value that is different
517
- than the current status of the category or category group. In other
518
- words, this API may not be used to convert a category to a category
519
- group or vice versa.
506
+ description: This property is tolerated but cannot be changed.
507
+ This API cannot be used to convert a category into a category group or vice versa.
520
508
  children:
521
509
  type: array
522
510
  nullable: false
@@ -622,213 +610,268 @@ components:
622
610
  - category_name
623
611
  - dependents
624
612
 
625
- # The object containing information about a manual account
626
- manualAccountObject:
613
+ # The base object containing information about a crypto balance
614
+ cryptoBalanceObject:
627
615
  type: object
628
- title: manual account object
616
+ title: crypto balance object
629
617
  additionalProperties: false
630
- description: An object containing information about a manual account
618
+ description: The balance for a single crypto asset
631
619
  properties:
632
620
  id:
633
621
  type: integer
634
622
  format: int32
635
- description: The unique identifier of this account
636
- name:
623
+ description: A system defined unique ID for the crypto asset if the source is "manual" or the synced connection ID if the source is "synced"
624
+ source:
637
625
  type: string
638
- description: Name of the account
639
- minLength: 1
640
- maxLength: 45
641
- institution_name:
626
+ description: The source type for this crypto asset
627
+ enum:
628
+ - manual
629
+ - synced
630
+ account_status:
631
+ type: string
632
+ description: Status of the synced crypto account. Will not be present for manually managed crypto assets.
633
+ enum:
634
+ - active
635
+ - unsupported
636
+ - relink
637
+ - initializing
638
+ name:
642
639
  type: string
643
640
  nullable: true
644
641
  minLength: 1
645
- maxLength: 50
646
- description: Name of institution holding the account
642
+ maxLength: 45
643
+ description: The name of the crypto asset
647
644
  display_name:
648
645
  type: string
649
646
  nullable: true
650
- description: Optional display name for the account as set by the user or derived from the `institution_name` and `name` if not explicitly set.
651
- type:
652
- description: Primary type of the account
653
- allOf:
654
- - $ref: "#/components/schemas/accountTypeEnum"
655
- subtype:
647
+ description: Optional display name for the crypto asset
648
+ institution_name:
656
649
  type: string
657
650
  nullable: true
658
- description: Optional account subtype. Examples include<br> - retirement -
659
- checking - savings - prepaid credit card
660
651
  minLength: 1
661
- maxLength: 100
652
+ maxLength: 50
653
+ description: Institution or wallet provider display name
662
654
  balance:
663
655
  type: string
664
- pattern: ^-?\d+(\.\d{1,4})?$
665
- description: Current balance of the account in numeric format to 4 decimal places
656
+ pattern: ^-?\d+(\.\d{1,18})?$
657
+ description: Current balance in numeric format to 18 decimal places
666
658
  currency:
667
659
  type: string
668
- minLength: 3
669
- maxLength: 3
670
- description: Three-letter lowercase currency code of the account balance
660
+ minLength: 1
661
+ maxLength: 10
662
+ description: Cryptocurrency symbol
663
+ coingecko_id:
664
+ type: string
665
+ nullable: true
666
+ minLength: 1
667
+ maxLength: 100
668
+ description: CoinGecko identifier associated with this balance
671
669
  to_base:
672
670
  type: number
673
- description: The balance converted to the user's primary currency
671
+ description: Balance converted to the user's primary currency
674
672
  balance_as_of:
675
673
  type: string
676
674
  format: date-time
677
- description: Date balance was last updated in ISO 8601 extended format, can be in date or date-time format
678
- status:
679
- type: string
680
- description: The status of the account
681
- enum:
682
- - active
683
- - closed
684
- closed_on:
685
- type: string
686
- format: date
687
675
  nullable: true
688
- description: The date this account was closed in YYYY-MM-DD format. Will be null if the account has
689
- not been marked as closed.
690
- external_id:
676
+ description: Date/time the balance was last updated in ISO 8601 extended format
677
+ last_import:
691
678
  type: string
679
+ format: date-time
692
680
  nullable: true
693
- minLength: 0
694
- maxLength: 75
695
- description: An optional external_id that may be set or updated via the API
696
- custom_metadata:
697
- type: object
698
- nullable: true
699
- description: User defined JSON data that can be set or cleared via the API
700
- additionalProperties: true
701
- exclude_from_transactions:
702
- type: boolean
703
- default: false
704
- description: If true, this account will not show up as an option for assignment
705
- when creating transactions manually
681
+ description: Timestamp in ISO 8601 extended format of the last successful import
706
682
  created_by_name:
707
683
  type: string
708
- description: The name of the user who created the account
684
+ nullable: true
685
+ description: Name of the user who created the crypto asset
709
686
  created_at:
710
687
  type: string
711
688
  format: date-time
712
- description: Date/time the account was created in ISO 8601 extended format
689
+ description: Date/time the crypto asset was created in ISO 8601 extended format
713
690
  updated_at:
714
691
  type: string
715
692
  format: date-time
716
- description: Date/time the account was created in ISO 8601 extended format
693
+ description: Date/time the crypto asset was last updated in ISO 8601 extended format
717
694
  required:
718
695
  - id
696
+ - source
719
697
  - name
720
- - type
721
- - subtype
722
698
  - display_name
699
+ - institution_name
723
700
  - balance
724
701
  - currency
702
+ - coingecko_id
725
703
  - to_base
726
704
  - balance_as_of
727
- - closed_on
728
- - institution_name
729
- - external_id
730
- - exclude_from_transactions
705
+ - last_import
731
706
  - created_by_name
732
707
  - created_at
733
708
  - updated_at
734
- - status
735
709
 
736
- # The object that may be submitted to POST /manual_accounts
737
- createManualAccountRequestObject:
710
+ # Manual crypto balance type derived from cryptoBalanceObject
711
+ cryptoManualObject:
712
+ title: manual crypto object
713
+ x-internal: true
714
+ allOf:
715
+ - type: object
716
+ properties:
717
+ source:
718
+ type: string
719
+ description: The source type for this crypto asset. Will always be "manual" for manual crypto assets.
720
+ enum:
721
+ - manual
722
+ - $ref: "#/components/schemas/cryptoBalanceObject"
723
+
724
+ # Synced crypto balance type derived from cryptoBalanceObject
725
+ cryptoSyncedObject:
726
+ title: synced crypto object
727
+ x-internal: true
728
+ allOf:
729
+ - type: object
730
+ properties:
731
+ source:
732
+ type: string
733
+ description: The source type for this crypto asset. Will always be "synced" for synced crypto assets.
734
+ enum:
735
+ - synced
736
+ account_status:
737
+ type: string
738
+ description: Status of the synced crypto account. If not `active`, see the [Knowledge Base](https://support.lunchmoney.app/setup/crypto#why-is-my-synced-crypto-account-showing-not-supported) for more details.
739
+ enum:
740
+ - active
741
+ - unsupported
742
+ - relink
743
+ - initializing
744
+ currency:
745
+ type: string
746
+ minLength: 1
747
+ maxLength: 10
748
+ description: Symbol of the currency held in the synced account.
749
+ - $ref: "#/components/schemas/cryptoBalanceObject"
750
+
751
+ # Response object returned by GET /crypto
752
+ cryptoListResponseObject:
738
753
  type: object
754
+ x-internal: true
739
755
  additionalProperties: false
756
+ properties:
757
+ crypto:
758
+ type: array
759
+ items:
760
+ $ref: "#/components/schemas/cryptoBalanceObject"
761
+ required:
762
+ - crypto
763
+
764
+ # Response object returned by GET /crypto/manual
765
+ cryptoManualListResponseObject:
766
+ type: object
740
767
  x-internal: true
768
+ additionalProperties: false
741
769
  properties:
742
- name:
743
- type: string
744
- description: Name of the manual account
745
- minLength: 1
746
- maxLength: 45
747
- example: My Savings Account
748
- institution_name:
749
- type: string
750
- example: Bank of the West
751
- description: Name of institution holding the manual account
752
- minLength: 1
753
- maxLength: 50
754
- display_name:
755
- type: string
756
- description: Display name of the manual account as set by user or derived from the `institution_name` and `name` if not explicitly set.<br>
757
- This must be unique for the budgeting account.
758
- example: Savings
759
- type:
760
- description: The type of manual account
761
- allOf:
762
- - $ref: "#/components/schemas/accountTypeEnum"
763
- subtype:
770
+ crypto_manual:
771
+ type: array
772
+ items:
773
+ $ref: "#/components/schemas/cryptoManualObject"
774
+ required:
775
+ - crypto_manual
776
+
777
+ # Response object returned by GET /crypto/synced and GET /crypto/synced/{id}
778
+ cryptoSyncedListResponseObject:
779
+ type: object
780
+ x-internal: true
781
+ additionalProperties: false
782
+ properties:
783
+ crypto_synced:
784
+ type: array
785
+ items:
786
+ $ref: "#/components/schemas/cryptoSyncedObject"
787
+ required:
788
+ - crypto_synced
789
+
790
+ # Response object returned by GET /cryptocurrencies
791
+ cryptoCurrencyResponseObject:
792
+ type: object
793
+ x-internal: true
794
+ additionalProperties: false
795
+ properties:
796
+ cryptocurrencies:
797
+ type: array
798
+ description: List of cryptocurrencies currently supported for manual tracking.
799
+ items:
800
+ type: object
801
+ additionalProperties: false
802
+ properties:
803
+ id:
804
+ type: integer
805
+ format: int32
806
+ description: System-defined unique identifier for this cryptocurrency in Lunch Money.
807
+ coingecko_id:
808
+ type: string
809
+ minLength: 1
810
+ maxLength: 50
811
+ description: System-defined CoinGecko identifier used to fetch the USD-based prices for this cryptocurrency.
812
+ currency:
813
+ type: string
814
+ minLength: 1
815
+ maxLength: 50
816
+ description: Lowercase currency symbol that must be used as `currency` when creating a manual crypto balance.
817
+ full_name:
818
+ type: string
819
+ minLength: 1
820
+ maxLength: 200
821
+ description: Human-readable name of the cryptocurrency.
822
+ required:
823
+ - id
824
+ - coingecko_id
825
+ - currency
826
+ - full_name
827
+ required:
828
+ - cryptocurrencies
829
+
830
+ # The object that may be submitted to POST /crypto/manual
831
+ createCryptoManualRequestObject:
832
+ type: object
833
+ additionalProperties: false
834
+ x-internal: true
835
+ properties:
836
+ name:
764
837
  type: string
765
- description: An optional manual account subtype. Examples include<br> -
766
- retirement - checking - savings - prepaid credit card
767
838
  minLength: 1
768
- maxLength: 100
769
- example: prepaid credit card
839
+ maxLength: 45
840
+ description: The name of the manual crypto asset
841
+ example: Hardware Wallet
842
+ display_name:
843
+ type: string
844
+ minLength: 1
845
+ maxLength: 45
846
+ description: Optional display name for the manual crypto asset
847
+ example: Cold Storage
848
+ institution_name:
849
+ type: string
850
+ minLength: 1
851
+ maxLength: 50
852
+ description: Optional institution or wallet provider display name
853
+ example: Ledger
770
854
  balance:
771
855
  oneOf:
772
856
  - type: number
773
857
  format: double
774
858
  - type: string
775
- pattern: ^-?\d+(\.\d{1,4})?$
776
- example: "195.50"
777
- description: Numeric value of the current balance, up to four decimal places, of
778
- the account as a number or string. Do not include any special
779
- characters aside from a decimal point.
780
- balance_as_of:
781
- type: string
782
- oneOf:
783
- - format: date-time
784
- - format: date
785
- example: "2024-09-15"
786
- description: Date/time the balance of the manual account was last updated in ISO 8601 extended format
859
+ pattern: ^-?\d+(\.\d{1,18})?$
860
+ description: Numeric value of the balance, up to 18 decimal places
861
+ example: "0.523400000000000000"
787
862
  currency:
788
- description: Three-letter lowercase currency code of the transaction in ISO 4217
789
- format
790
- allOf:
791
- - $ref: "#/components/schemas/currencyEnum"
792
- status:
793
- type: string
794
- description: The status of the account
795
- enum:
796
- - active
797
- - closed
798
- default: active
799
- closed_on:
800
- oneOf:
801
- - type: string
802
- format: date
803
- - type: string
804
- format: date-time
805
- nullable: true
806
- example: "2024-10-01"
807
- description: The date this manual account was closed in YYYY-MM-DD format. If set, `status` must also be set to `closed`.
808
- external_id:
809
863
  type: string
810
- nullable: true
811
- minLength: 0
812
- maxLength: 75
813
- description: An optional user-defined ID for the manual account
814
- custom_metadata:
815
- type: object
816
- nullable: true
817
- description: An optional JSON object that includes additional data related to
818
- this account. This must be a valid JSON object and, when
819
- stringified, must not exceed 4096 characters.
820
- additionalProperties: true
821
- exclude_from_transactions:
822
- type: boolean
823
- description: If `true`, transactions may not be assigned to this manual account
824
- default: false
864
+ minLength: 1
865
+ maxLength: 10
866
+ description: Cryptocurrency symbol to track. Must match the `currency` of one of the supported cryptocurrencies returned by `GET /cryptocurrencies`.
867
+ example: btc
825
868
  required:
826
869
  - name
827
- - type
828
870
  - balance
871
+ - currency
829
872
 
830
- # The object that may be submitted to PUT /manual_accounts/:id
831
- updateManualAccountRequestObject:
873
+ # The object that may be submitted to PUT /crypto/manual/{id}
874
+ updateCryptoManualRequestObject:
832
875
  type: object
833
876
  x-internal: true
834
877
  additionalProperties: false
@@ -836,210 +879,141 @@ components:
836
879
  id:
837
880
  type: integer
838
881
  format: int32
839
- description: System defined unique identifier of this account. Ignored if set
882
+ description: System defined unique ID for the manual crypto asset. Ignored if set
883
+ x-updatable: false
884
+ source:
885
+ type: string
886
+ description: System defined source for the crypto asset. Ignored if set
887
+ enum:
888
+ - manual
840
889
  x-updatable: false
841
890
  name:
842
891
  type: string
843
- description: If set, the new name of the manual account
892
+ nullable: true
844
893
  minLength: 1
845
894
  maxLength: 45
895
+ description: If set, the new name of the manual crypto asset
846
896
  x-updatable: true
847
- institution_name:
897
+ display_name:
848
898
  type: string
849
899
  nullable: true
850
- description: If set, the name of institution holding the account
851
900
  minLength: 1
852
- maxLength: 50
901
+ maxLength: 45
902
+ description: If set, the new display name for the manual crypto asset
853
903
  x-updatable: true
854
- display_name:
904
+ institution_name:
855
905
  type: string
856
906
  nullable: true
857
- description: If set, the new display name for the manual account.<br>
858
- This must be unique for the user.
859
- x-updatable: true
860
- type:
861
- description: If set, the new type of the manual account
862
- x-updatable: true
863
- allOf:
864
- - $ref: "#/components/schemas/accountTypeEnum"
865
- subtype:
866
- type: string
867
- description: If set, an optional account subtype. Examples include<br> -
868
- retirement - checking - savings - prepaid credit card
869
907
  minLength: 1
870
- maxLength: 100
908
+ maxLength: 50
909
+ description: If set, the new institution or wallet provider display name
871
910
  x-updatable: true
872
911
  balance:
873
912
  oneOf:
874
913
  - type: number
875
914
  format: double
876
915
  - type: string
877
- pattern: ^-?\d+(\.\d{1,4})?$
878
- example: "195.50"
879
- description: Numeric value of the current balance, up to four decimal places, of
880
- the manual account as a number or string. Do not include any special
881
- characters aside from a decimal point.
916
+ pattern: ^-?\d+(\.\d{1,18})?$
917
+ description: If set, the new balance value up to 18 decimal places
918
+ example: "1.050000000000000000"
882
919
  x-updatable: true
883
920
  currency:
884
- description: If set, the new three-letter lowercase currency code of the manual account
885
- balance.
886
- x-updatable: true
887
- allOf:
888
- - $ref: "#/components/schemas/currencyEnum"
921
+ type: string
922
+ minLength: 1
923
+ maxLength: 10
924
+ description: Existing cryptocurrency symbol. Ignored if set.
925
+ x-updatable: false
926
+ coingecko_id:
927
+ type: string
928
+ nullable: true
929
+ minLength: 1
930
+ maxLength: 100
931
+ description: System-defined CoinGecko identifier for this currency. Ignored if set.
932
+ x-updatable: false
933
+ to_base:
934
+ type: number
935
+ description: System defined balance converted to the user's primary currency. Ignored if set
936
+ x-updatable: false
889
937
  balance_as_of:
890
938
  type: string
891
- oneOf:
892
- - format: date-time
893
- - format: date
894
- description: "A new date for the `updated_at` property.
895
- May be set as a date, ie: YYYY-MM-DD, or date-time string in ISO 8601 extended format.
896
- This property is ignored if `balance` is not also set. If `balance` is set and this property is
897
- not set the current time is used."
898
- x-updatable: true
939
+ format: date-time
940
+ nullable: true
941
+ description: System defined date/time the balance was last updated in ISO 8601 extended format. Ignored if set
942
+ x-updatable: false
943
+ last_import:
944
+ type: string
945
+ format: date-time
946
+ nullable: true
947
+ description: System defined timestamp in ISO 8601 extended format of the last successful import. Ignored if set
948
+ x-updatable: false
899
949
  status:
900
950
  type: string
901
- description: If set, the status of the manual account. If set to `closed`, the `closed_on_date` date will be set to the current date, unless it is also set.
951
+ description: System defined status of the crypto asset. Ignored if set
902
952
  enum:
903
953
  - active
904
- - closed
905
- x-updatable: true
906
- closed_on:
907
- nullable: true
908
- oneOf:
909
- - type: string
910
- format: date
911
- - type: string
912
- format: date-time
913
- description: If set, the date this manual account was closed in YYYY-MM-DD format. If updating an account that is not already closed, `status` must also be set to `closed`.
914
- x-updatable: true
915
- external_id:
954
+ - unsupported
955
+ - relink
956
+ - initializing
957
+ x-updatable: false
958
+ created_by_name:
916
959
  type: string
917
960
  nullable: true
918
- minLength: 0
919
- maxLength: 75
920
- description: An optional user-defined ID for the manual account
921
- x-updatable: true
922
- custom_metadata:
923
- type: object
924
- nullable: true
925
- description: An optional JSON object that includes additional data related to
926
- this account. This must be a valid JSON object and, when
927
- stringified, must not exceed 4096 characters.
928
- additionalProperties: true
929
- x-updatable: true
930
- exclude_from_transactions:
931
- type: boolean
932
- description: If set, transactions may not be assigned to this manual account
933
- x-updatable: true
934
- to_base:
935
- type: number
936
- description: System defined balance converted to the user's primary currency. Ignored if set. Use `balance` to update the balance in the account
961
+ description: System defined name of the user who created the crypto asset. Ignored if set
937
962
  x-updatable: false
938
963
  created_at:
939
964
  type: string
940
965
  format: date-time
941
- description: System defined date/time the account was created in ISO 8601
942
- extended format. Ignored if set.
966
+ description: System defined date/time the crypto asset was created in ISO 8601 extended format. Ignored if set
943
967
  x-updatable: false
944
968
  updated_at:
945
969
  type: string
946
970
  format: date-time
947
- description: System defined date/time the account was created in ISO 8601
948
- extended format. Ignored if set.
949
- x-updatable: false
950
- created_by_name:
951
- type: string
952
- description: System defined name of the user who created the account. Ignored if set
971
+ description: System defined date/time the crypto asset was last updated in ISO 8601 extended format. Ignored if set
953
972
  x-updatable: false
973
+ description: Update a manual crypto balance. System-defined properties are accepted but ignored
954
974
 
955
- # The object containing information about a Plaid account
956
- plaidAccountObject:
975
+
976
+ # The object containing information about a manual account
977
+ manualAccountObject:
957
978
  type: object
958
- title: plaid account object
979
+ title: manual account object
959
980
  additionalProperties: false
960
- description: An object containing information about an account synced via Plaid
981
+ description: An object containing information about a manual account
961
982
  properties:
962
983
  id:
963
984
  type: integer
964
985
  format: int32
965
986
  description: The unique identifier of this account
966
- plaid_item_id:
967
- type: string
968
- nullable: true
969
- minLength: 0
970
- maxLength: 255
971
- description: The unique identifier of the Plaid connection that this account belongs to. Accounts with the same plaid_item_id usually belong to the same institution.
972
- date_linked:
973
- type: string
974
- format: date
975
- description: Date account was first linked in ISO 8601 format
976
- linked_by_name:
977
- type: string
978
- nullable: false
979
- description: The name of the user who linked the account
980
987
  name:
981
988
  type: string
982
- description: Name of the account. This field is set by Plaid and cannot be
983
- altered.
989
+ description: Name of the account
990
+ minLength: 1
991
+ maxLength: 45
992
+ institution_name:
993
+ type: string
994
+ nullable: true
995
+ minLength: 1
996
+ maxLength: 50
997
+ description: Name of institution holding the account
984
998
  display_name:
985
999
  type: string
986
1000
  nullable: true
987
- description: Optional display name for the account set by the user. If not set,
988
- it will return a concatenated string of institution and account
989
- name.
1001
+ description: Optional display name for the account as set by the user or derived from the `institution_name` and `name` if not explicitly set.
990
1002
  type:
991
- type: string
992
- description: Primary type of the account, such as `credit`, `depository`, etc.
993
- This field is set by Plaid and cannot be altered.
1003
+ description: Primary type of the account
1004
+ allOf:
1005
+ - $ref: "#/components/schemas/accountTypeEnum"
994
1006
  subtype:
995
1007
  type: string
996
- description: Optional account subtype. This field is set by Plaid and cannot be
997
- altered.
998
- mask:
999
- type: string
1000
- description: Mask (last 3 to 4 digits of account) of account. This field is set
1001
- by Plaid and cannot be altered.
1002
- institution_name:
1003
- type: string
1004
- description: Name of institution holding the account. This field is set by Plaid
1005
- and cannot be altered.
1006
- status:
1007
- type: string
1008
- description: "Denotes the current status of the account within Lunch Money. Must
1009
- be one of<br>
1010
- - active: Account is actively syncing transactions and/or balance<br>
1011
- - inactive: Account marked inactive from user. Transaction imports and balance updates will not occur for this account.<br>
1012
- - closed: Account is marked as closed<br>
1013
- - deactivated: Account is marked deactivated during setup. The user must click `Add/Remove Accounts From This Bank` and manually re-select this account to activate it.'<br>
1014
- - not found: Account was once linked but can no longer be found with Plaid.<br>
1015
- - not supported: Account is not supported by Plaid.<br>
1016
- - relink: Account (and others with the same connection) need to be relinked with Plaid.<br>
1017
- - syncing: Account is awaiting the first import of transactions.<br>
1018
- - revoked: Account connection has been revoked by Plaid and syncing is no longer possible. A new connection needs to be set up again.<br>
1019
- - error: Account (and others with the same connection) is in error with Plaid and requires intervention to re-activate it.<br>"
1020
- enum:
1021
- - active
1022
- - inactive
1023
- - closed
1024
- - deactivated
1025
- - not found
1026
- - not supported
1027
- - relink
1028
- - syncing
1029
- - revoked
1030
- - error
1031
- allow_transaction_modifications:
1032
- type: boolean
1033
- description: If `false`, transactions imported for this synced account can have their properties (such as amount and account) be modified by the user. This option is managed in the web app.
1034
- limit:
1035
- type: number
1036
1008
  nullable: true
1037
- description: Optional credit limit of the account. This field is set by Plaid
1038
- and cannot be altered
1009
+ description: Optional account subtype. Examples include<br> - retirement -
1010
+ checking - savings - prepaid credit card
1011
+ minLength: 1
1012
+ maxLength: 100
1039
1013
  balance:
1040
1014
  type: string
1041
- description: Current balance of the account in numeric format to 4 decimal
1042
- places. This field is set by Plaid and cannot be altered.
1015
+ pattern: ^-?\d+(\.\d{1,4})?$
1016
+ description: Current balance of the account in numeric format to 4 decimal places
1043
1017
  currency:
1044
1018
  type: string
1045
1019
  minLength: 3
@@ -1047,505 +1021,882 @@ components:
1047
1021
  description: Three-letter lowercase currency code of the account balance
1048
1022
  to_base:
1049
1023
  type: number
1050
- description: The account balance converted to the user's primary currency
1051
- balance_last_update:
1024
+ description: The balance converted to the user's primary currency
1025
+ balance_as_of:
1052
1026
  type: string
1053
1027
  format: date-time
1054
- nullable: true
1055
- description: Date balance was last updated in ISO 8601 extended format. This
1056
- field is set by Plaid and cannot be altered.
1057
- import_start_date:
1028
+ description: Date balance was last updated in ISO 8601 extended format, can be in date or date-time format
1029
+ status:
1030
+ type: string
1031
+ description: The status of the account
1032
+ enum:
1033
+ - active
1034
+ - closed
1035
+ closed_on:
1058
1036
  type: string
1059
1037
  format: date
1060
1038
  nullable: true
1061
- description: Date of earliest date allowed for importing transactions.
1062
- Transactions earlier than this date are not imported.
1063
- last_import:
1039
+ description: The date this account was closed in YYYY-MM-DD format. Will be null if the account has
1040
+ not been marked as closed.
1041
+ external_id:
1064
1042
  type: string
1065
- format: date-time
1066
1043
  nullable: true
1067
- description: Timestamp in ISO 8601 extended format of the last time Lunch Money
1068
- imported new data from Plaid for this account.
1069
- last_fetch:
1044
+ minLength: 0
1045
+ maxLength: 75
1046
+ description: An optional external_id that may be set or updated via the API
1047
+ custom_metadata:
1048
+ type: object
1049
+ nullable: true
1050
+ description: User defined JSON data that can be set or cleared via the API
1051
+ additionalProperties: true
1052
+ exclude_from_transactions:
1053
+ type: boolean
1054
+ default: false
1055
+ description: If true, this account will not show up as an option for assignment
1056
+ when creating transactions manually
1057
+ created_by_name:
1058
+ type: string
1059
+ description: The name of the user who created the account
1060
+ created_at:
1070
1061
  type: string
1071
1062
  format: date-time
1072
- nullable: true
1073
- description: Timestamp in ISO 8601 extended format of the last successful
1074
- request from Lunch Money for updated data or timestamps from Plaid
1075
- in ISO 8601 extended format (not necessarily date of last successful
1076
- import)
1077
- plaid_last_successful_update:
1063
+ description: Date/time the account was created in ISO 8601 extended format
1064
+ updated_at:
1078
1065
  type: string
1079
1066
  format: date-time
1080
- nullable: true
1081
- description: Timestamp in ISO 8601 extended format of the last time Plaid
1082
- successfully connected with institution for new transaction updates,
1083
- regardless of whether any new data was available in the update.
1067
+ description: Date/time the account was created in ISO 8601 extended format
1084
1068
  required:
1085
1069
  - id
1086
- - plaid_item_id
1087
- - date_linked
1088
- - linked_by_name
1089
1070
  - name
1090
- - display_name
1091
1071
  - type
1092
1072
  - subtype
1093
- - mask
1094
- - institution_name
1095
- - status
1096
- - allow_transaction_modifications
1097
- - limit
1073
+ - display_name
1098
1074
  - balance
1099
1075
  - currency
1100
1076
  - to_base
1101
- - balance_last_update
1102
- - import_start_date
1103
- - last_import
1104
- - last_fetch
1105
- - plaid_last_successful_update
1077
+ - balance_as_of
1078
+ - closed_on
1079
+ - institution_name
1080
+ - external_id
1081
+ - exclude_from_transactions
1082
+ - created_by_name
1083
+ - created_at
1084
+ - updated_at
1085
+ - status
1106
1086
 
1107
- # The object containing information about a recurring item
1108
- recurringObject:
1087
+ # The object that may be submitted to POST /manual_accounts
1088
+ createManualAccountRequestObject:
1109
1089
  type: object
1110
- title: recurring item object
1090
+ additionalProperties: false
1091
+ x-internal: true
1092
+ properties:
1093
+ name:
1094
+ type: string
1095
+ description: Name of the manual account
1096
+ minLength: 1
1097
+ maxLength: 45
1098
+ example: My Savings Account
1099
+ institution_name:
1100
+ type: string
1101
+ example: Bank of the West
1102
+ description: Name of institution holding the manual account
1103
+ minLength: 1
1104
+ maxLength: 50
1105
+ display_name:
1106
+ type: string
1107
+ description: Display name of the manual account as set by user or derived from the `institution_name` and `name` if not explicitly set.<br>
1108
+ This must be unique for the budgeting account.
1109
+ example: Savings
1110
+ type:
1111
+ description: The type of manual account
1112
+ allOf:
1113
+ - $ref: "#/components/schemas/accountTypeEnum"
1114
+ subtype:
1115
+ type: string
1116
+ description: An optional manual account subtype. Examples include<br> -
1117
+ retirement - checking - savings - prepaid credit card
1118
+ minLength: 1
1119
+ maxLength: 100
1120
+ example: prepaid credit card
1121
+ balance:
1122
+ oneOf:
1123
+ - type: number
1124
+ format: double
1125
+ - type: string
1126
+ pattern: ^-?\d+(\.\d{1,4})?$
1127
+ example: "195.50"
1128
+ description: Numeric value of the current balance, up to four decimal places, of
1129
+ the account as a number or string. Do not include any special
1130
+ characters aside from a decimal point.
1131
+ balance_as_of:
1132
+ type: string
1133
+ oneOf:
1134
+ - format: date-time
1135
+ - format: date
1136
+ example: "2024-09-15"
1137
+ description: Date/time the balance of the manual account was last updated in ISO 8601 extended format
1138
+ currency:
1139
+ description: Three-letter lowercase currency code of the transaction in ISO 4217
1140
+ format
1141
+ allOf:
1142
+ - $ref: "#/components/schemas/currencyEnum"
1143
+ status:
1144
+ type: string
1145
+ description: The status of the account
1146
+ enum:
1147
+ - active
1148
+ - closed
1149
+ default: active
1150
+ closed_on:
1151
+ oneOf:
1152
+ - type: string
1153
+ format: date
1154
+ - type: string
1155
+ format: date-time
1156
+ nullable: true
1157
+ example: "2024-10-01"
1158
+ description: The date this manual account was closed in YYYY-MM-DD format. If set, `status` must also be set to `closed`.
1159
+ external_id:
1160
+ type: string
1161
+ nullable: true
1162
+ minLength: 0
1163
+ maxLength: 75
1164
+ description: An optional user-defined ID for the manual account
1165
+ custom_metadata:
1166
+ type: object
1167
+ nullable: true
1168
+ description: An optional JSON object that includes additional data related to
1169
+ this account. This must be a valid JSON object and, when
1170
+ stringified, must not exceed 4096 characters.
1171
+ additionalProperties: true
1172
+ exclude_from_transactions:
1173
+ type: boolean
1174
+ description: If `true`, transactions may not be assigned to this manual account
1175
+ default: false
1176
+ required:
1177
+ - name
1178
+ - type
1179
+ - balance
1180
+
1181
+ # The object that may be submitted to PUT /manual_accounts/:id
1182
+ updateManualAccountRequestObject:
1183
+ type: object
1184
+ x-internal: true
1185
+ additionalProperties: false
1111
1186
  properties:
1112
1187
  id:
1113
1188
  type: integer
1114
1189
  format: int32
1115
- description: The unique identifier of this recurring item
1116
- description:
1190
+ description: System defined unique identifier of this account. Ignored if set
1191
+ x-updatable: false
1192
+ name:
1193
+ type: string
1194
+ description: If set, the new name of the manual account
1195
+ minLength: 1
1196
+ maxLength: 45
1197
+ x-updatable: true
1198
+ institution_name:
1117
1199
  type: string
1118
1200
  nullable: true
1119
- description: An optional description of this recurring item.
1120
- status:
1201
+ description: If set, the name of institution holding the account
1202
+ minLength: 1
1203
+ maxLength: 50
1204
+ x-updatable: true
1205
+ display_name:
1121
1206
  type: string
1122
- description: The status of this recurring item. `suggested` recurring items are
1123
- generated by Lunch Money, but only `reviewed` recurring items will
1124
- be applied to matching transactions.
1125
- enum:
1126
- - suggested
1127
- - reviewed
1128
- transaction_criteria:
1129
- type: object
1130
- description: The set of properties used to identify matching transactions.
1131
- properties:
1132
- start_date:
1133
- type: string
1134
- format: date
1135
- nullable: true
1136
- description: The beginning of the date range for matching transactions. If `null`,
1137
- any transactions before end_date may be considered.
1138
- end_date:
1139
- type: string
1140
- format: date
1141
- nullable: true
1142
- description: The end of the date range for matching transactions. If `null`, any
1143
- transactions after start_date may be considered.
1144
- granularity:
1145
- type: string
1146
- description: The unit of time used to define the cadence of the recurring item.
1147
- enum:
1148
- - day
1149
- - week
1150
- - month
1151
- - year
1152
- quantity:
1153
- type: integer
1154
- description: The number of granularity units between each recurrence.
1155
- anchor_date:
1156
- type: string
1157
- format: date
1158
- nullable: false
1159
- description: The date used in conjunction with the `quantity` and `granularity`
1160
- properties to calculate expected occurrences of recurring
1161
- transactions.
1162
- payee:
1163
- type: string
1164
- nullable: true
1165
- description: If set, represents the original transaction payee name that
1166
- triggered this recurring item's creation.
1167
- amount:
1168
- type: string
1207
+ nullable: true
1208
+ description: If set, the new display name for the manual account.<br>
1209
+ This must be unique for the user.
1210
+ x-updatable: true
1211
+ type:
1212
+ description: If set, the new type of the manual account
1213
+ x-updatable: true
1214
+ allOf:
1215
+ - $ref: "#/components/schemas/accountTypeEnum"
1216
+ subtype:
1217
+ type: string
1218
+ description: If set, an optional account subtype. Examples include<br> -
1219
+ retirement - checking - savings - prepaid credit card
1220
+ minLength: 1
1221
+ maxLength: 100
1222
+ x-updatable: true
1223
+ balance:
1224
+ oneOf:
1225
+ - type: number
1226
+ format: double
1227
+ - type: string
1169
1228
  pattern: ^-?\d+(\.\d{1,4})?$
1170
- description: The expected amount for a transaction that will match this
1171
- recurring item. For recurring items that have a flexible amount
1172
- this is the average of the specified min and max amounts.
1173
- to_base:
1174
- type: number
1175
- description: The amount converted to the user's primary currency
1176
- currency:
1177
- type: string
1178
- nullable: false
1179
- description: Three-letter lowercase currency code of the recurring item.
1180
- plaid_account_id:
1181
- type: integer
1182
- format: int64
1183
- nullable: true
1184
- description: The Plaid account ID associated with the recurring item, if any.
1185
- manual_account_id:
1186
- type: integer
1187
- format: int64
1188
- nullable: true
1189
- description: The manual account ID associated with the recurring item, if any.
1190
- required:
1191
- - start_date
1192
- - end_date
1193
- - granularity
1194
- - quantity
1195
- - anchor_date
1196
- - payee
1197
- - amount
1198
- - to_base
1199
- - currency
1200
- - plaid_account_id
1201
- - manual_account_id
1202
- overrides:
1203
- type: object
1204
- description: The values that will be applied to matching transactions.
1205
- properties:
1206
- payee:
1207
- type: string
1208
- nullable: false
1209
- description: If present, the payee name that will be displayed for any matching
1210
- transactions.
1211
- notes:
1212
- type: string
1213
- nullable: false
1214
- description: If present, the notes that will be displayed for any matching
1215
- transactions.
1216
- category_id:
1217
- type: integer
1218
- nullable: false
1219
- description: If present, the ID of the category that matching transactions will
1220
- be assigned to.
1221
- matches:
1222
- type: object
1229
+ example: "195.50"
1230
+ description: Numeric value of the current balance, up to four decimal places, of
1231
+ the manual account as a number or string. Do not include any special
1232
+ characters aside from a decimal point.
1233
+ x-updatable: true
1234
+ currency:
1235
+ description: If set, the new three-letter lowercase currency code of the manual account
1236
+ balance.
1237
+ x-updatable: true
1238
+ allOf:
1239
+ - $ref: "#/components/schemas/currencyEnum"
1240
+ balance_as_of:
1241
+ type: string
1242
+ oneOf:
1243
+ - format: date-time
1244
+ - format: date
1245
+ description: "A new date for the `updated_at` property.
1246
+ May be set as a date, ie: YYYY-MM-DD, or date-time string in ISO 8601 extended format.
1247
+ This property is ignored if `balance` is not also set. If `balance` is set and this property is
1248
+ not set the current time is used."
1249
+ x-updatable: true
1250
+ status:
1251
+ type: string
1252
+ description: If set, the status of the manual account. If set to `closed`, the `closed_on_date` date will be set to the current date, unless it is also set.
1253
+ enum:
1254
+ - active
1255
+ - closed
1256
+ x-updatable: true
1257
+ closed_on:
1223
1258
  nullable: true
1224
- description: Details on expected, found and missing transactions for the
1225
- specified range. This will be `null` for recurring items with a
1226
- `status` of `suggested`.
1227
- properties:
1228
- request_start_date:
1229
- type: string
1230
- format: date
1231
- description: The beginning of the date range that this request used to find
1232
- matching transactions.
1233
- request_end_date:
1234
- type: string
1259
+ oneOf:
1260
+ - type: string
1235
1261
  format: date
1236
- description: The beginning of the date range that this request used to find
1237
- matching transactions.
1238
- expected_occurrence_dates:
1239
- type: array
1240
- items:
1241
- type: string
1242
- format: date
1243
- description: A list of dates within the specified range where a recurring
1244
- transactions is expected.
1245
- found_transactions:
1246
- type: array
1247
- description: A list with the dates and IDs of matching transactions.
1248
- items:
1249
- type: object
1250
- properties:
1251
- date:
1252
- type: string
1253
- format: date
1254
- description: The date for a matching transaction within the specified range.
1255
- transaction_id:
1256
- type: integer
1257
- description: The ID of a matching transaction within the specified range.
1258
- missing_transaction_dates:
1259
- type: array
1260
- items:
1261
- type: string
1262
- format: date
1263
- description: A list of dates within the range of where a recurring transaction
1264
- was expected but none was found.
1265
- created_by:
1266
- type: integer
1267
- nullable: false
1268
- description: The ID of the user who created the recurring item.
1262
+ - type: string
1263
+ format: date-time
1264
+ description: If set, the date this manual account was closed in YYYY-MM-DD format. If updating an account that is not already closed, `status` must also be set to `closed`.
1265
+ x-updatable: true
1266
+ external_id:
1267
+ type: string
1268
+ nullable: true
1269
+ minLength: 0
1270
+ maxLength: 75
1271
+ description: An optional user-defined ID for the manual account
1272
+ x-updatable: true
1273
+ custom_metadata:
1274
+ type: object
1275
+ nullable: true
1276
+ description: An optional JSON object that includes additional data related to
1277
+ this account. This must be a valid JSON object and, when
1278
+ stringified, must not exceed 4096 characters.
1279
+ additionalProperties: true
1280
+ x-updatable: true
1281
+ exclude_from_transactions:
1282
+ type: boolean
1283
+ description: If set, transactions may not be assigned to this manual account
1284
+ x-updatable: true
1285
+ to_base:
1286
+ type: number
1287
+ description: System defined balance converted to the user's primary currency. Ignored if set. Use `balance` to update the balance in the account
1288
+ x-updatable: false
1269
1289
  created_at:
1270
1290
  type: string
1271
1291
  format: date-time
1272
- nullable: false
1273
- description: Date/time the recurring item was created in ISO 8601 extended format.
1292
+ description: System defined date/time the account was created in ISO 8601
1293
+ extended format. Ignored if set.
1294
+ x-updatable: false
1274
1295
  updated_at:
1275
1296
  type: string
1276
1297
  format: date-time
1277
- nullable: false
1278
- description: Date/time the recurring item was updated in ISO 8601 extended format.
1279
- source:
1298
+ description: System defined date/time the account was created in ISO 8601
1299
+ extended format. Ignored if set.
1300
+ x-updatable: false
1301
+ created_by_name:
1280
1302
  type: string
1281
- description: >
1282
- This can be one of four values:
1283
-
1284
- - `manual`: User created this recurring item manually from the
1285
- Recurring Items page
1286
-
1287
- - `transaction`: User created this by converting a transaction from
1288
- the Transactions page
1289
-
1290
- - `system`: Recurring item was created by the system on transaction
1291
- import
1303
+ description: System defined name of the user who created the account. Ignored if set
1304
+ x-updatable: false
1292
1305
 
1293
- - `null`: Some older recurring items may not have a source.
1294
- enum:
1295
- - manual
1296
- - transaction
1297
- - system
1298
- required:
1299
- - id
1300
- - description
1301
- - status
1302
- - transaction_criteria
1303
- - overrides
1304
- - matches
1305
- - created_by
1306
- - created_at
1307
- - updated_at
1308
- - source
1309
-
1310
- # The object containing information about a tag
1311
- tagObject:
1306
+ # The object containing information about a Plaid account
1307
+ plaidAccountObject:
1312
1308
  type: object
1313
- title: tag object
1309
+ title: plaid account object
1314
1310
  additionalProperties: false
1311
+ description: An object containing information about an account synced via Plaid
1315
1312
  properties:
1316
1313
  id:
1317
1314
  type: integer
1318
1315
  format: int32
1319
- description: Unique identifier for the tag.
1320
- name:
1321
- type: string
1322
- description: Name of the tag.
1323
- description:
1324
- type: string
1325
- nullable: true
1326
- description: Description of the tag.
1327
- text_color:
1316
+ description: The unique identifier of this account
1317
+ plaid_item_id:
1328
1318
  type: string
1329
1319
  nullable: true
1330
- description: The text color of the tag.
1331
- background_color:
1320
+ minLength: 0
1321
+ maxLength: 255
1322
+ description: The unique identifier of the Plaid connection that this account belongs to. Accounts with the same plaid_item_id usually belong to the same institution.
1323
+ date_linked:
1332
1324
  type: string
1333
- nullable: true
1334
- description: The background color of the tag.
1335
- updated_at:
1325
+ format: date
1326
+ description: Date account was first linked in ISO 8601 format
1327
+ linked_by_name:
1336
1328
  type: string
1337
- format: date-time
1338
1329
  nullable: false
1339
- description: The date and time of when the tag was last updated (in the ISO 8601
1340
- extended format).
1341
- created_at:
1330
+ description: The name of the user who linked the account
1331
+ name:
1342
1332
  type: string
1343
- format: date-time
1344
- nullable: false
1345
- description: The date and time of when the tag was created (in the ISO 8601
1346
- extended format).
1347
- archived:
1348
- type: boolean
1349
- description: If `true`, the tag will not show up when creating or updating
1350
- transactions in the Lunch Money app. **Can it be assigned via the
1351
- API**
1352
- archived_at:
1333
+ description: Name of the account. This field is set by Plaid and cannot be
1334
+ altered.
1335
+ display_name:
1353
1336
  type: string
1354
- format: date-time
1355
1337
  nullable: true
1356
- description: The date and time of when the tag was last archived or `null` if not
1357
- archived
1358
- required:
1359
- - id
1360
- - name
1361
- - description
1362
- - text_color
1363
- - background_color
1364
- - created_at
1365
- - updated_at
1366
- - archived
1367
- - archived_at
1368
-
1369
- # The object that may be submitted to POST /tags
1370
- createTagRequestObject:
1371
- type: object
1372
- additionalProperties: false
1373
- x-internal: true
1374
- properties:
1375
- name:
1338
+ description: Optional display name for the account set by the user. If not set,
1339
+ it will return a concatenated string of institution and account
1340
+ name.
1341
+ type:
1376
1342
  type: string
1377
- nullable: false
1378
- description: |-
1379
- The name of the new tag. Must be between 1 and 100 characters.
1380
- Must not match the name of any existing tags.
1381
- minLength: 1
1382
- maxLength: 100
1383
- description:
1343
+ description: Primary type of the account, such as `credit`, `depository`, etc.
1344
+ This field is set by Plaid and cannot be altered.
1345
+ subtype:
1384
1346
  type: string
1385
- nullable: true
1386
- default: null
1387
- description: The description of the tag. Must not exceed 200 characters.
1388
- maxLength: 200
1389
- text_color:
1347
+ description: Optional account subtype. This field is set by Plaid and cannot be
1348
+ altered.
1349
+ mask:
1390
1350
  type: string
1391
- nullable: true
1392
- description: The text color of the tag.
1393
- background_color:
1351
+ description: Mask (last 3 to 4 digits of account) of account. This field is set
1352
+ by Plaid and cannot be altered.
1353
+ institution_name:
1394
1354
  type: string
1395
- nullable: true
1396
- description: The background color of the tag.
1397
- archived:
1355
+ description: Name of institution holding the account. This field is set by Plaid
1356
+ and cannot be altered.
1357
+ status:
1358
+ type: string
1359
+ description: "Denotes the current status of the account within Lunch Money. Must
1360
+ be one of<br>
1361
+ - active: Account is actively syncing transactions and/or balance<br>
1362
+ - inactive: Account marked inactive from user. Transaction imports and balance updates will not occur for this account.<br>
1363
+ - closed: Account is marked as closed<br>
1364
+ - deactivated: Account is marked deactivated during setup. The user must click `Add/Remove Accounts From This Bank` and manually re-select this account to activate it.'<br>
1365
+ - not found: Account was once linked but can no longer be found with Plaid.<br>
1366
+ - not supported: Account is not supported by Plaid.<br>
1367
+ - relink: Account (and others with the same connection) need to be relinked with Plaid.<br>
1368
+ - syncing: Account is awaiting the first import of transactions.<br>
1369
+ - revoked: Account connection has been revoked by Plaid and syncing is no longer possible. A new connection needs to be set up again.<br>
1370
+ - error: Account (and others with the same connection) is in error with Plaid and requires intervention to re-activate it.<br>"
1371
+ enum:
1372
+ - active
1373
+ - inactive
1374
+ - closed
1375
+ - deactivated
1376
+ - not found
1377
+ - not supported
1378
+ - relink
1379
+ - syncing
1380
+ - revoked
1381
+ - error
1382
+ allow_transaction_modifications:
1398
1383
  type: boolean
1399
- default: false
1400
- description: If `true`, the tag is archived and not displayed in relevant areas of
1401
- the Lunch Money app.
1402
- required:
1403
- - name
1404
-
1405
- # The object that may be submitted to PUT /tags/:id
1406
- updateTagRequestObject:
1407
- type: object
1408
- x-internal: true
1409
- additionalProperties: false
1410
- properties:
1411
- name:
1384
+ description: If `false`, transactions imported for this synced account can have their properties (such as amount and account) be modified by the user. This option is managed in the web app.
1385
+ limit:
1386
+ type: number
1387
+ nullable: true
1388
+ description: Optional credit limit of the account. This field is set by Plaid
1389
+ and cannot be altered
1390
+ balance:
1412
1391
  type: string
1413
- nullable: false
1414
- description: If set, the new name of the category. Must be between 1 and 100
1415
- characters.
1416
- minLength: 1
1417
- maxLength: 100
1418
- x-updatable: true
1419
- description:
1392
+ description: Current balance of the account in numeric format to 4 decimal
1393
+ places. This field is set by Plaid and cannot be altered.
1394
+ currency:
1420
1395
  type: string
1421
- nullable: true
1422
- description: If set, the new description of the category. Must not exceed 200
1423
- characters.
1424
- maxLength: 200
1425
- x-updatable: true
1426
- text_color:
1396
+ minLength: 3
1397
+ maxLength: 3
1398
+ description: Three-letter lowercase currency code of the account balance
1399
+ to_base:
1400
+ type: number
1401
+ description: The account balance converted to the user's primary currency
1402
+ balance_last_update:
1427
1403
  type: string
1404
+ format: date-time
1428
1405
  nullable: true
1429
- description: The text color of the tag.
1430
- x-updatable: true
1431
- background_color:
1406
+ description: Date balance was last updated in ISO 8601 extended format. This
1407
+ field is set by Plaid and cannot be altered.
1408
+ import_start_date:
1432
1409
  type: string
1410
+ format: date
1433
1411
  nullable: true
1434
- description: The background color of the tag.
1435
- x-updatable: true
1436
- archived:
1437
- type: boolean
1438
- description: If set, will indicate if this category is archived.
1439
- x-updatable: true
1440
- id:
1441
- type: integer
1442
- format: int32
1443
- description: System-defined unique identifier for the category. Ignored if set.
1444
- x-updatable: false
1445
- updated_at:
1412
+ description: Date of earliest date allowed for importing transactions.
1413
+ Transactions earlier than this date are not imported.
1414
+ last_import:
1446
1415
  type: string
1447
1416
  format: date-time
1448
- nullable: false
1449
- description: System-set time the tag was last updated. Ignored if set
1450
- x-updatable: false
1451
- created_at:
1417
+ nullable: true
1418
+ description: Timestamp in ISO 8601 extended format of the last time Lunch Money
1419
+ imported new data from Plaid for this account.
1420
+ last_fetch:
1452
1421
  type: string
1453
1422
  format: date-time
1454
- nullable: false
1455
- description: System-set time the tag was created. Ignored if set.
1456
- x-updatable: false
1457
- archived_at:
1423
+ nullable: true
1424
+ description: Timestamp in ISO 8601 extended format of the last successful
1425
+ request from Lunch Money for updated data or timestamps from Plaid
1426
+ in ISO 8601 extended format (not necessarily date of last successful
1427
+ import)
1428
+ plaid_last_successful_update:
1458
1429
  type: string
1459
1430
  format: date-time
1460
1431
  nullable: true
1461
- description: System-set time the tag was archived. Ignored if set.
1462
- x-updatable: false
1432
+ description: Timestamp in ISO 8601 extended format of the last time Plaid
1433
+ successfully connected with institution for new transaction updates,
1434
+ regardless of whether any new data was available in the update.
1435
+ required:
1436
+ - id
1437
+ - plaid_item_id
1438
+ - date_linked
1439
+ - linked_by_name
1440
+ - name
1441
+ - display_name
1442
+ - type
1443
+ - subtype
1444
+ - mask
1445
+ - institution_name
1446
+ - status
1447
+ - allow_transaction_modifications
1448
+ - limit
1449
+ - balance
1450
+ - currency
1451
+ - to_base
1452
+ - balance_last_update
1453
+ - import_start_date
1454
+ - last_import
1455
+ - last_fetch
1456
+ - plaid_last_successful_update
1463
1457
 
1464
- # The object returned when a DELETE /tag/:id request
1465
- # has an id for a tag that has dependencies
1466
- deleteTagResponseWithDependencies:
1458
+ # The object containing information about a recurring item
1459
+ recurringObject:
1467
1460
  type: object
1468
- x-internal: true
1469
- additionalProperties: false
1461
+ title: recurring item object
1470
1462
  properties:
1471
- tag_name:
1463
+ id:
1464
+ type: integer
1465
+ format: int32
1466
+ description: The unique identifier of this recurring item
1467
+ description:
1472
1468
  type: string
1473
- description: The name of the tag
1474
- dependents:
1469
+ nullable: true
1470
+ description: An optional description of this recurring item.
1471
+ status:
1472
+ type: string
1473
+ description: The status of this recurring item. `suggested` recurring items are
1474
+ generated by Lunch Money, but only `reviewed` recurring items will
1475
+ be applied to matching transactions.
1476
+ enum:
1477
+ - suggested
1478
+ - reviewed
1479
+ transaction_criteria:
1475
1480
  type: object
1481
+ description: The set of properties used to identify matching transactions.
1476
1482
  properties:
1477
- rules:
1483
+ start_date:
1484
+ type: string
1485
+ format: date
1486
+ nullable: true
1487
+ description: The beginning of the date range for matching transactions. If `null`,
1488
+ any transactions before end_date may be considered.
1489
+ end_date:
1490
+ type: string
1491
+ format: date
1492
+ nullable: true
1493
+ description: The end of the date range for matching transactions. If `null`, any
1494
+ transactions after start_date may be considered.
1495
+ granularity:
1496
+ type: string
1497
+ description: The unit of time used to define the cadence of the recurring item.
1498
+ enum:
1499
+ - day
1500
+ - week
1501
+ - month
1502
+ - year
1503
+ quantity:
1478
1504
  type: integer
1479
- description: The number of rules depending on the tag
1480
- transactions:
1505
+ description: The number of granularity units between each recurrence.
1506
+ anchor_date:
1507
+ type: string
1508
+ format: date
1509
+ nullable: false
1510
+ description: The date used in conjunction with the `quantity` and `granularity`
1511
+ properties to calculate expected occurrences of recurring
1512
+ transactions.
1513
+ payee:
1514
+ type: string
1515
+ nullable: true
1516
+ description: If set, represents the original transaction payee name that
1517
+ triggered this recurring item's creation.
1518
+ amount:
1519
+ type: string
1520
+ pattern: ^-?\d+(\.\d{1,4})?$
1521
+ description: The expected amount for a transaction that will match this
1522
+ recurring item. For recurring items that have a flexible amount
1523
+ this is the average of the specified min and max amounts.
1524
+ to_base:
1525
+ type: number
1526
+ description: The amount converted to the user's primary currency
1527
+ currency:
1528
+ type: string
1529
+ nullable: false
1530
+ description: Three-letter lowercase currency code of the recurring item.
1531
+ plaid_account_id:
1481
1532
  type: integer
1482
- description: The number of transactions with the tag
1533
+ format: int64
1534
+ nullable: true
1535
+ description: The Plaid account ID associated with the recurring item, if any.
1536
+ manual_account_id:
1537
+ type: integer
1538
+ format: int64
1539
+ nullable: true
1540
+ description: The manual account ID associated with the recurring item, if any.
1483
1541
  required:
1484
- - rules
1485
- - transactions
1542
+ - start_date
1543
+ - end_date
1544
+ - granularity
1545
+ - quantity
1546
+ - anchor_date
1547
+ - payee
1548
+ - amount
1549
+ - to_base
1550
+ - currency
1551
+ - plaid_account_id
1552
+ - manual_account_id
1553
+ overrides:
1554
+ type: object
1555
+ description: The values that will be applied to matching transactions.
1556
+ properties:
1557
+ payee:
1558
+ type: string
1559
+ nullable: false
1560
+ description: If present, the payee name that will be displayed for any matching
1561
+ transactions.
1562
+ notes:
1563
+ type: string
1564
+ nullable: false
1565
+ description: If present, the notes that will be displayed for any matching
1566
+ transactions.
1567
+ category_id:
1568
+ type: integer
1569
+ nullable: false
1570
+ description: If present, the ID of the category that matching transactions will
1571
+ be assigned to.
1572
+ matches:
1573
+ type: object
1574
+ nullable: true
1575
+ description: Details on expected, found and missing transactions for the
1576
+ specified range. This will be `null` for recurring items with a
1577
+ `status` of `suggested`.
1578
+ properties:
1579
+ request_start_date:
1580
+ type: string
1581
+ format: date
1582
+ description: The beginning of the date range that this request used to find
1583
+ matching transactions.
1584
+ request_end_date:
1585
+ type: string
1586
+ format: date
1587
+ description: The beginning of the date range that this request used to find
1588
+ matching transactions.
1589
+ expected_occurrence_dates:
1590
+ type: array
1591
+ items:
1592
+ type: string
1593
+ format: date
1594
+ description: A list of dates within the specified range where a recurring
1595
+ transactions is expected.
1596
+ found_transactions:
1597
+ type: array
1598
+ description: A list with the dates and IDs of matching transactions.
1599
+ items:
1600
+ type: object
1601
+ properties:
1602
+ date:
1603
+ type: string
1604
+ format: date
1605
+ description: The date for a matching transaction within the specified range.
1606
+ transaction_id:
1607
+ type: integer
1608
+ description: The ID of a matching transaction within the specified range.
1609
+ missing_transaction_dates:
1610
+ type: array
1611
+ items:
1612
+ type: string
1613
+ format: date
1614
+ description: A list of dates within the range of where a recurring transaction
1615
+ was expected but none was found.
1616
+ created_by:
1617
+ type: integer
1618
+ nullable: false
1619
+ description: The ID of the user who created the recurring item.
1620
+ created_at:
1621
+ type: string
1622
+ format: date-time
1623
+ nullable: false
1624
+ description: Date/time the recurring item was created in ISO 8601 extended format.
1625
+ updated_at:
1626
+ type: string
1627
+ format: date-time
1628
+ nullable: false
1629
+ description: Date/time the recurring item was updated in ISO 8601 extended format.
1630
+ source:
1631
+ type: string
1632
+ description: >
1633
+ This can be one of four values:
1634
+
1635
+ - `manual`: User created this recurring item manually from the
1636
+ Recurring Items page
1637
+
1638
+ - `transaction`: User created this by converting a transaction from
1639
+ the Transactions page
1640
+
1641
+ - `system`: Recurring item was created by the system on transaction
1642
+ import
1643
+
1644
+ - `null`: Some older recurring items may not have a source.
1645
+ enum:
1646
+ - manual
1647
+ - transaction
1648
+ - system
1486
1649
  required:
1487
- - tag_name
1488
- - dependents
1650
+ - id
1651
+ - description
1652
+ - status
1653
+ - transaction_criteria
1654
+ - overrides
1655
+ - matches
1656
+ - created_by
1657
+ - created_at
1658
+ - updated_at
1659
+ - source
1489
1660
 
1490
- # The primary object that represents a transaction
1491
- transactionObject:
1661
+ # The object containing information about a tag
1662
+ tagObject:
1492
1663
  type: object
1493
- title: transaction object
1664
+ title: tag object
1494
1665
  additionalProperties: false
1495
1666
  properties:
1496
1667
  id:
1497
1668
  type: integer
1498
- format: int64
1499
- description: System created unique identifier for transaction
1500
- date:
1669
+ format: int32
1670
+ description: Unique identifier for the tag.
1671
+ name:
1501
1672
  type: string
1502
- format: date
1503
- description: Date of transaction in ISO 8601 format
1504
- amount:
1673
+ description: Name of the tag.
1674
+ description:
1505
1675
  type: string
1506
- description: Amount of the transaction in numeric format to 4 decimal places.
1507
- Positive values indicate a debit transaction, negative values indicate a credit transaction.
1508
- currency:
1509
- description: Three-letter lowercase currency code of the transaction in ISO 4217
1510
- format.
1511
- allOf:
1512
- - $ref: "#/components/schemas/currencyEnum"
1513
- to_base:
1514
- type: number
1515
- format: double
1516
- description: The amount converted to the user's primary currency. If the
1517
- multi-currency feature is not being used, to_base and amount will be
1518
- the same.
1519
- Positive values indicate a debit transaction, negative values indicate a credit transaction.
1520
- recurring_id:
1521
- type: integer
1522
- format: int32
1523
1676
  nullable: true
1524
- description: The unique identifier of the associated recurring item that this
1525
- transaction matched.
1526
- payee:
1527
- type: string
1528
- description: |
1529
- Name of payee set by the user, the financial institution, or by
1530
- a matched recurring item. This will match the value
1531
- displayed in payee field on the transactions page in the GUI.
1532
- minLength: 0
1533
- maxLength: 140
1534
- original_name:
1677
+ description: Description of the tag.
1678
+ text_color:
1535
1679
  type: string
1536
1680
  nullable: true
1537
- description: Original payee name from the source (financial institution, CSV, etc.). For Plaid transactions, this is the raw name before normalization. For manual/API transactions, this typically matches `payee`. May be null for older transactions.
1538
- minLength: 0
1539
- maxLength: 140
1540
- category_id:
1541
- type: integer
1542
- format: int32
1681
+ description: The text color of the tag.
1682
+ background_color:
1683
+ type: string
1543
1684
  nullable: true
1544
- description: Unique identifier of associated category set by the user or by a
1545
- matched recurring_item.<br> Category details can be obtained by
1546
- passing the value of this property to the [Get A Single
1547
- Category](../operations/getCategoryById) API
1548
- plaid_account_id:
1685
+ description: The background color of the tag.
1686
+ updated_at:
1687
+ type: string
1688
+ format: date-time
1689
+ nullable: false
1690
+ description: The date and time of when the tag was last updated (in the ISO 8601
1691
+ extended format).
1692
+ created_at:
1693
+ type: string
1694
+ format: date-time
1695
+ nullable: false
1696
+ description: The date and time of when the tag was created (in the ISO 8601
1697
+ extended format).
1698
+ archived:
1699
+ type: boolean
1700
+ description: If `true`, the tag will not show up when creating or updating
1701
+ transactions in the Lunch Money app. **Can it be assigned via the
1702
+ API**
1703
+ archived_at:
1704
+ type: string
1705
+ format: date-time
1706
+ nullable: true
1707
+ description: The date and time of when the tag was last archived or `null` if not
1708
+ archived
1709
+ required:
1710
+ - id
1711
+ - name
1712
+ - description
1713
+ - text_color
1714
+ - background_color
1715
+ - created_at
1716
+ - updated_at
1717
+ - archived
1718
+ - archived_at
1719
+
1720
+ # The object that may be submitted to POST /tags
1721
+ createTagRequestObject:
1722
+ type: object
1723
+ additionalProperties: false
1724
+ x-internal: true
1725
+ properties:
1726
+ name:
1727
+ type: string
1728
+ nullable: false
1729
+ description: |-
1730
+ The name of the new tag. Must be between 1 and 100 characters.
1731
+ Must not match the name of any existing tags.
1732
+ minLength: 1
1733
+ maxLength: 100
1734
+ description:
1735
+ type: string
1736
+ nullable: true
1737
+ default: null
1738
+ description: The description of the tag. Must not exceed 200 characters.
1739
+ maxLength: 200
1740
+ text_color:
1741
+ type: string
1742
+ nullable: true
1743
+ description: The text color of the tag.
1744
+ background_color:
1745
+ type: string
1746
+ nullable: true
1747
+ description: The background color of the tag.
1748
+ archived:
1749
+ type: boolean
1750
+ default: false
1751
+ description: If `true`, the tag is archived and not displayed in relevant areas of
1752
+ the Lunch Money app.
1753
+ required:
1754
+ - name
1755
+
1756
+ # The object that may be submitted to PUT /tags/:id
1757
+ updateTagRequestObject:
1758
+ type: object
1759
+ x-internal: true
1760
+ additionalProperties: false
1761
+ properties:
1762
+ name:
1763
+ type: string
1764
+ nullable: false
1765
+ description: If set, the new name of the category. Must be between 1 and 100
1766
+ characters.
1767
+ minLength: 1
1768
+ maxLength: 100
1769
+ x-updatable: true
1770
+ description:
1771
+ type: string
1772
+ nullable: true
1773
+ description: If set, the new description of the category. Must not exceed 200
1774
+ characters.
1775
+ maxLength: 200
1776
+ x-updatable: true
1777
+ text_color:
1778
+ type: string
1779
+ nullable: true
1780
+ description: The text color of the tag.
1781
+ x-updatable: true
1782
+ background_color:
1783
+ type: string
1784
+ nullable: true
1785
+ description: The background color of the tag.
1786
+ x-updatable: true
1787
+ archived:
1788
+ type: boolean
1789
+ description: If set, will indicate if this category is archived.
1790
+ x-updatable: true
1791
+ id:
1792
+ type: integer
1793
+ format: int32
1794
+ description: System-defined unique identifier for the category. Ignored if set.
1795
+ x-updatable: false
1796
+ updated_at:
1797
+ type: string
1798
+ format: date-time
1799
+ nullable: false
1800
+ description: System-set time the tag was last updated. Ignored if set
1801
+ x-updatable: false
1802
+ created_at:
1803
+ type: string
1804
+ format: date-time
1805
+ nullable: false
1806
+ description: System-set time the tag was created. Ignored if set.
1807
+ x-updatable: false
1808
+ archived_at:
1809
+ type: string
1810
+ format: date-time
1811
+ nullable: true
1812
+ description: System-set time the tag was archived. Ignored if set.
1813
+ x-updatable: false
1814
+
1815
+ # The object returned when a DELETE /tag/:id request
1816
+ # has an id for a tag that has dependencies
1817
+ deleteTagResponseWithDependencies:
1818
+ type: object
1819
+ x-internal: true
1820
+ additionalProperties: false
1821
+ properties:
1822
+ tag_name:
1823
+ type: string
1824
+ description: The name of the tag
1825
+ dependents:
1826
+ type: object
1827
+ properties:
1828
+ rules:
1829
+ type: integer
1830
+ description: The number of rules depending on the tag
1831
+ transactions:
1832
+ type: integer
1833
+ description: The number of transactions with the tag
1834
+ required:
1835
+ - rules
1836
+ - transactions
1837
+ required:
1838
+ - tag_name
1839
+ - dependents
1840
+
1841
+ # The primary object that represents a transaction
1842
+ transactionObject:
1843
+ type: object
1844
+ title: transaction object
1845
+ additionalProperties: false
1846
+ properties:
1847
+ id:
1848
+ type: integer
1849
+ format: int64
1850
+ description: System created unique identifier for transaction
1851
+ date:
1852
+ type: string
1853
+ format: date
1854
+ description: Date of transaction in ISO 8601 format
1855
+ amount:
1856
+ type: string
1857
+ description: Amount of the transaction in numeric format to 4 decimal places.
1858
+ Positive values indicate a debit transaction, negative values indicate a credit transaction.
1859
+ currency:
1860
+ description: Three-letter lowercase currency code of the transaction in ISO 4217
1861
+ format.
1862
+ allOf:
1863
+ - $ref: "#/components/schemas/currencyEnum"
1864
+ to_base:
1865
+ type: number
1866
+ format: double
1867
+ description: The amount converted to the user's primary currency. If the
1868
+ multi-currency feature is not being used, to_base and amount will be
1869
+ the same.
1870
+ Positive values indicate a debit transaction, negative values indicate a credit transaction.
1871
+ recurring_id:
1872
+ type: integer
1873
+ format: int32
1874
+ nullable: true
1875
+ description: The unique identifier of the associated recurring item that this
1876
+ transaction matched.
1877
+ payee:
1878
+ type: string
1879
+ description: |
1880
+ Name of payee set by the user, the financial institution, or by
1881
+ a matched recurring item. This will match the value
1882
+ displayed in payee field on the transactions page in the GUI.
1883
+ minLength: 0
1884
+ maxLength: 140
1885
+ original_name:
1886
+ type: string
1887
+ nullable: true
1888
+ description: Original payee name from the source (financial institution, CSV, etc.). For Plaid transactions, this is the raw name before normalization. For manual/API transactions, this typically matches `payee`. May be null for older transactions.
1889
+ minLength: 0
1890
+ maxLength: 140
1891
+ category_id:
1892
+ type: integer
1893
+ format: int32
1894
+ nullable: true
1895
+ description: Unique identifier of associated category set by the user or by a
1896
+ matched recurring_item.<br> Category details can be obtained by
1897
+ passing the value of this property to the [Get A Single
1898
+ Category](../operations/getCategoryById) API
1899
+ plaid_account_id:
1549
1900
  type: integer
1550
1901
  format: int32
1551
1902
  nullable: true
@@ -3896,266 +4247,695 @@ paths:
3896
4247
  summary: "Monthly budget summary with past occurrences included"
3897
4248
  description: "Example response for aligned monthly budget periods with include_past_budget_dates=true, showing 3 past occurrences with in_range: false"
3898
4249
  value:
3899
- aligned: true
3900
- categories:
3901
- - category_id: 315177
3902
- totals:
3903
- other_activity: 156.64
3904
- recurring_activity: 0
3905
- budgeted: 500
3906
- available: 343.36
3907
- recurring_remaining: 0
3908
- recurring_expected: 0
3909
- occurrences:
3910
- - in_range: false
3911
- start_date: "2025-04-01"
3912
- end_date: "2025-04-30"
3913
- other_activity: 120.50
3914
- recurring_activity: 0
3915
- budgeted: 500
3916
- budgeted_amount: "500.0000"
3917
- budgeted_currency: "usd"
3918
- notes: "Monthly budget allocation"
3919
- - in_range: false
3920
- start_date: "2025-05-01"
3921
- end_date: "2025-05-31"
3922
- other_activity: 180.25
3923
- recurring_activity: 0
3924
- budgeted: 500
3925
- budgeted_amount: "500.0000"
3926
- budgeted_currency: "usd"
3927
- notes: null
3928
- - in_range: false
3929
- start_date: "2025-06-01"
3930
- end_date: "2025-06-30"
3931
- other_activity: 200.00
3932
- recurring_activity: 0
3933
- budgeted: 500
3934
- budgeted_amount: "500.0000"
3935
- budgeted_currency: "usd"
3936
- notes: "Adjusted for seasonal spending"
3937
- - in_range: true
3938
- start_date: "2025-07-01"
3939
- end_date: "2025-07-31"
3940
- other_activity: 156.64
3941
- recurring_activity: 0
3942
- budgeted: 500
3943
- budgeted_amount: "500.0000"
3944
- budgeted_currency: "usd"
3945
- notes: "Monthly budget allocation"
3946
- "with rollover pool":
3947
- summary: "Monthly budget summary with rollover pool included"
3948
- description: "Example response for aligned monthly budget periods with include_rollover_pool=true, showing rollover pool data for categories with budgets"
4250
+ aligned: true
4251
+ categories:
4252
+ - category_id: 315177
4253
+ totals:
4254
+ other_activity: 156.64
4255
+ recurring_activity: 0
4256
+ budgeted: 500
4257
+ available: 343.36
4258
+ recurring_remaining: 0
4259
+ recurring_expected: 0
4260
+ occurrences:
4261
+ - in_range: false
4262
+ start_date: "2025-04-01"
4263
+ end_date: "2025-04-30"
4264
+ other_activity: 120.50
4265
+ recurring_activity: 0
4266
+ budgeted: 500
4267
+ budgeted_amount: "500.0000"
4268
+ budgeted_currency: "usd"
4269
+ notes: "Monthly budget allocation"
4270
+ - in_range: false
4271
+ start_date: "2025-05-01"
4272
+ end_date: "2025-05-31"
4273
+ other_activity: 180.25
4274
+ recurring_activity: 0
4275
+ budgeted: 500
4276
+ budgeted_amount: "500.0000"
4277
+ budgeted_currency: "usd"
4278
+ notes: null
4279
+ - in_range: false
4280
+ start_date: "2025-06-01"
4281
+ end_date: "2025-06-30"
4282
+ other_activity: 200.00
4283
+ recurring_activity: 0
4284
+ budgeted: 500
4285
+ budgeted_amount: "500.0000"
4286
+ budgeted_currency: "usd"
4287
+ notes: "Adjusted for seasonal spending"
4288
+ - in_range: true
4289
+ start_date: "2025-07-01"
4290
+ end_date: "2025-07-31"
4291
+ other_activity: 156.64
4292
+ recurring_activity: 0
4293
+ budgeted: 500
4294
+ budgeted_amount: "500.0000"
4295
+ budgeted_currency: "usd"
4296
+ notes: "Monthly budget allocation"
4297
+ "with rollover pool":
4298
+ summary: "Monthly budget summary with rollover pool included"
4299
+ description: "Example response for aligned monthly budget periods with include_rollover_pool=true, showing rollover pool data for categories with budgets"
4300
+ value:
4301
+ aligned: true
4302
+ categories:
4303
+ - category_id: 315177
4304
+ totals:
4305
+ other_activity: 156.64
4306
+ recurring_activity: 0
4307
+ budgeted: 500
4308
+ available: 343.36
4309
+ recurring_remaining: 0
4310
+ recurring_expected: 0
4311
+ occurrences:
4312
+ - in_range: true
4313
+ start_date: "2025-07-01"
4314
+ end_date: "2025-07-31"
4315
+ other_activity: 156.64
4316
+ recurring_activity: 0
4317
+ budgeted: 500
4318
+ budgeted_amount: "500.0000"
4319
+ budgeted_currency: "usd"
4320
+ notes: "Monthly budget allocation"
4321
+ rollover_pool:
4322
+ budgeted_to_base: 179.50
4323
+ all_adjustments:
4324
+ - in_range: false
4325
+ date: "2025-06-30"
4326
+ amount: "179.5000"
4327
+ currency: "usd"
4328
+ to_base: 179.50
4329
+ - in_range: false
4330
+ date: "2025-05-31"
4331
+ amount: "120.2500"
4332
+ currency: "usd"
4333
+ to_base: 120.25
4334
+ - in_range: false
4335
+ date: "2025-04-30"
4336
+ amount: "80.0000"
4337
+ currency: "usd"
4338
+ to_base: 80.00
4339
+ "401":
4340
+ $ref: "#/components/responses/unauthorizedToken"
4341
+ "429":
4342
+ $ref: "#/components/responses/rateLimited"
4343
+ "500":
4344
+ $ref: "#/components/responses/serverError"
4345
+ /categories:
4346
+ get:
4347
+ tags:
4348
+ - categories
4349
+ summary: Get all categories
4350
+ description: Retrieve a list of all categories associated with the user's account.
4351
+ operationId: getAllCategories
4352
+ parameters:
4353
+ - name: format
4354
+ in: query
4355
+ description: If `nested`, returns top-level categories (either category groups
4356
+ or categories not part of a category group) in alphabetical order.
4357
+ Grouped categories are nested within the category group under the
4358
+ property `children`. A `flattened`, response is similar but it
4359
+ includes grouped categories at the top level.<br/><br/> Categories
4360
+ are sorted by their `order`. When `order` is null, they are listed in
4361
+ alphabetical order below other categories with an `order`.
4362
+ required: false
4363
+ schema:
4364
+ type: string
4365
+ default: nested
4366
+ enum:
4367
+ - nested
4368
+ - flattened
4369
+ - name: is_group
4370
+ in: query
4371
+ description: If `false`, only categories not part of a category group
4372
+ are returned.<br> If `true`, only category groups are
4373
+ returned.<br> When set, the `format` parameter is ignored.
4374
+ required: false
4375
+ schema:
4376
+ type: boolean
4377
+ responses:
4378
+ "200":
4379
+ description: A list of Category Objects
4380
+ content:
4381
+ application/json:
4382
+ schema:
4383
+ type: object
4384
+ properties:
4385
+ categories:
4386
+ type: array
4387
+ items:
4388
+ $ref: "#/components/schemas/categoryObject"
4389
+ examples:
4390
+ nested response:
4391
+ value:
4392
+ categories:
4393
+ - id: 86
4394
+ name: Automobile
4395
+ description: Auto related categories
4396
+ is_income: false
4397
+ exclude_from_budget: false
4398
+ exclude_from_totals: false
4399
+ updated_at: "2025-02-28T09:49:03.238Z"
4400
+ created_at: "2025-01-28T09:49:03.238Z"
4401
+ is_group: true
4402
+ order: 2
4403
+ collapsed: false
4404
+ archived: false
4405
+ group_id: null
4406
+ archived_at: null
4407
+ children:
4408
+ - id: 315174
4409
+ name: Fuel
4410
+ description: Fuel and gas expenses
4411
+ is_income: false
4412
+ exclude_from_budget: false
4413
+ exclude_from_totals: false
4414
+ updated_at: "2025-02-28T09:49:03.238Z"
4415
+ created_at: "2025-01-28T09:49:03.238Z"
4416
+ is_group: false
4417
+ order: 1
4418
+ collapsed: false
4419
+ archived: false
4420
+ group_id: 86
4421
+ archived_at: null
4422
+ - id: 315175
4423
+ name: Maintenance
4424
+ description: Car maintenance and repairs
4425
+ is_income: false
4426
+ exclude_from_budget: false
4427
+ exclude_from_totals: false
4428
+ updated_at: "2025-02-28T09:49:03.238Z"
4429
+ created_at: "2025-01-28T09:49:03.238Z"
4430
+ is_group: false
4431
+ order: 2
4432
+ collapsed: false
4433
+ archived: false
4434
+ group_id: 86
4435
+ archived_at: null
4436
+ - id: 83
4437
+ name: Rent
4438
+ description: Monthly Rent
4439
+ is_income: false
4440
+ exclude_from_budget: false
4441
+ exclude_from_totals: false
4442
+ updated_at: "2025-02-28T09:49:03.225Z"
4443
+ created_at: "2025-01-28T09:49:03.225Z"
4444
+ is_group: false
4445
+ order: 0
4446
+ collapsed: false
4447
+ archived: false
4448
+ group_id: null
4449
+ archived_at: null
4450
+ - id: 88
4451
+ name: W2 Income
4452
+ description: null
4453
+ is_income: true
4454
+ exclude_from_budget: false
4455
+ exclude_from_totals: true
4456
+ updated_at: "2025-02-28T09:49:03.238Z"
4457
+ created_at: "2025-01-28T09:49:03.238Z"
4458
+ is_group: false
4459
+ order: 3
4460
+ collapsed: false
4461
+ archived: false
4462
+ group_id: null
4463
+ archived_at: null
4464
+ flattened response:
4465
+ value:
4466
+ categories:
4467
+ - id: 86
4468
+ name: Automobile
4469
+ description: Auto related categories
4470
+ is_income: false
4471
+ exclude_from_budget: false
4472
+ exclude_from_totals: false
4473
+ updated_at: "2025-02-28T09:49:03.238Z"
4474
+ created_at: "2025-01-28T09:49:03.238Z"
4475
+ is_group: true
4476
+ order: 1
4477
+ collapsed: false
4478
+ archived: false
4479
+ group_id: null
4480
+ archived_at: null
4481
+ children:
4482
+ - id: 315174
4483
+ name: Fuel
4484
+ description: Fuel and gas expenses
4485
+ is_income: false
4486
+ exclude_from_budget: false
4487
+ exclude_from_totals: false
4488
+ updated_at: "2025-02-28T09:49:03.238Z"
4489
+ created_at: "2025-01-28T09:49:03.238Z"
4490
+ is_group: false
4491
+ order: 1
4492
+ collapsed: false
4493
+ archived: false
4494
+ group_id: 86
4495
+ archived_at: null
4496
+ - id: 315175
4497
+ name: Maintenance
4498
+ description: Car maintenance and repairs
4499
+ is_income: false
4500
+ exclude_from_budget: false
4501
+ exclude_from_totals: false
4502
+ updated_at: "2025-02-28T09:49:03.238Z"
4503
+ created_at: "2025-01-28T09:49:03.238Z"
4504
+ is_group: false
4505
+ order: 2
4506
+ collapsed: false
4507
+ archived: false
4508
+ group_id: 86
4509
+ archived_at: null
4510
+ - id: 315174
4511
+ name: Fuel
4512
+ description: Fuel and gas expenses
4513
+ is_income: false
4514
+ exclude_from_budget: false
4515
+ exclude_from_totals: false
4516
+ updated_at: "2025-02-28T09:49:03.238Z"
4517
+ created_at: "2025-01-28T09:49:03.238Z"
4518
+ is_group: false
4519
+ order: 1
4520
+ collapsed: false
4521
+ archived: false
4522
+ group_id: 86
4523
+ archived_at: null
4524
+ - id: 315175
4525
+ name: Maintenance
4526
+ description: Car maintenance and repairs
4527
+ is_income: false
4528
+ exclude_from_budget: false
4529
+ exclude_from_totals: false
4530
+ updated_at: "2025-02-28T09:49:03.238Z"
4531
+ created_at: "2025-01-28T09:49:03.238Z"
4532
+ is_group: false
4533
+ order: 2
4534
+ collapsed: false
4535
+ archived: false
4536
+ group_id: 86
4537
+ archived_at: null
4538
+ - id: 83
4539
+ name: Rent
4540
+ description: Monthly Rent
4541
+ is_income: false
4542
+ exclude_from_budget: false
4543
+ exclude_from_totals: false
4544
+ updated_at: "2025-02-28T09:49:03.225Z"
4545
+ created_at: "2025-01-28T09:49:03.225Z"
4546
+ is_group: false
4547
+ order: 2
4548
+ collapsed: false
4549
+ archived: false
4550
+ group_id: null
4551
+ archived_at: null
4552
+ - id: 88
4553
+ name: W2 Income
4554
+ description: null
4555
+ is_income: true
4556
+ exclude_from_budget: false
4557
+ exclude_from_totals: true
4558
+ updated_at: "2025-02-28T09:49:03.238Z"
4559
+ created_at: "2025-01-28T09:49:03.238Z"
4560
+ is_group: false
4561
+ order: 3
4562
+ collapsed: false
4563
+ archived: false
4564
+ group_id: null
4565
+ archived_at: null
4566
+ "400":
4567
+ description: Invalid request parameters
4568
+ content:
4569
+ application/json:
4570
+ schema:
4571
+ $ref: "#/components/schemas/errorResponseObject"
4572
+ example:
4573
+ message: Request Validation Failure
4574
+ errors:
4575
+ - errMsg: must be equal to one of the allowed values
4576
+ instancePath: /query/format
4577
+ schemaPath: "#/properties/query/properties/format/enum"
4578
+ keyword: enum
4579
+ params:
4580
+ allowedValues:
4581
+ - flattened
4582
+ - nested
4583
+ "401":
4584
+ $ref: "#/components/responses/unauthorizedToken"
4585
+ "429":
4586
+ $ref: "#/components/responses/rateLimited"
4587
+ "500":
4588
+ $ref: "#/components/responses/serverError"
4589
+ post:
4590
+ tags:
4591
+ - categories
4592
+ summary: Create a new category or category group
4593
+ description: Creates a new category with the given name.<br> If the `is_group`
4594
+ attribute is set to true, a category group is created. In this case, the
4595
+ `children` attribute may be set to an array of existing category
4596
+ IDs to add to the newly-created category group.
4597
+ operationId: createCategory
4598
+ requestBody:
4599
+ required: true
4600
+ content:
4601
+ application/json:
4602
+ schema:
4603
+ $ref: "#/components/schemas/createCategoryRequestObject"
4604
+ examples:
4605
+ category:
4606
+ value:
4607
+ name: API Created Category
4608
+ description: Test description of created category
4609
+ is_income: false
4610
+ exclude_from_budget: true
4611
+ exclude_from_totals: false
4612
+ is_group: false
4613
+ category group:
4614
+ value:
4615
+ name: API Created Category Group
4616
+ description: Test description of Category Group
4617
+ is_income: false
4618
+ exclude_from_budget: false
4619
+ exclude_from_totals: false
4620
+ is_group: true
4621
+ children:
4622
+ - 83
4623
+ responses:
4624
+ "201":
4625
+ description: Category or Category Group Object with the successfully created
4626
+ category or category group.
4627
+ content:
4628
+ application/json:
4629
+ schema:
4630
+ $ref: "#/components/schemas/categoryObject"
4631
+ examples:
4632
+ category:
4633
+ value:
4634
+ id: 90
4635
+ name: API Created Category
4636
+ description: Test description of created category
4637
+ is_income: false
4638
+ exclude_from_budget: true
4639
+ exclude_from_totals: false
4640
+ updated_at: "2025-05-26T19:56:52.699Z"
4641
+ created_at: "2025-05-26T19:56:52.699Z"
4642
+ is_group: false
4643
+ group_id: null
4644
+ archived: false
4645
+ archived_at: null
4646
+ order: null
4647
+ collapsed: false
4648
+ category group:
3949
4649
  value:
3950
- aligned: true
3951
- categories:
3952
- - category_id: 315177
3953
- totals:
3954
- other_activity: 156.64
3955
- recurring_activity: 0
3956
- budgeted: 500
3957
- available: 343.36
3958
- recurring_remaining: 0
3959
- recurring_expected: 0
3960
- occurrences:
3961
- - in_range: true
3962
- start_date: "2025-07-01"
3963
- end_date: "2025-07-31"
3964
- other_activity: 156.64
3965
- recurring_activity: 0
3966
- budgeted: 500
3967
- budgeted_amount: "500.0000"
3968
- budgeted_currency: "usd"
3969
- notes: "Monthly budget allocation"
3970
- rollover_pool:
3971
- budgeted_to_base: 179.50
3972
- all_adjustments:
3973
- - in_range: false
3974
- date: "2025-06-30"
3975
- amount: "179.5000"
3976
- currency: "usd"
3977
- to_base: 179.50
3978
- - in_range: false
3979
- date: "2025-05-31"
3980
- amount: "120.2500"
3981
- currency: "usd"
3982
- to_base: 120.25
3983
- - in_range: false
3984
- date: "2025-04-30"
3985
- amount: "80.0000"
3986
- currency: "usd"
3987
- to_base: 80.00
4650
+ id: 91
4651
+ name: API Created Category Group
4652
+ description: Test description of Category Group
4653
+ is_income: false
4654
+ exclude_from_budget: false
4655
+ exclude_from_totals: false
4656
+ updated_at: "2025-05-27T19:59:45.053Z"
4657
+ created_at: "2025-05-27T19:59:45.053Z"
4658
+ is_group: true
4659
+ group_id: null
4660
+ archived: false
4661
+ archived_at: null
4662
+ order: null
4663
+ collapsed: false
4664
+ children:
4665
+ - id: 83
4666
+ name: Rent
4667
+ description: Monthly Rent
4668
+ is_income: false
4669
+ exclude_from_budget: false
4670
+ exclude_from_totals: false
4671
+ updated_at: "2025-02-28T09:49:03.225Z"
4672
+ created_at: "2025-01-28T09:49:03.225Z"
4673
+ is_group: false
4674
+ order: 1
4675
+ collapsed: false
4676
+ archived: false
4677
+ group_id: null
4678
+ archived_at: null
4679
+ "400":
4680
+ description: Bad Request
4681
+ content:
4682
+ application/json:
4683
+ schema:
4684
+ $ref: "#/components/schemas/errorResponseObject"
4685
+ example:
4686
+ message: Invalid Request Body
4687
+ errors:
4688
+ - errMsg: Cannot specify a 'group_id' in request body if 'is_group' is also true
3988
4689
  "401":
3989
4690
  $ref: "#/components/responses/unauthorizedToken"
3990
4691
  "429":
3991
4692
  $ref: "#/components/responses/rateLimited"
3992
4693
  "500":
3993
4694
  $ref: "#/components/responses/serverError"
3994
- /categories:
4695
+ /categories/{id}:
3995
4696
  get:
3996
4697
  tags:
3997
4698
  - categories
3998
- summary: Get all categories
3999
- description: Retrieve a list of all categories associated with the user's account.
4000
- operationId: getAllCategories
4699
+ summary: Get a single category
4700
+ description: Retrieve details of a specific category or category group by its ID.
4701
+ operationId: getCategoryById
4001
4702
  parameters:
4002
- - name: format
4003
- in: query
4004
- description: If `nested`, returns top-level categories (either category groups
4005
- or categories not part of a category group) in alphabetical order.
4006
- Grouped categories are nested within the category group under the
4007
- property `children`. A `flattened`, response is similar but it
4008
- includes grouped categories at the top level.<br/><br/> Categories
4009
- are sorted by their `order`. When `order` is null, they are listed in
4010
- alphabetical order below other categories with an `order`.
4011
- required: false
4012
- schema:
4013
- type: string
4014
- default: nested
4015
- enum:
4016
- - nested
4017
- - flattened
4018
- - name: is_group
4019
- in: query
4020
- description: If `false`, only categories not part of a category group
4021
- are returned.<br> If `true`, only category groups are
4022
- returned.<br> When set, the `format` parameter is ignored.
4023
- required: false
4703
+ - name: id
4704
+ in: path
4705
+ description: ID of the category to retrieve
4706
+ required: true
4024
4707
  schema:
4025
- type: boolean
4708
+ type: integer
4709
+ format: int32
4710
+ examples:
4711
+ category:
4712
+ summary: Example of a category's id
4713
+ value: 315174
4714
+ category group:
4715
+ summary: Example of a category group's id
4716
+ value: 86
4717
+ id not found:
4718
+ summary: Example of an id that doesn't exist
4719
+ value: 543210
4026
4720
  responses:
4027
- "200":
4028
- description: A list of Category Objects
4721
+ "201":
4722
+ description: Category Object with the requested category or category group.
4029
4723
  content:
4030
4724
  application/json:
4031
4725
  schema:
4032
- type: object
4033
- properties:
4034
- categories:
4035
- type: array
4036
- items:
4037
- $ref: "#/components/schemas/categoryObject"
4726
+ $ref: "#/components/schemas/categoryObject"
4038
4727
  examples:
4039
- nested response:
4728
+ category:
4040
4729
  value:
4041
- categories:
4042
- - id: 86
4043
- name: Automobile
4044
- description: Auto related categories
4730
+ id: 315174
4731
+ name: Fuel
4732
+ description: Fuel and gas expenses
4733
+ is_income: false
4734
+ exclude_from_budget: false
4735
+ exclude_from_totals: false
4736
+ updated_at: "2025-02-28T09:49:03.238Z"
4737
+ created_at: "2025-01-28T09:49:03.238Z"
4738
+ group_id: 86
4739
+ is_group: false
4740
+ archived: false
4741
+ archived_at: null
4742
+ order: 1
4743
+ collapsed: false
4744
+ category group:
4745
+ value:
4746
+ id: 86
4747
+ name: Automobile
4748
+ description: Auto related categories
4749
+ is_income: false
4750
+ exclude_from_budget: false
4751
+ exclude_from_totals: false
4752
+ updated_at: "2025-02-28T09:49:03.238Z"
4753
+ created_at: "2025-01-28T09:49:03.238Z"
4754
+ is_group: true
4755
+ order: 2
4756
+ collapsed: false
4757
+ archived: false
4758
+ group_id: null
4759
+ archived_at: null
4760
+ children:
4761
+ - id: 315174
4762
+ name: Fuel
4763
+ description: Fuel and gas expenses
4045
4764
  is_income: false
4046
4765
  exclude_from_budget: false
4047
4766
  exclude_from_totals: false
4048
4767
  updated_at: "2025-02-28T09:49:03.238Z"
4049
4768
  created_at: "2025-01-28T09:49:03.238Z"
4050
- is_group: true
4051
- order: 2
4052
- collapsed: false
4769
+ group_id: 86
4770
+ is_group: false
4053
4771
  archived: false
4054
- group_id: null
4055
4772
  archived_at: null
4056
- children:
4057
- - id: 315174
4058
- name: Fuel
4059
- description: Fuel and gas expenses
4060
- is_income: false
4061
- exclude_from_budget: false
4062
- exclude_from_totals: false
4063
- updated_at: "2025-02-28T09:49:03.238Z"
4064
- created_at: "2025-01-28T09:49:03.238Z"
4065
- is_group: false
4066
- order: 1
4067
- collapsed: false
4068
- archived: false
4069
- group_id: 86
4070
- archived_at: null
4071
- - id: 315175
4072
- name: Maintenance
4073
- description: Car maintenance and repairs
4074
- is_income: false
4075
- exclude_from_budget: false
4076
- exclude_from_totals: false
4077
- updated_at: "2025-02-28T09:49:03.238Z"
4078
- created_at: "2025-01-28T09:49:03.238Z"
4079
- is_group: false
4080
- order: 2
4081
- collapsed: false
4082
- archived: false
4083
- group_id: 86
4084
- archived_at: null
4085
- - id: 83
4086
- name: Rent
4087
- description: Monthly Rent
4773
+ order: 1
4774
+ collapsed: false
4775
+ - id: 315175
4776
+ name: Maintenance
4777
+ description: Car maintenance and repairs
4088
4778
  is_income: false
4089
4779
  exclude_from_budget: false
4090
4780
  exclude_from_totals: false
4091
- updated_at: "2025-02-28T09:49:03.225Z"
4092
- created_at: "2025-01-28T09:49:03.225Z"
4093
- is_group: false
4094
- order: 0
4095
- collapsed: false
4096
- archived: false
4097
- group_id: null
4098
- archived_at: null
4099
- - id: 88
4100
- name: W2 Income
4101
- description: null
4102
- is_income: true
4103
- exclude_from_budget: false
4104
- exclude_from_totals: true
4105
4781
  updated_at: "2025-02-28T09:49:03.238Z"
4106
4782
  created_at: "2025-01-28T09:49:03.238Z"
4783
+ group_id: 86
4107
4784
  is_group: false
4108
- order: 3
4109
- collapsed: false
4110
4785
  archived: false
4111
- group_id: null
4112
4786
  archived_at: null
4113
- flattened response:
4787
+ order: 2
4788
+ collapsed: false
4789
+ "400":
4790
+ description: Bad Request
4791
+ content:
4792
+ application/json:
4793
+ schema:
4794
+ $ref: "#/components/schemas/errorResponseObject"
4795
+ example:
4796
+ message: Request Validation Failure
4797
+ errors:
4798
+ - errMsg: must be a valid integer
4799
+ instancePath: /query/ids/0
4800
+ schemaPath: "#/properties/query/properties/ids/items/type"
4801
+ keyword: type
4802
+ params:
4803
+ type: integer
4804
+ "401":
4805
+ $ref: "#/components/responses/unauthorizedToken"
4806
+ "404":
4807
+ description: Not Found
4808
+ content:
4809
+ application/json:
4810
+ schema:
4811
+ $ref: "#/components/schemas/errorResponseObject"
4812
+ example:
4813
+ message: Not Found
4814
+ errors:
4815
+ - errMsg: "There is no category with the id: 543210."
4816
+ "429":
4817
+ $ref: "#/components/responses/rateLimited"
4818
+ "500":
4819
+ $ref: "#/components/responses/serverError"
4820
+ put:
4821
+ tags:
4822
+ - categories
4823
+ summary: Update an existing category or category group
4824
+ description: >-
4825
+ Modifies the properties of an existing category or category group.<br><br>
4826
+
4827
+ You may submit the response from a `GET /categories/{id}` as the request body; however, only certain
4828
+ properties can be updated using this API. The following properties are
4829
+ accepted in the request body but their values will be ignored: `id`, `is_group`,`archived_at`, `updated_at`, `created_at`, and `order`.<br><br>
4830
+
4831
+ It is also possible to provide only the properties to be updated in the
4832
+ request body, as long as the request includes at least one of the
4833
+ properties that is not listed above. For example, a request body that contains only a `name` property is valid.<br><br>
4834
+
4835
+ It is not possible to use this API to convert a category to a category group, or a vice versa, so while submitting a request body with the `is_group` property is tolerated, it will result in an error response if the value is changed.<br><br>
4836
+
4837
+ It is possible to modify the children of an existing category group with this API by setting the `children` attribute. If this is set, it will replace the existing children with the newly specified children. If the intention is to add or remove a single category, it is more straightforward to update the child category by specifying the new `group_id` attribute. If the goal is to add multiple new children or remove multiple existing children, it is recommended to first call the `GET /categories/:id` endpoint to get the existing children and then modify the list as desired.<br><br>
4838
+ operationId: updateCategory
4839
+ parameters:
4840
+ - name: id
4841
+ in: path
4842
+ description: ID of the category to update
4843
+ required: true
4844
+ schema:
4845
+ type: integer
4846
+ format: int32
4847
+ examples:
4848
+ category:
4849
+ summary: Example of a category's id
4850
+ value: 83
4851
+ category group:
4852
+ summary: Example of a category group's id
4853
+ value: 86
4854
+ child category:
4855
+ summary: Example of a category belonging to a group
4856
+ value: 315164
4857
+ not found:
4858
+ summary: Example of a category id that does not exist
4859
+ value: 543210
4860
+ requestBody:
4861
+ required: true
4862
+ content:
4863
+ application/json:
4864
+ schema:
4865
+ $ref: "#/components/schemas/updateCategoryRequestObject"
4866
+ examples:
4867
+ Update some category properties:
4868
+ value:
4869
+ name: Updated Category Name
4870
+ description: Updated description of the category
4871
+ Update same properties with full object:
4872
+ value:
4873
+ id: 83
4874
+ name: Updated Category Name
4875
+ description: Updated description of the category
4876
+ is_income: false
4877
+ exclude_from_budget: true
4878
+ exclude_from_totals: false
4879
+ updated_at: "2020-01-28T09:49:03.225Z"
4880
+ created_at: "2020-01-28T09:49:03.225Z"
4881
+ is_group: false
4882
+ group_id: null
4883
+ archived: false
4884
+ archived_at: null
4885
+ order: 0
4886
+ Invalid attempt to convert to category group:
4887
+ value:
4888
+ id: 83
4889
+ name: Old Category is now a group!
4890
+ is_group: true
4891
+ Remove category from a group:
4892
+ value:
4893
+ id: 86
4894
+ name: Automobile
4895
+ description: API Removed a sub category
4896
+ children:
4897
+ - 315174
4898
+ responses:
4899
+ "200":
4900
+ description: Category or Category Group updated successfully
4901
+ content:
4902
+ application/json:
4903
+ schema:
4904
+ $ref: "#/components/schemas/categoryObject"
4905
+ examples:
4906
+ category:
4907
+ value:
4908
+ id: 83
4909
+ name: Updated Category Name
4910
+ description: Updated description of the category
4911
+ is_income: false
4912
+ exclude_from_budget: false
4913
+ exclude_from_totals: true
4914
+ updated_at: "2025-05-26T20:41:18.406Z"
4915
+ created_at: "2025-01-28T09:49:03.225Z"
4916
+ is_group: false
4917
+ order: 0
4918
+ collapsed: false
4919
+ archived: false
4920
+ archived_at: null
4921
+ group_id: null
4922
+ category group:
4114
4923
  value:
4115
- categories:
4116
- - id: 86
4117
- name: Automobile
4118
- description: Auto related categories
4119
- is_income: false
4120
- exclude_from_budget: false
4121
- exclude_from_totals: false
4122
- updated_at: "2025-02-28T09:49:03.238Z"
4123
- created_at: "2025-01-28T09:49:03.238Z"
4124
- is_group: true
4125
- order: 1
4126
- collapsed: false
4127
- archived: false
4128
- group_id: null
4129
- archived_at: null
4130
- children:
4131
- - id: 315174
4132
- name: Fuel
4133
- description: Fuel and gas expenses
4134
- is_income: false
4135
- exclude_from_budget: false
4136
- exclude_from_totals: false
4137
- updated_at: "2025-02-28T09:49:03.238Z"
4138
- created_at: "2025-01-28T09:49:03.238Z"
4139
- is_group: false
4140
- order: 1
4141
- collapsed: false
4142
- archived: false
4143
- group_id: 86
4144
- archived_at: null
4145
- - id: 315175
4146
- name: Maintenance
4147
- description: Car maintenance and repairs
4148
- is_income: false
4149
- exclude_from_budget: false
4150
- exclude_from_totals: false
4151
- updated_at: "2025-02-28T09:49:03.238Z"
4152
- created_at: "2025-01-28T09:49:03.238Z"
4153
- is_group: false
4154
- order: 2
4155
- collapsed: false
4156
- archived: false
4157
- group_id: 86
4158
- archived_at: null
4924
+ id: 86
4925
+ name: Automobile
4926
+ description: API Removed a sub category
4927
+ is_income: false
4928
+ exclude_from_budget: false
4929
+ exclude_from_totals: false
4930
+ updated_at: "2025-06-22T19:54:30.921Z"
4931
+ created_at: "2025-01-28T09:49:03.238Z"
4932
+ is_group: true
4933
+ order: 2
4934
+ collapsed: false
4935
+ archived: false
4936
+ group_id: null
4937
+ archived_at: null
4938
+ children:
4159
4939
  - id: 315174
4160
4940
  name: Fuel
4161
4941
  description: Fuel and gas expenses
@@ -4164,71 +4944,248 @@ paths:
4164
4944
  exclude_from_totals: false
4165
4945
  updated_at: "2025-02-28T09:49:03.238Z"
4166
4946
  created_at: "2025-01-28T09:49:03.238Z"
4167
- is_group: false
4168
- order: 1
4169
- collapsed: false
4170
- archived: false
4171
- group_id: 86
4172
- archived_at: null
4173
- - id: 315175
4174
- name: Maintenance
4175
- description: Car maintenance and repairs
4176
- is_income: false
4177
- exclude_from_budget: false
4178
- exclude_from_totals: false
4179
- updated_at: "2025-02-28T09:49:03.238Z"
4180
- created_at: "2025-01-28T09:49:03.238Z"
4181
- is_group: false
4182
- order: 2
4183
- collapsed: false
4184
- archived: false
4185
4947
  group_id: 86
4186
- archived_at: null
4187
- - id: 83
4188
- name: Rent
4189
- description: Monthly Rent
4190
- is_income: false
4191
- exclude_from_budget: false
4192
- exclude_from_totals: false
4193
- updated_at: "2025-02-28T09:49:03.225Z"
4194
- created_at: "2025-01-28T09:49:03.225Z"
4195
4948
  is_group: false
4196
- order: 2
4197
- collapsed: false
4198
4949
  archived: false
4199
- group_id: null
4200
4950
  archived_at: null
4201
- - id: 88
4202
- name: W2 Income
4203
- description: null
4204
- is_income: true
4205
- exclude_from_budget: false
4206
- exclude_from_totals: true
4207
- updated_at: "2025-02-28T09:49:03.238Z"
4208
- created_at: "2025-01-28T09:49:03.238Z"
4209
- is_group: false
4210
- order: 3
4951
+ order: 1
4211
4952
  collapsed: false
4212
- archived: false
4213
- group_id: null
4214
- archived_at: null
4215
4953
  "400":
4216
- description: Invalid request parameters
4954
+ description: Bad Request
4217
4955
  content:
4218
4956
  application/json:
4219
4957
  schema:
4220
4958
  $ref: "#/components/schemas/errorResponseObject"
4221
4959
  example:
4222
- message: Request Validation Failure
4960
+ message: Invalid Request Body
4223
4961
  errors:
4224
- - errMsg: must be equal to one of the allowed values
4225
- instancePath: /query/format
4226
- schemaPath: "#/properties/query/properties/format/enum"
4227
- keyword: enum
4228
- params:
4229
- allowedValues:
4230
- - flattened
4231
- - nested
4962
+ - errMsg: Cannot modify the 'group_id' property of an existing category or
4963
+ category group
4964
+ "401":
4965
+ $ref: "#/components/responses/unauthorizedToken"
4966
+ "404":
4967
+ description: Not Found
4968
+ content:
4969
+ application/json:
4970
+ schema:
4971
+ $ref: "#/components/schemas/errorResponseObject"
4972
+ example:
4973
+ message: Not Found
4974
+ errors:
4975
+ - errMsg: "There is no category with the id: 543210."
4976
+ "429":
4977
+ $ref: "#/components/responses/rateLimited"
4978
+ "500":
4979
+ $ref: "#/components/responses/serverError"
4980
+ delete:
4981
+ tags:
4982
+ - categories
4983
+ summary: Delete a category or category group
4984
+ description: Attempts to delete the single category or category group specified
4985
+ on the path. By default, this will only work if there are no dependencies,
4986
+ such as existing budgets for the category, categorized transactions,
4987
+ children categories for a category group, categorized recurring items,
4988
+ etc. If there are dependents, this endpoint will return an object that
4989
+ describes the amount and type of existing dependencies.
4990
+ operationId: deleteCategory
4991
+ parameters:
4992
+ - in: path
4993
+ name: id
4994
+ description: ID of the category to delete
4995
+ required: true
4996
+ schema:
4997
+ type: integer
4998
+ format: int32
4999
+ examples:
5000
+ delete category:
5001
+ summary: Simple category delete
5002
+ value: 83
5003
+ delete category group:
5004
+ summary: Attempt to delete category with dependencies
5005
+ value: 84
5006
+ id not found:
5007
+ summary: Example of an id that doesn't exist
5008
+ value: 543210
5009
+ - in: query
5010
+ name: force
5011
+ description: Set to `true` to force deletion even if there are dependencies
5012
+ required: false
5013
+ schema:
5014
+ type: boolean
5015
+ default: false
5016
+ responses:
5017
+ "204":
5018
+ description: No Content
5019
+ "401":
5020
+ $ref: "#/components/responses/unauthorizedToken"
5021
+ "404":
5022
+ description: Not Found
5023
+ content:
5024
+ application/json:
5025
+ schema:
5026
+ $ref: "#/components/schemas/errorResponseObject"
5027
+ example:
5028
+ message: Not Found
5029
+ errors:
5030
+ - errMsg: "There is no category with the id: 543210."
5031
+ "422":
5032
+ description: Unprocessable Content
5033
+ content:
5034
+ application/json:
5035
+ schema:
5036
+ $ref: "#/components/schemas/deleteCategoryResponseWithDependencies"
5037
+ examples:
5038
+ delete category with dependencies:
5039
+ summary: Response to an attempt to delete category with dependencies
5040
+ value:
5041
+ category_name: Category to be Deleted
5042
+ dependents:
5043
+ budget: 0
5044
+ category_rules: 1
5045
+ transactions: 10
5046
+ children: 0
5047
+ recurring: 0
5048
+ plaid_cats: 0
5049
+ delete category group:
5050
+ summary: Response to attempt to delete a category group with children
5051
+ value:
5052
+ category_name: Category Group to be Deleted
5053
+ dependents:
5054
+ budget: 0
5055
+ category_rules: 0
5056
+ transactions: 0
5057
+ children: 3
5058
+ recurring: 0
5059
+ plaid_cats: 0
5060
+ "429":
5061
+ $ref: "#/components/responses/rateLimited"
5062
+ "500":
5063
+ $ref: "#/components/responses/serverError"
5064
+ /crypto:
5065
+ get:
5066
+ tags:
5067
+ - crypto
5068
+ summary: Get all crypto balances
5069
+ description: Retrieve all crypto balances associated with the user's account, including both manual and synced sources.
5070
+ operationId: getAllCrypto
5071
+ responses:
5072
+ "200":
5073
+ description: A list of crypto balances
5074
+ content:
5075
+ application/json:
5076
+ schema:
5077
+ $ref: "#/components/schemas/cryptoListResponseObject"
5078
+ example:
5079
+ crypto:
5080
+ - id: 22001
5081
+ source: manual
5082
+ name: Cold Wallet BTC
5083
+ display_name: Long-term BTC
5084
+ institution_name: Ledger
5085
+ balance: "0.852341920145782301"
5086
+ currency: btc
5087
+ coingecko_id: bitcoin
5088
+ to_base: 53124.72
5089
+ balance_as_of: "2026-02-25T14:22:10.000Z"
5090
+ last_import: null
5091
+ created_by_name: User 1
5092
+ created_at: "2025-11-12T20:14:32.000Z"
5093
+ updated_at: "2026-02-25T14:22:10.000Z"
5094
+ - id: 33004
5095
+ source: synced
5096
+ name: ETH
5097
+ display_name: Coinbase Main
5098
+ institution_name: Coinbase
5099
+ balance: "12.004500000000000000"
5100
+ currency: eth
5101
+ coingecko_id: ethereum
5102
+ to_base: 28998.44
5103
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5104
+ last_import: "2026-02-25T14:25:01.000Z"
5105
+ account_status: active
5106
+ created_by_name: User 1
5107
+ created_at: "2025-10-02T11:02:09.000Z"
5108
+ updated_at: "2026-02-25T14:25:01.000Z"
5109
+ "401":
5110
+ $ref: "#/components/responses/unauthorizedToken"
5111
+ "429":
5112
+ $ref: "#/components/responses/rateLimited"
5113
+ "500":
5114
+ $ref: "#/components/responses/serverError"
5115
+
5116
+ /cryptocurrencies:
5117
+ get:
5118
+ tags:
5119
+ - crypto
5120
+ summary: Get all supported cryptocurrencies
5121
+ description: >
5122
+ Retrieve the list of cryptocurrencies currently supported for manual tracking.<p>
5123
+
5124
+ When creating a new manual crypto balance via `POST /crypto/manual`, the
5125
+ `currency` you specify must match the `currency` of one of the entries
5126
+ returned by this endpoint.
5127
+ operationId: getAllCryptocurrencies
5128
+ responses:
5129
+ "200":
5130
+ description: A list of supported cryptocurrencies
5131
+ content:
5132
+ application/json:
5133
+ schema:
5134
+ $ref: "#/components/schemas/cryptoCurrencyResponseObject"
5135
+ example:
5136
+ cryptocurrencies:
5137
+ - id: 1
5138
+ coingecko_id: bitcoin
5139
+ currency: btc
5140
+ full_name: Bitcoin
5141
+ - id: 2
5142
+ coingecko_id: ethereum
5143
+ currency: eth
5144
+ full_name: Ethereum
5145
+ - id: 3
5146
+ coingecko_id: solana
5147
+ currency: sol
5148
+ full_name: Solana
5149
+ - id: 4
5150
+ coingecko_id: ripple
5151
+ currency: xrp
5152
+ full_name: XRP
5153
+ "401":
5154
+ $ref: "#/components/responses/unauthorizedToken"
5155
+ "429":
5156
+ $ref: "#/components/responses/rateLimited"
5157
+ "500":
5158
+ $ref: "#/components/responses/serverError"
5159
+ /crypto/manual:
5160
+ get:
5161
+ tags:
5162
+ - crypto
5163
+ summary: Get all manual crypto balances
5164
+ description: Retrieve all manually managed crypto balances associated with the user's account.
5165
+ operationId: getAllCryptoManual
5166
+ responses:
5167
+ "200":
5168
+ description: A list of manual crypto balances
5169
+ content:
5170
+ application/json:
5171
+ schema:
5172
+ $ref: "#/components/schemas/cryptoManualListResponseObject"
5173
+ example:
5174
+ crypto_manual:
5175
+ - id: 22001
5176
+ source: manual
5177
+ name: Cold Wallet BTC
5178
+ display_name: Long-term BTC
5179
+ institution_name: Ledger
5180
+ balance: "0.852341920145782301"
5181
+ currency: btc
5182
+ coingecko_id: bitcoin
5183
+ to_base: 53124.72
5184
+ balance_as_of: "2026-02-25T14:22:10.000Z"
5185
+ last_import: null
5186
+ created_by_name: User 1
5187
+ created_at: "2025-11-12T20:14:32.000Z"
5188
+ updated_at: "2026-02-25T14:22:10.000Z"
4232
5189
  "401":
4233
5190
  $ref: "#/components/responses/unauthorizedToken"
4234
5191
  "429":
@@ -4237,94 +5194,117 @@ paths:
4237
5194
  $ref: "#/components/responses/serverError"
4238
5195
  post:
4239
5196
  tags:
4240
- - categories
4241
- summary: Create a new category or category group
4242
- description: Creates a new category with the given name.<br> If the `is_group`
4243
- attribute is set to true, a category group is created. In this case, the
4244
- `children` attribute may be set to an array of existing category
4245
- IDs to add to the newly-created category group.
4246
- operationId: createCategory
5197
+ - crypto
5198
+ summary: Create a manual crypto balance
5199
+ description: Create a manually managed crypto asset.
5200
+ operationId: createCryptoManual
4247
5201
  requestBody:
4248
5202
  required: true
4249
5203
  content:
4250
5204
  application/json:
4251
5205
  schema:
4252
- $ref: "#/components/schemas/createCategoryRequestObject"
5206
+ $ref: "#/components/schemas/createCryptoManualRequestObject"
4253
5207
  examples:
4254
- category:
5208
+ minimum request body:
5209
+ summary: Minimum required fields
4255
5210
  value:
4256
- name: API Created Category
4257
- description: Test description of created category
4258
- is_income: false
4259
- exclude_from_budget: true
4260
- exclude_from_totals: false
4261
- is_group: false
4262
- category group:
5211
+ name: Cold Wallet BTC
5212
+ balance: "0.852341920145782301"
5213
+ currency: btc
5214
+ full request body:
5215
+ summary: Full example with optional display fields
4263
5216
  value:
4264
- name: API Created Category Group
4265
- description: Test description of Category Group
4266
- is_income: false
4267
- exclude_from_budget: false
4268
- exclude_from_totals: false
4269
- is_group: true
4270
- children:
4271
- - 83
5217
+ name: Coinbase ETH Holdings
5218
+ display_name: Trading ETH
5219
+ institution_name: Coinbase
5220
+ balance: "12.004500000000000000"
5221
+ currency: eth
4272
5222
  responses:
4273
5223
  "201":
4274
- description: Category or Category Group Object with the successfully created
4275
- category or category group.
5224
+ description: Manual crypto balance created successfully
4276
5225
  content:
4277
5226
  application/json:
4278
5227
  schema:
4279
- $ref: "#/components/schemas/categoryObject"
5228
+ $ref: "#/components/schemas/cryptoManualObject"
5229
+ example:
5230
+ id: 22045
5231
+ source: manual
5232
+ name: Coinbase ETH Holdings
5233
+ display_name: Trading ETH
5234
+ institution_name: Coinbase
5235
+ balance: "12.004500000000000000"
5236
+ currency: eth
5237
+ coingecko_id: ethereum
5238
+ to_base: 28998.44
5239
+ balance_as_of: "2026-03-01T09:20:41.000Z"
5240
+ last_import: null
5241
+ created_by_name: User 1
5242
+ created_at: "2026-03-01T09:20:41.000Z"
5243
+ updated_at: "2026-03-01T09:20:41.000Z"
5244
+ "400":
5245
+ description: Invalid request body
5246
+ content:
5247
+ application/json:
5248
+ schema:
5249
+ $ref: "#/components/schemas/errorResponseObject"
4280
5250
  examples:
4281
- category:
4282
- value:
4283
- id: 90
4284
- name: API Created Category
4285
- description: Test description of created category
4286
- is_income: false
4287
- exclude_from_budget: true
4288
- exclude_from_totals: false
4289
- updated_at: "2025-05-26T19:56:52.699Z"
4290
- created_at: "2025-05-26T19:56:52.699Z"
4291
- is_group: false
4292
- group_id: null
4293
- archived: false
4294
- archived_at: null
4295
- order: null
4296
- collapsed: false
4297
- category group:
5251
+ missing required properties:
4298
5252
  value:
4299
- id: 91
4300
- name: API Created Category Group
4301
- description: Test description of Category Group
4302
- is_income: false
4303
- exclude_from_budget: false
4304
- exclude_from_totals: false
4305
- updated_at: "2025-05-27T19:59:45.053Z"
4306
- created_at: "2025-05-27T19:59:45.053Z"
4307
- is_group: true
4308
- group_id: null
4309
- archived: false
4310
- archived_at: null
4311
- order: null
4312
- collapsed: false
4313
- children:
4314
- - id: 83
4315
- name: Rent
4316
- description: Monthly Rent
4317
- is_income: false
4318
- exclude_from_budget: false
4319
- exclude_from_totals: false
4320
- updated_at: "2025-02-28T09:49:03.225Z"
4321
- created_at: "2025-01-28T09:49:03.225Z"
4322
- is_group: false
4323
- order: 1
4324
- collapsed: false
4325
- archived: false
4326
- group_id: null
4327
- archived_at: null
5253
+ message: Request Validation Failure
5254
+ errors:
5255
+ - errMsg: "Missing required property 'name' in request body."
5256
+ - errMsg: "Missing required property 'balance' in request body."
5257
+ - errMsg: "Missing required property 'currency' in request body."
5258
+ "401":
5259
+ $ref: "#/components/responses/unauthorizedToken"
5260
+ "429":
5261
+ $ref: "#/components/responses/rateLimited"
5262
+ "500":
5263
+ $ref: "#/components/responses/serverError"
5264
+ /crypto/manual/{id}:
5265
+ get:
5266
+ tags:
5267
+ - crypto
5268
+ summary: Get a single manual crypto balance
5269
+ description: Retrieve a single manually managed crypto balance by ID.
5270
+ operationId: getCryptoManualById
5271
+ parameters:
5272
+ - name: id
5273
+ in: path
5274
+ description: ID of the manual crypto balance to retrieve
5275
+ required: true
5276
+ schema:
5277
+ type: integer
5278
+ format: int32
5279
+ examples:
5280
+ existing manual crypto:
5281
+ summary: Existing manual crypto ID
5282
+ value: 22001
5283
+ id not found:
5284
+ summary: Example of an id that doesn't exist
5285
+ value: 99999999
5286
+ responses:
5287
+ "200":
5288
+ description: Manual crypto balance object
5289
+ content:
5290
+ application/json:
5291
+ schema:
5292
+ $ref: "#/components/schemas/cryptoManualObject"
5293
+ example:
5294
+ id: 22001
5295
+ source: manual
5296
+ name: Cold Wallet BTC
5297
+ display_name: Long-term BTC
5298
+ institution_name: Ledger
5299
+ balance: "0.852341920145782301"
5300
+ currency: btc
5301
+ coingecko_id: bitcoin
5302
+ to_base: 53124.72
5303
+ balance_as_of: "2026-02-25T14:22:10.000Z"
5304
+ last_import: null
5305
+ created_by_name: User 1
5306
+ created_at: "2025-11-12T20:14:32.000Z"
5307
+ updated_at: "2026-02-25T14:22:10.000Z"
4328
5308
  "400":
4329
5309
  description: Bad Request
4330
5310
  content:
@@ -4332,273 +5312,289 @@ paths:
4332
5312
  schema:
4333
5313
  $ref: "#/components/schemas/errorResponseObject"
4334
5314
  example:
4335
- message: Invalid Request Body
5315
+ message: Invalid Path Parameters
4336
5316
  errors:
4337
- - errMsg: Cannot specify a 'group_id' in request body if 'is_group' is also true
5317
+ - errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'."
4338
5318
  "401":
4339
5319
  $ref: "#/components/responses/unauthorizedToken"
5320
+ "404":
5321
+ description: Not Found
5322
+ content:
5323
+ application/json:
5324
+ schema:
5325
+ $ref: "#/components/schemas/errorResponseObject"
5326
+ example:
5327
+ message: Not Found
5328
+ errors:
5329
+ - errMsg: "There is no manual crypto balance with the id: 99999999."
4340
5330
  "429":
4341
5331
  $ref: "#/components/responses/rateLimited"
4342
5332
  "500":
4343
5333
  $ref: "#/components/responses/serverError"
4344
- /categories/{id}:
4345
- get:
5334
+ put:
4346
5335
  tags:
4347
- - categories
4348
- summary: Get a single category
4349
- description: Retrieve details of a specific category or category group by its ID.
4350
- operationId: getCategoryById
5336
+ - crypto
5337
+ summary: Update a manual crypto balance
5338
+ description: >-
5339
+ Modify a manually managed crypto balance.<br><br>
5340
+
5341
+ You may submit the response from `GET /crypto/manual/{id}` as the request body. System-defined properties
5342
+ are accepted and ignored according to the `x-updatable` metadata in the update schema.
5343
+ operationId: updateCryptoManual
4351
5344
  parameters:
4352
5345
  - name: id
4353
5346
  in: path
4354
- description: ID of the category to retrieve
5347
+ description: ID of the manual crypto balance to update
4355
5348
  required: true
4356
5349
  schema:
4357
5350
  type: integer
4358
5351
  format: int32
4359
5352
  examples:
4360
- category:
4361
- summary: Example of a category's id
4362
- value: 315174
4363
- category group:
4364
- summary: Example of a category group's id
4365
- value: 86
5353
+ existing manual crypto:
5354
+ summary: Existing manual crypto ID
5355
+ value: 22001
4366
5356
  id not found:
4367
5357
  summary: Example of an id that doesn't exist
4368
- value: 543210
5358
+ value: 99999999
5359
+ requestBody:
5360
+ required: true
5361
+ content:
5362
+ application/json:
5363
+ schema:
5364
+ $ref: "#/components/schemas/updateCryptoManualRequestObject"
5365
+ examples:
5366
+ minimum request body:
5367
+ summary: Update balance only
5368
+ value:
5369
+ balance: "0.900000000000000000"
5370
+ full get response body:
5371
+ summary: Full object payload with system fields tolerated
5372
+ value:
5373
+ id: 22001
5374
+ source: manual
5375
+ name: Cold Wallet BTC
5376
+ display_name: Long-term BTC
5377
+ institution_name: Ledger
5378
+ balance: "0.900000000000000000"
5379
+ currency: btc
5380
+ coingecko_id: bitcoin
5381
+ to_base: 56011.12
5382
+ balance_as_of: "2026-03-01T09:41:18.000Z"
5383
+ last_import: null
5384
+ created_by_name: User 1
5385
+ created_at: "2025-11-12T20:14:32.000Z"
5386
+ updated_at: "2026-02-25T14:22:10.000Z"
4369
5387
  responses:
4370
- "201":
4371
- description: Category Object with the requested category or category group.
5388
+ "200":
5389
+ description: Manual crypto balance updated successfully
4372
5390
  content:
4373
5391
  application/json:
4374
5392
  schema:
4375
- $ref: "#/components/schemas/categoryObject"
4376
- examples:
4377
- category:
4378
- value:
4379
- id: 315174
4380
- name: Fuel
4381
- description: Fuel and gas expenses
4382
- is_income: false
4383
- exclude_from_budget: false
4384
- exclude_from_totals: false
4385
- updated_at: "2025-02-28T09:49:03.238Z"
4386
- created_at: "2025-01-28T09:49:03.238Z"
4387
- group_id: 86
4388
- is_group: false
4389
- archived: false
4390
- archived_at: null
4391
- order: 1
4392
- collapsed: false
4393
- category group:
4394
- value:
4395
- id: 86
4396
- name: Automobile
4397
- description: Auto related categories
4398
- is_income: false
4399
- exclude_from_budget: false
4400
- exclude_from_totals: false
4401
- updated_at: "2025-02-28T09:49:03.238Z"
4402
- created_at: "2025-01-28T09:49:03.238Z"
4403
- is_group: true
4404
- order: 2
4405
- collapsed: false
4406
- archived: false
4407
- group_id: null
4408
- archived_at: null
4409
- children:
4410
- - id: 315174
4411
- name: Fuel
4412
- description: Fuel and gas expenses
4413
- is_income: false
4414
- exclude_from_budget: false
4415
- exclude_from_totals: false
4416
- updated_at: "2025-02-28T09:49:03.238Z"
4417
- created_at: "2025-01-28T09:49:03.238Z"
4418
- group_id: 86
4419
- is_group: false
4420
- archived: false
4421
- archived_at: null
4422
- order: 1
4423
- collapsed: false
4424
- - id: 315175
4425
- name: Maintenance
4426
- description: Car maintenance and repairs
4427
- is_income: false
4428
- exclude_from_budget: false
4429
- exclude_from_totals: false
4430
- updated_at: "2025-02-28T09:49:03.238Z"
4431
- created_at: "2025-01-28T09:49:03.238Z"
4432
- group_id: 86
4433
- is_group: false
4434
- archived: false
4435
- archived_at: null
4436
- order: 2
4437
- collapsed: false
5393
+ $ref: "#/components/schemas/cryptoManualObject"
5394
+ example:
5395
+ id: 22001
5396
+ source: manual
5397
+ name: Cold Wallet BTC
5398
+ display_name: Long-term BTC
5399
+ institution_name: Ledger
5400
+ balance: "0.900000000000000000"
5401
+ currency: btc
5402
+ coingecko_id: bitcoin
5403
+ to_base: 56011.12
5404
+ balance_as_of: "2026-03-01T09:41:18.000Z"
5405
+ last_import: null
5406
+ created_by_name: User 1
5407
+ created_at: "2025-11-12T20:14:32.000Z"
5408
+ updated_at: "2026-03-01T09:41:18.000Z"
4438
5409
  "400":
4439
5410
  description: Bad Request
5411
+ content:
5412
+ application/json:
5413
+ schema:
5414
+ $ref: "#/components/schemas/errorResponseObject"
5415
+ examples:
5416
+ missing updatable properties:
5417
+ value:
5418
+ message: Invalid Request Body
5419
+ errors:
5420
+ - errMsg: "A request to update a manual crypto balance must include at least one updatable property: name, display_name, institution_name, balance"
5421
+ "401":
5422
+ $ref: "#/components/responses/unauthorizedToken"
5423
+ "404":
5424
+ description: Not Found
5425
+ content:
5426
+ application/json:
5427
+ schema:
5428
+ $ref: "#/components/schemas/errorResponseObject"
5429
+ example:
5430
+ message: Not Found
5431
+ errors:
5432
+ - errMsg: "There is no manual crypto balance with the id: 99999999."
5433
+ "429":
5434
+ $ref: "#/components/responses/rateLimited"
5435
+ "500":
5436
+ $ref: "#/components/responses/serverError"
5437
+ delete:
5438
+ tags:
5439
+ - crypto
5440
+ summary: Delete a manual crypto balance
5441
+ description: Delete a single manually managed crypto asset by ID.<p>
5442
+ 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`.
5443
+ operationId: deleteCryptoManual
5444
+ parameters:
5445
+ - name: id
5446
+ in: path
5447
+ description: ID of the manual crypto balance to delete
5448
+ required: true
5449
+ schema:
5450
+ type: integer
5451
+ format: int32
5452
+ examples:
5453
+ existing manual crypto:
5454
+ summary: Existing manual crypto ID
5455
+ value: 22001
5456
+ id not found:
5457
+ summary: Example of an id that doesn't exist
5458
+ value: 99999999
5459
+ - name: keep_history
5460
+ in: query
5461
+ description: Explicitly set to `true` to preserve balance history, or `false` to remove associated history during deletion. This must be set if the account has a balance history.
5462
+ required: false
5463
+ schema:
5464
+ type: boolean
5465
+ responses:
5466
+ "204":
5467
+ description: No Content. The crypto asset has been deleted.
5468
+ "401":
5469
+ $ref: "#/components/responses/unauthorizedToken"
5470
+ "404":
5471
+ description: Not Found
4440
5472
  content:
4441
5473
  application/json:
4442
5474
  schema:
4443
5475
  $ref: "#/components/schemas/errorResponseObject"
4444
5476
  example:
4445
- message: Request Validation Failure
5477
+ message: Not Found
4446
5478
  errors:
4447
- - errMsg: must be a valid integer
4448
- instancePath: /query/ids/0
4449
- schemaPath: "#/properties/query/properties/ids/items/type"
4450
- keyword: type
4451
- params:
4452
- type: integer
4453
- "401":
4454
- $ref: "#/components/responses/unauthorizedToken"
4455
- "404":
4456
- description: Not Found
5479
+ - errMsg: "There is no manual crypto balance with the id: 99999999."
5480
+ "422":
5481
+ description: Unprocessable Content
4457
5482
  content:
4458
5483
  application/json:
4459
5484
  schema:
4460
5485
  $ref: "#/components/schemas/errorResponseObject"
4461
5486
  example:
4462
- message: Not Found
5487
+ message: Explicit confirmation required
4463
5488
  errors:
4464
- - errMsg: There is no category with the id:'543210'`
5489
+ - errMsg: This crypto manual account has existing balance history. To delete this account, you must explicitly set keep_history to true or false.
5490
+ crypto_manual_id: 22001
5491
+ has_balance_history: true
5492
+ required_parameter: keep_history
5493
+ allowed_values:
5494
+ - true
5495
+ - false
4465
5496
  "429":
4466
5497
  $ref: "#/components/responses/rateLimited"
4467
5498
  "500":
4468
5499
  $ref: "#/components/responses/serverError"
4469
- put:
5500
+ /crypto/synced:
5501
+ get:
4470
5502
  tags:
4471
- - categories
4472
- summary: Update an existing category or category group
4473
- description: >-
4474
- Modifies the properties of an existing category or category group.<br><br>
4475
-
4476
- You may submit the response from a `GET /categories/{id}` as the request body; however, only certain
4477
- properties can be updated using this API. The following properties are
4478
- accepted in the request body but their values will be ignored: `id`, `is_group`,`archived_at`, `updated_at`, `created_at`, and `order`.<br><br>
4479
-
4480
- It is also possible to provide only the properties to be updated in the
4481
- request body, as long as the request includes at least one of the
4482
- properties that is not listed above. For example, a request body that contains only a `name` property is valid.<br><br>
4483
-
4484
- It is not possible to use this API to convert a category to a category group, or a vice versa, so while submitting a request body with the `is_group` property is tolerated, it will result in an error response if the value is changed.<br><br>
4485
-
4486
- It is possible to modify the children of an existing category group with this API by setting the `children` attribute. If this is set, it will replace the existing children with the newly specified children. If the intention is to add or remove a single category, it is more straightforward to update the child category by specifying the new `group_id` attribute. If the goal is to add multiple new children or remove multiple existing children, it is recommended to first call the `GET /categories/:id` endpoint to get the existing children and then modify the list as desired.<br><br>
4487
- operationId: updateCategory
5503
+ - crypto
5504
+ summary: Get all synced crypto balances
5505
+ description: Retrieves the balances for all synced crypto accounts associated with the user's account.
5506
+ operationId: getAllCryptoSynced
5507
+ responses:
5508
+ "200":
5509
+ description: A list of synced crypto balances
5510
+ content:
5511
+ application/json:
5512
+ schema:
5513
+ $ref: "#/components/schemas/cryptoSyncedListResponseObject"
5514
+ example:
5515
+ crypto_synced:
5516
+ - id: 33004
5517
+ source: synced
5518
+ name: ETH
5519
+ display_name: Coinbase Main
5520
+ institution_name: Coinbase
5521
+ balance: "12.004500000000000000"
5522
+ currency: eth
5523
+ coingecko_id: ethereum
5524
+ to_base: 28998.44
5525
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5526
+ last_import: "2026-02-25T14:25:01.000Z"
5527
+ account_status: active
5528
+ created_by_name: User 1
5529
+ created_at: "2025-10-02T11:02:09.000Z"
5530
+ updated_at: "2026-02-25T14:25:01.000Z"
5531
+ - id: 33004
5532
+ source: synced
5533
+ name: BTC
5534
+ display_name: Coinbase Main
5535
+ institution_name: Coinbase
5536
+ balance: "0.100020003000400050"
5537
+ currency: btc
5538
+ coingecko_id: bitcoin
5539
+ to_base: 6231.28
5540
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5541
+ last_import: "2026-02-25T14:25:01.000Z"
5542
+ account_status: active
5543
+ created_by_name: User 1
5544
+ created_at: "2025-10-02T11:02:09.000Z"
5545
+ updated_at: "2026-02-25T14:25:01.000Z"
5546
+ "401":
5547
+ $ref: "#/components/responses/unauthorizedToken"
5548
+ "429":
5549
+ $ref: "#/components/responses/rateLimited"
5550
+ "500":
5551
+ $ref: "#/components/responses/serverError"
5552
+ /crypto/synced/{id}:
5553
+ get:
5554
+ tags:
5555
+ - crypto
5556
+ summary: Get synced crypto balances for a single synced connection
5557
+ description: Retrieves the balances for all currencies connected from the specified synced crypto account ID.
5558
+ operationId: getCryptoSyncedById
4488
5559
  parameters:
4489
5560
  - name: id
4490
5561
  in: path
4491
- description: ID of the category to update
5562
+ description: Synced crypto account ID
4492
5563
  required: true
4493
5564
  schema:
4494
5565
  type: integer
4495
5566
  format: int32
4496
5567
  examples:
4497
- category:
4498
- summary: Example of a category's id
4499
- value: 83
4500
- category group:
4501
- summary: Example of a category group's id
4502
- value: 86
4503
- child category:
4504
- summary: Example of a category belonging to a group
4505
- value: 315164
4506
- not found:
4507
- summary: Example of a category id that does not exist
4508
- value: 543210
4509
- requestBody:
4510
- required: true
4511
- content:
4512
- application/json:
4513
- schema:
4514
- $ref: "#/components/schemas/updateCategoryRequestObject"
4515
- examples:
4516
- Update some category properties:
4517
- value:
4518
- name: Updated Category Name
4519
- description: Updated description of the category
4520
- Update same properties with full object:
4521
- value:
4522
- id: 83
4523
- name: Updated Category Name
4524
- description: Updated description of the category
4525
- is_income: false
4526
- exclude_from_budget: true
4527
- exclude_from_totals: false
4528
- updated_at: "2020-01-28T09:49:03.225Z"
4529
- created_at: "2020-01-28T09:49:03.225Z"
4530
- is_group: false
4531
- group_id: null
4532
- archived: false
4533
- archived_at: null
4534
- order: 0
4535
- Invalid attempt to convert to category group:
4536
- value:
4537
- id: 83
4538
- name: Old Category is now a group!
4539
- is_group: true
4540
- Remove category from a group:
4541
- value:
4542
- id: 86
4543
- name: Automobile
4544
- description: API Removed a sub category
4545
- children:
4546
- - 315174
5568
+ existing synced connection:
5569
+ summary: Existing synced account ID
5570
+ value: 33004
5571
+ id not found:
5572
+ summary: Example of an id that doesn't exist
5573
+ value: 99999999
4547
5574
  responses:
4548
5575
  "200":
4549
- description: Category or Category Group updated successfully
5576
+ description: Synced crypto balances for a single synced account
4550
5577
  content:
4551
5578
  application/json:
4552
5579
  schema:
4553
- $ref: "#/components/schemas/categoryObject"
4554
- examples:
4555
- category:
4556
- value:
4557
- id: 83
4558
- name: Updated Category Name
4559
- description: Updated description of the category
4560
- is_income: false
4561
- exclude_from_budget: false
4562
- exclude_from_totals: true
4563
- updated_at: "2025-05-26T20:41:18.406Z"
4564
- created_at: "2025-01-28T09:49:03.225Z"
4565
- is_group: false
4566
- order: 0
4567
- collapsed: false
4568
- archived: false
4569
- archived_at: null
4570
- group_id: null
4571
- category group:
4572
- value:
4573
- id: 86
4574
- name: Automobile
4575
- description: API Removed a sub category
4576
- is_income: false
4577
- exclude_from_budget: false
4578
- exclude_from_totals: false
4579
- updated_at: "2025-06-22T19:54:30.921Z"
4580
- created_at: "2025-01-28T09:49:03.238Z"
4581
- is_group: true
4582
- order: 2
4583
- collapsed: false
4584
- archived: false
4585
- group_id: null
4586
- archived_at: null
4587
- children:
4588
- - id: 315174
4589
- name: Fuel
4590
- description: Fuel and gas expenses
4591
- is_income: false
4592
- exclude_from_budget: false
4593
- exclude_from_totals: false
4594
- updated_at: "2025-02-28T09:49:03.238Z"
4595
- created_at: "2025-01-28T09:49:03.238Z"
4596
- group_id: 86
4597
- is_group: false
4598
- archived: false
4599
- archived_at: null
4600
- order: 1
4601
- collapsed: false
5580
+ $ref: "#/components/schemas/cryptoSyncedListResponseObject"
5581
+ example:
5582
+ crypto_synced:
5583
+ - id: 33004
5584
+ source: synced
5585
+ name: ETH
5586
+ display_name: Coinbase Main
5587
+ institution_name: Coinbase
5588
+ balance: "12.004500000000000000"
5589
+ currency: eth
5590
+ coingecko_id: ethereum
5591
+ to_base: 28998.44
5592
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5593
+ last_import: "2026-02-25T14:25:01.000Z"
5594
+ account_status: active
5595
+ created_by_name: User 1
5596
+ created_at: "2025-10-02T11:02:09.000Z"
5597
+ updated_at: "2026-02-25T14:25:01.000Z"
4602
5598
  "400":
4603
5599
  description: Bad Request
4604
5600
  content:
@@ -4606,10 +5602,9 @@ paths:
4606
5602
  schema:
4607
5603
  $ref: "#/components/schemas/errorResponseObject"
4608
5604
  example:
4609
- message: Invalid Request Body
5605
+ message: Invalid Path Parameters
4610
5606
  errors:
4611
- - errMsg: Cannot modify the 'group_id' property of an existing category or
4612
- category group
5607
+ - errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'."
4613
5608
  "401":
4614
5609
  $ref: "#/components/responses/unauthorizedToken"
4615
5610
  "404":
@@ -4621,50 +5616,72 @@ paths:
4621
5616
  example:
4622
5617
  message: Not Found
4623
5618
  errors:
4624
- - errMsg: There is no category with the id:'543210'`
5619
+ - errMsg: "There is no synced crypto connection with the id: 99999999."
4625
5620
  "429":
4626
5621
  $ref: "#/components/responses/rateLimited"
4627
5622
  "500":
4628
5623
  $ref: "#/components/responses/serverError"
4629
- delete:
5624
+ /crypto/synced/{id}/refresh:
5625
+ post:
4630
5626
  tags:
4631
- - categories
4632
- summary: Delete a category or category group
4633
- description: Attempts to delete the single category or category group specified
4634
- on the path. By default, this will only work if there are no dependencies,
4635
- such as existing budgets for the category, categorized transactions,
4636
- children categories for a category group, categorized recurring items,
4637
- etc. If there are dependents, this endpoint will return an object that
4638
- describes the amount and type of existing dependencies.
4639
- operationId: deleteCategory
5627
+ - crypto
5628
+ summary: Refresh balances for a synced crypto account
5629
+ description: Trigger a balance refresh for the specified synced crypto account. Returns a normalized cryptoSyncedListResponseObject envelope containing the refreshed balances for the account.
5630
+ operationId: refreshCryptoSynced
4640
5631
  parameters:
4641
- - in: path
4642
- name: id
4643
- description: ID of the category to delete
5632
+ - name: id
5633
+ in: path
5634
+ description: Synced crypto account ID
4644
5635
  required: true
4645
5636
  schema:
4646
5637
  type: integer
4647
5638
  format: int32
4648
5639
  examples:
4649
- delete category:
4650
- summary: Simple category delete
4651
- value: 83
4652
- delete category group:
4653
- summary: Attempt to delete category with dependencies
4654
- value: 84
5640
+ existing synced connection:
5641
+ summary: Existing synced account ID
5642
+ value: 33004
4655
5643
  id not found:
4656
5644
  summary: Example of an id that doesn't exist
4657
- value: 543210
4658
- - in: query
4659
- name: force
4660
- description: Set to `true` to force deletion even if there are dependencies
4661
- required: false
4662
- schema:
4663
- type: boolean
4664
- default: false
5645
+ value: 99999999
4665
5646
  responses:
4666
- "204":
4667
- description: No Content
5647
+ "200":
5648
+ description: Refreshed balances for the synced crypto account
5649
+ content:
5650
+ application/json:
5651
+ schema:
5652
+ $ref: "#/components/schemas/cryptoSyncedListResponseObject"
5653
+ example:
5654
+ crypto_synced:
5655
+ - id: 33004
5656
+ source: synced
5657
+ name: ETH
5658
+ display_name: Coinbase Main
5659
+ institution_name: Coinbase
5660
+ balance: "12.004500000000000000"
5661
+ currency: eth
5662
+ coingecko_id: ethereum
5663
+ to_base: 28998.44
5664
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5665
+ last_import: "2026-02-25T14:25:01.000Z"
5666
+ account_status: active
5667
+ created_by_name: User 1
5668
+ created_at: "2025-10-02T11:02:09.000Z"
5669
+ updated_at: "2026-02-25T14:25:01.000Z"
5670
+ - id: 33004
5671
+ source: synced
5672
+ name: BTC
5673
+ display_name: Coinbase Main
5674
+ institution_name: Coinbase
5675
+ balance: "0.100020003000400050"
5676
+ currency: btc
5677
+ coingecko_id: bitcoin
5678
+ to_base: 6231.28
5679
+ balance_as_of: "2026-02-25T14:25:00.000Z"
5680
+ last_import: "2026-02-25T14:25:01.000Z"
5681
+ account_status: active
5682
+ created_by_name: User 1
5683
+ created_at: "2025-10-02T11:02:09.000Z"
5684
+ updated_at: "2026-02-25T14:25:01.000Z"
4668
5685
  "401":
4669
5686
  $ref: "#/components/responses/unauthorizedToken"
4670
5687
  "404":
@@ -4676,36 +5693,7 @@ paths:
4676
5693
  example:
4677
5694
  message: Not Found
4678
5695
  errors:
4679
- - errMsg: There is no category with the id:'543210'`
4680
- "422":
4681
- description: Unprocessable Entity
4682
- content:
4683
- application/json:
4684
- schema:
4685
- $ref: "#/components/schemas/deleteCategoryResponseWithDependencies"
4686
- examples:
4687
- delete category with dependencies:
4688
- summary: Response to an attempt to delete category with dependencies
4689
- value:
4690
- category_name: Category to be Deleted
4691
- dependents:
4692
- budget: 0
4693
- category_rules: 1
4694
- transactions: 10
4695
- children: 0
4696
- recurring: 0
4697
- plaid_cats: 0
4698
- delete category group:
4699
- summary: Response to attempt to delete a category group with children
4700
- value:
4701
- category_name: Category Group to be Deleted
4702
- dependents:
4703
- budget: 0
4704
- category_rules: 0
4705
- transactions: 0
4706
- children: 3
4707
- recurring: 0
4708
- plaid_cats: 0
5696
+ - errMsg: "There is no synced crypto connection with the id: 99999999."
4709
5697
  "429":
4710
5698
  $ref: "#/components/responses/rateLimited"
4711
5699
  "500":
@@ -5139,7 +6127,7 @@ paths:
5139
6127
  example:
5140
6128
  message: Not Found
5141
6129
  errors:
5142
- - errMsg: There is no manual account with the id:'543210'`
6130
+ - errMsg: "There is no manual account with the id: 543210."
5143
6131
  "429":
5144
6132
  $ref: "#/components/responses/rateLimited"
5145
6133
  "500":
@@ -5196,7 +6184,7 @@ paths:
5196
6184
  example:
5197
6185
  message: Not Found
5198
6186
  errors:
5199
- - errMsg: There is no manual account with the id:'543210'`
6187
+ - errMsg: "There is no manual account with the id: 543210."
5200
6188
  "429":
5201
6189
  $ref: "#/components/responses/rateLimited"
5202
6190
  "500":
@@ -5994,7 +6982,7 @@ paths:
5994
6982
  apply_rules:
5995
6983
  type: boolean
5996
6984
  default: false
5997
- description: If `true`, any rules associated with the account specified by
6985
+ description: If explicitly set to `true`, any rules associated with the account specified by
5998
6986
  the `manual_account_id` property for each transaction will
5999
6987
  be applied.
6000
6988
  skip_duplicates:
@@ -6358,7 +7346,7 @@ paths:
6358
7346
  examples:
6359
7347
  invalid ids in new transactions:
6360
7348
  value:
6361
- message: Invalid Request Body
7349
+ message: Request Validation Failure
6362
7350
  errors:
6363
7351
  - errMsg: "transactions[0] manual account ID does not exist: 9999999"
6364
7352
  transaction_index: 0
@@ -6377,7 +7365,7 @@ paths:
6377
7365
  recurring_id: 88888888
6378
7366
  duplicate external_ids within request:
6379
7367
  value:
6380
- message: Invalid Request Body
7368
+ message: Request Validation Failure
6381
7369
  errors:
6382
7370
  - errMsg: Duplicate External IDs found in the request body
6383
7371
  error: Duplicate External ID
@@ -6653,7 +7641,7 @@ paths:
6653
7641
  examples:
6654
7642
  invalid ids in id list:
6655
7643
  value:
6656
- message: Invalid Request Body
7644
+ message: Request Validation Failure
6657
7645
  errors:
6658
7646
  - errMsg: "transactions[0] manual account ID does not exist: 999999999"
6659
7647
  transaction_index: 0
@@ -6672,7 +7660,7 @@ paths:
6672
7660
  recurring_id: 888888888
6673
7661
  update with errors:
6674
7662
  value:
6675
- message: Invalid Request Body
7663
+ message: Request Validation Failure
6676
7664
  errors:
6677
7665
  - errMsg: "There is no transaction with the id: 9999999"
6678
7666
  error: Invalid Transaction ID
@@ -6730,7 +7718,7 @@ paths:
6730
7718
  locked_property: amount
6731
7719
  duplicate external_ids within request:
6732
7720
  value:
6733
- message: Invalid Request Body
7721
+ message: Request Validation Failure
6734
7722
  errors:
6735
7723
  - errMsg: Duplicate External IDs found in the request body
6736
7724
  error: Duplicate External ID
@@ -6748,7 +7736,7 @@ paths:
6748
7736
  - 3
6749
7737
  invalid ids:
6750
7738
  value:
6751
- message: Invalid Request Body
7739
+ message: Request Validation Failure
6752
7740
  errors:
6753
7741
  - errMsg: "There is no transaction with the id: 1"
6754
7742
  error: Invalid Transaction ID
@@ -7117,7 +8105,7 @@ paths:
7117
8105
  example:
7118
8106
  message: Not Found
7119
8107
  errors:
7120
- - errMsg: There is no transaction with the id:'543210'`
8108
+ - errMsg: "There is no transaction with the id: 543210."
7121
8109
  "429":
7122
8110
  $ref: "#/components/responses/rateLimited"
7123
8111
  "500":
@@ -7256,7 +8244,7 @@ paths:
7256
8244
  example:
7257
8245
  message: Not Found
7258
8246
  errors:
7259
- - errMsg: There is no transaction with the id:'543210'`
8247
+ - errMsg: "There is no transaction with the id: 543210."
7260
8248
  "429":
7261
8249
  $ref: "#/components/responses/rateLimited"
7262
8250
  "500":
@@ -7309,7 +8297,7 @@ paths:
7309
8297
  example:
7310
8298
  message: Not Found
7311
8299
  errors:
7312
- - errMsg: There is no transaction with the id:'543210'`
8300
+ - errMsg: "There is no transaction with the id: 543210."
7313
8301
  "429":
7314
8302
  $ref: "#/components/responses/rateLimited"
7315
8303
  "500":
@@ -7830,30 +8818,30 @@ paths:
7830
8818
  examples:
7831
8819
  bad math:
7832
8820
  value:
7833
- message: Invalid Request Body
8821
+ message: Request Validation Failure
7834
8822
  errors:
7835
- - errMsg: Sums of split transactions do not add up to the original transaction
7836
- amount!
8823
+ - errMsg: Sum of split transactions do not add up to the original transaction amount.
7837
8824
  split recurring:
7838
8825
  value:
7839
- message: Invalid Request Body
8826
+ message: Request Validation Failure
7840
8827
  errors:
7841
- - errMsg: You cannot split a recurring transaction!
8828
+ - errMsg: You cannot split a recurring transaction.
8829
+ id: 2112150655
7842
8830
  split group:
7843
8831
  value:
7844
- message: Invalid Request Body
8832
+ message: Request Validation Failure
7845
8833
  errors:
7846
- - errMsg: You cannot split a grouped transaction!
8834
+ - errMsg: You cannot split a group transaction. Ungroup it before splitting.
7847
8835
  split split:
7848
8836
  value:
7849
- message: Invalid Request Body
8837
+ message: Request Validation Failure
7850
8838
  errors:
7851
- - errMsg: You cannot split an already split transaction!"
8839
+ - errMsg: You cannot split an already split transaction. Unsplit it before splitting again.
7852
8840
  missing amount in child transaction:
7853
8841
  value:
7854
8842
  message: Invalid Request Body
7855
8843
  errors:
7856
- - errMsg: "child_transactions[0] amount is required."
8844
+ - errMsg: "child_transactions[0] is missing required property 'amount' in request body."
7857
8845
  child_transactions_index: 0
7858
8846
  error: Missing required property
7859
8847
  invalid_property: amount
@@ -8407,9 +9395,9 @@ paths:
8407
9395
  schema:
8408
9396
  $ref: "#/components/schemas/errorResponseObject"
8409
9397
  example:
8410
- message: Invalid Request Body
9398
+ message: Request Validation Failure
8411
9399
  errors:
8412
- - errMsg: "A request to update a tag must include at least one of the following properties: name, description, archived"
9400
+ - errMsg: "A request to update a tag must include at least one of the following properties: name, description, archived."
8413
9401
  "401":
8414
9402
  $ref: "#/components/responses/unauthorizedToken"
8415
9403
  "404":
@@ -8421,7 +9409,7 @@ paths:
8421
9409
  example:
8422
9410
  message: Not Found
8423
9411
  errors:
8424
- - errMsg: There is no tag with the id:'543210'`
9412
+ - errMsg: "There is no tag with the id: 543210."
8425
9413
  "429":
8426
9414
  $ref: "#/components/responses/rateLimited"
8427
9415
  "500":
@@ -8476,9 +9464,9 @@ paths:
8476
9464
  example:
8477
9465
  message: Not Found
8478
9466
  errors:
8479
- - errMsg: There is no tag with the id:'543210'`
9467
+ - errMsg: "There is no tag with the id: 543210."
8480
9468
  "422":
8481
- description: Unprocessable Entity
9469
+ description: Unprocessable Content
8482
9470
  content:
8483
9471
  application/json:
8484
9472
  schema: