@lunch-money/v2-api-spec 2.9.0 → 2.10.0-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md.backup +0 -12
- package/lunch-money-api-v2.yaml +1009 -61
- package/package.json +1 -1
- package/version-history.md +9 -3
package/README.md.backup
CHANGED
|
@@ -66,18 +66,6 @@ The OpenAPI spec is the authoritative source for:
|
|
|
66
66
|
- Authentication requirements
|
|
67
67
|
- Status codes and error formats
|
|
68
68
|
|
|
69
|
-
##### Versioning
|
|
70
|
-
|
|
71
|
-
The Lunch Money API spec uses a modified version of SEMVER for its versioning methodology as follows
|
|
72
|
-
- The major version is the API version. This will always be 2 in this repo
|
|
73
|
-
- The minor version represents the number of main endpoints (or OpenAPI tags) the current version of the spec supports. For example, a version of the API that supports the /me, /categories, and /transactions endpoints would have a minor version of 3
|
|
74
|
-
- The revision number represents the number of updates since the last endpoint was added. For example, each time changes are made to one of the existing three APIs as described above, the revision number will be bumped.
|
|
75
|
-
|
|
76
|
-
Details of each version can be found in [./version-history.md](./version-history.md)
|
|
77
|
-
|
|
78
|
-
Changes to the spec that modify existing or add new API endpoints should update the version number in the spec and in the package.json accordingly.
|
|
79
|
-
|
|
80
|
-
|
|
81
69
|
### Documentation Guides (`v2/docs/*.md`)
|
|
82
70
|
- **Purpose**: Human-readable guides and tutorials
|
|
83
71
|
- **Format**: Markdown with custom extensions
|
package/lunch-money-api-v2.yaml
CHANGED
|
@@ -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.
|
|
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:
|
|
@@ -622,6 +627,347 @@ components:
|
|
|
622
627
|
- category_name
|
|
623
628
|
- dependents
|
|
624
629
|
|
|
630
|
+
# The base object containing information about a crypto balance
|
|
631
|
+
cryptoBalanceObject:
|
|
632
|
+
type: object
|
|
633
|
+
title: crypto balance object
|
|
634
|
+
additionalProperties: false
|
|
635
|
+
description: The balance for a single crypto asset
|
|
636
|
+
properties:
|
|
637
|
+
id:
|
|
638
|
+
type: integer
|
|
639
|
+
format: int32
|
|
640
|
+
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"
|
|
641
|
+
source:
|
|
642
|
+
type: string
|
|
643
|
+
description: The source type for this crypto asset
|
|
644
|
+
enum:
|
|
645
|
+
- manual
|
|
646
|
+
- synced
|
|
647
|
+
name:
|
|
648
|
+
type: string
|
|
649
|
+
nullable: true
|
|
650
|
+
minLength: 1
|
|
651
|
+
maxLength: 45
|
|
652
|
+
description: The name of the crypto asset
|
|
653
|
+
display_name:
|
|
654
|
+
type: string
|
|
655
|
+
nullable: true
|
|
656
|
+
description: Optional display name for the crypto asset
|
|
657
|
+
institution_name:
|
|
658
|
+
type: string
|
|
659
|
+
nullable: true
|
|
660
|
+
minLength: 1
|
|
661
|
+
maxLength: 50
|
|
662
|
+
description: Institution or wallet provider display name
|
|
663
|
+
balance:
|
|
664
|
+
type: string
|
|
665
|
+
pattern: ^-?\d+(\.\d{1,18})?$
|
|
666
|
+
description: Current balance in numeric format to 18 decimal places
|
|
667
|
+
currency:
|
|
668
|
+
type: string
|
|
669
|
+
minLength: 1
|
|
670
|
+
maxLength: 10
|
|
671
|
+
description: Cryptocurrency symbol
|
|
672
|
+
coingecko_id:
|
|
673
|
+
type: string
|
|
674
|
+
nullable: true
|
|
675
|
+
minLength: 1
|
|
676
|
+
maxLength: 100
|
|
677
|
+
description: CoinGecko identifier associated with this balance
|
|
678
|
+
to_base:
|
|
679
|
+
type: number
|
|
680
|
+
description: Balance converted to the user's primary currency
|
|
681
|
+
balance_as_of:
|
|
682
|
+
type: string
|
|
683
|
+
format: date-time
|
|
684
|
+
nullable: true
|
|
685
|
+
description: Date/time the balance was last updated in ISO 8601 extended format
|
|
686
|
+
last_import:
|
|
687
|
+
type: string
|
|
688
|
+
format: date-time
|
|
689
|
+
nullable: true
|
|
690
|
+
description: Timestamp in ISO 8601 extended format of the last successful import
|
|
691
|
+
status:
|
|
692
|
+
type: string
|
|
693
|
+
description: Status of the crypto asset
|
|
694
|
+
enum:
|
|
695
|
+
- active
|
|
696
|
+
- unsupported
|
|
697
|
+
- relink
|
|
698
|
+
- initializing
|
|
699
|
+
created_by_name:
|
|
700
|
+
type: string
|
|
701
|
+
nullable: true
|
|
702
|
+
description: Name of the user who created the crypto asset
|
|
703
|
+
created_at:
|
|
704
|
+
type: string
|
|
705
|
+
format: date-time
|
|
706
|
+
description: Date/time the crypto asset was created in ISO 8601 extended format
|
|
707
|
+
updated_at:
|
|
708
|
+
type: string
|
|
709
|
+
format: date-time
|
|
710
|
+
description: Date/time the crypto asset was last updated in ISO 8601 extended format
|
|
711
|
+
required:
|
|
712
|
+
- id
|
|
713
|
+
- source
|
|
714
|
+
- name
|
|
715
|
+
- display_name
|
|
716
|
+
- institution_name
|
|
717
|
+
- balance
|
|
718
|
+
- currency
|
|
719
|
+
- coingecko_id
|
|
720
|
+
- to_base
|
|
721
|
+
- balance_as_of
|
|
722
|
+
- last_import
|
|
723
|
+
- status
|
|
724
|
+
- created_by_name
|
|
725
|
+
- created_at
|
|
726
|
+
- updated_at
|
|
727
|
+
|
|
728
|
+
# Manual crypto balance type derived from cryptoBalanceObject
|
|
729
|
+
cryptoManualObject:
|
|
730
|
+
title: manual crypto object
|
|
731
|
+
x-internal: true
|
|
732
|
+
allOf:
|
|
733
|
+
- $ref: "#/components/schemas/cryptoBalanceObject"
|
|
734
|
+
- type: object
|
|
735
|
+
properties:
|
|
736
|
+
source:
|
|
737
|
+
type: string
|
|
738
|
+
description: The source type for this crypto asset. Will always be "manual" for manual crypto assets.
|
|
739
|
+
enum:
|
|
740
|
+
- manual
|
|
741
|
+
status:
|
|
742
|
+
type: string
|
|
743
|
+
description: Status of the manual crypto asset
|
|
744
|
+
enum:
|
|
745
|
+
- active
|
|
746
|
+
currency:
|
|
747
|
+
type: string
|
|
748
|
+
minLength: 1
|
|
749
|
+
maxLength: 10
|
|
750
|
+
description: Cryptocurrency symbol is supported by Lunch Money for manual tracking
|
|
751
|
+
|
|
752
|
+
# Synced crypto balance type derived from cryptoBalanceObject
|
|
753
|
+
cryptoSyncedObject:
|
|
754
|
+
title: synced crypto object
|
|
755
|
+
x-internal: true
|
|
756
|
+
allOf:
|
|
757
|
+
- $ref: "#/components/schemas/cryptoBalanceObject"
|
|
758
|
+
- type: object
|
|
759
|
+
properties:
|
|
760
|
+
source:
|
|
761
|
+
type: string
|
|
762
|
+
description: The source type for this crypto asset. Will always be "synced" for synced crypto assets.
|
|
763
|
+
enum:
|
|
764
|
+
- synced
|
|
765
|
+
status:
|
|
766
|
+
type: string
|
|
767
|
+
description: Status of the synced connection
|
|
768
|
+
enum:
|
|
769
|
+
- active
|
|
770
|
+
- unsupported
|
|
771
|
+
- relink
|
|
772
|
+
- initializing
|
|
773
|
+
currency:
|
|
774
|
+
type: string
|
|
775
|
+
minLength: 1
|
|
776
|
+
maxLength: 10
|
|
777
|
+
description: Symbol of the currency held in the synced account.
|
|
778
|
+
|
|
779
|
+
# Response object returned by GET /crypto
|
|
780
|
+
cryptoListResponseObject:
|
|
781
|
+
type: object
|
|
782
|
+
x-internal: true
|
|
783
|
+
additionalProperties: false
|
|
784
|
+
properties:
|
|
785
|
+
crypto:
|
|
786
|
+
type: array
|
|
787
|
+
items:
|
|
788
|
+
$ref: "#/components/schemas/cryptoBalanceObject"
|
|
789
|
+
required:
|
|
790
|
+
- crypto
|
|
791
|
+
|
|
792
|
+
# Response object returned by GET /crypto/manual
|
|
793
|
+
cryptoManualListResponseObject:
|
|
794
|
+
type: object
|
|
795
|
+
x-internal: true
|
|
796
|
+
additionalProperties: false
|
|
797
|
+
properties:
|
|
798
|
+
crypto_manual:
|
|
799
|
+
type: array
|
|
800
|
+
items:
|
|
801
|
+
$ref: "#/components/schemas/cryptoManualObject"
|
|
802
|
+
required:
|
|
803
|
+
- crypto_manual
|
|
804
|
+
|
|
805
|
+
# Response object returned by GET /crypto/synced and GET /crypto/synced/{id}
|
|
806
|
+
cryptoSyncedListResponseObject:
|
|
807
|
+
type: object
|
|
808
|
+
x-internal: true
|
|
809
|
+
additionalProperties: false
|
|
810
|
+
properties:
|
|
811
|
+
crypto_synced:
|
|
812
|
+
type: array
|
|
813
|
+
items:
|
|
814
|
+
$ref: "#/components/schemas/cryptoSyncedObject"
|
|
815
|
+
required:
|
|
816
|
+
- crypto_synced
|
|
817
|
+
|
|
818
|
+
# The object that may be submitted to POST /crypto/manual
|
|
819
|
+
createCryptoManualRequestObject:
|
|
820
|
+
type: object
|
|
821
|
+
additionalProperties: false
|
|
822
|
+
x-internal: true
|
|
823
|
+
properties:
|
|
824
|
+
name:
|
|
825
|
+
type: string
|
|
826
|
+
minLength: 1
|
|
827
|
+
maxLength: 45
|
|
828
|
+
description: The name of the manual crypto asset
|
|
829
|
+
example: Hardware Wallet
|
|
830
|
+
display_name:
|
|
831
|
+
type: string
|
|
832
|
+
minLength: 1
|
|
833
|
+
maxLength: 45
|
|
834
|
+
description: Optional display name for the manual crypto asset
|
|
835
|
+
example: Cold Storage
|
|
836
|
+
institution_name:
|
|
837
|
+
type: string
|
|
838
|
+
minLength: 1
|
|
839
|
+
maxLength: 50
|
|
840
|
+
description: Optional institution or wallet provider display name
|
|
841
|
+
example: Ledger
|
|
842
|
+
balance:
|
|
843
|
+
oneOf:
|
|
844
|
+
- type: number
|
|
845
|
+
format: double
|
|
846
|
+
- type: string
|
|
847
|
+
pattern: ^-?\d+(\.\d{1,18})?$
|
|
848
|
+
description: Numeric value of the balance, up to 18 decimal places
|
|
849
|
+
example: "0.523400000000000000"
|
|
850
|
+
currency:
|
|
851
|
+
type: string
|
|
852
|
+
minLength: 1
|
|
853
|
+
maxLength: 10
|
|
854
|
+
description: Cryptocurrency symbol is supported by Lunch Money for manual tracking
|
|
855
|
+
example: btc
|
|
856
|
+
coingecko_id:
|
|
857
|
+
type: string
|
|
858
|
+
minLength: 1
|
|
859
|
+
maxLength: 100
|
|
860
|
+
description: CoinGecko identifier for this crypto asset
|
|
861
|
+
example: bitcoin
|
|
862
|
+
required:
|
|
863
|
+
- name
|
|
864
|
+
- balance
|
|
865
|
+
- coingecko_id
|
|
866
|
+
- currency
|
|
867
|
+
|
|
868
|
+
# The object that may be submitted to PUT /crypto/manual/{id}
|
|
869
|
+
updateCryptoManualRequestObject:
|
|
870
|
+
type: object
|
|
871
|
+
x-internal: true
|
|
872
|
+
additionalProperties: false
|
|
873
|
+
properties:
|
|
874
|
+
id:
|
|
875
|
+
type: integer
|
|
876
|
+
format: int32
|
|
877
|
+
description: System defined unique ID for the manual crypto asset. Ignored if set
|
|
878
|
+
x-updatable: false
|
|
879
|
+
source:
|
|
880
|
+
type: string
|
|
881
|
+
description: System defined source for the crypto asset. Ignored if set
|
|
882
|
+
enum:
|
|
883
|
+
- manual
|
|
884
|
+
x-updatable: false
|
|
885
|
+
name:
|
|
886
|
+
type: string
|
|
887
|
+
nullable: true
|
|
888
|
+
minLength: 1
|
|
889
|
+
maxLength: 45
|
|
890
|
+
description: If set, the new name of the manual crypto asset
|
|
891
|
+
x-updatable: true
|
|
892
|
+
display_name:
|
|
893
|
+
type: string
|
|
894
|
+
nullable: true
|
|
895
|
+
minLength: 1
|
|
896
|
+
maxLength: 45
|
|
897
|
+
description: If set, the new display name for the manual crypto asset
|
|
898
|
+
x-updatable: true
|
|
899
|
+
institution_name:
|
|
900
|
+
type: string
|
|
901
|
+
nullable: true
|
|
902
|
+
minLength: 1
|
|
903
|
+
maxLength: 50
|
|
904
|
+
description: If set, the new institution or wallet provider display name
|
|
905
|
+
x-updatable: true
|
|
906
|
+
balance:
|
|
907
|
+
oneOf:
|
|
908
|
+
- type: number
|
|
909
|
+
format: double
|
|
910
|
+
- type: string
|
|
911
|
+
pattern: ^-?\d+(\.\d{1,18})?$
|
|
912
|
+
description: If set, the new balance value up to 18 decimal places
|
|
913
|
+
example: "1.050000000000000000"
|
|
914
|
+
x-updatable: true
|
|
915
|
+
currency:
|
|
916
|
+
type: string
|
|
917
|
+
minLength: 1
|
|
918
|
+
maxLength: 10
|
|
919
|
+
description: Cryptocurrency symbol is supported by Lunch Money for manual tracking. Ignored if set
|
|
920
|
+
x-updatable: false
|
|
921
|
+
coingecko_id:
|
|
922
|
+
type: string
|
|
923
|
+
nullable: true
|
|
924
|
+
minLength: 1
|
|
925
|
+
maxLength: 100
|
|
926
|
+
description: System defined CoinGecko identifier associated with this balance. Ignored if set
|
|
927
|
+
x-updatable: false
|
|
928
|
+
to_base:
|
|
929
|
+
type: number
|
|
930
|
+
description: System defined balance converted to the user's primary currency. Ignored if set
|
|
931
|
+
x-updatable: false
|
|
932
|
+
balance_as_of:
|
|
933
|
+
type: string
|
|
934
|
+
format: date-time
|
|
935
|
+
nullable: true
|
|
936
|
+
description: System defined date/time the balance was last updated in ISO 8601 extended format. Ignored if set
|
|
937
|
+
x-updatable: false
|
|
938
|
+
last_import:
|
|
939
|
+
type: string
|
|
940
|
+
format: date-time
|
|
941
|
+
nullable: true
|
|
942
|
+
description: System defined timestamp in ISO 8601 extended format of the last successful import. Ignored if set
|
|
943
|
+
x-updatable: false
|
|
944
|
+
status:
|
|
945
|
+
type: string
|
|
946
|
+
description: System defined status of the crypto asset. Ignored if set
|
|
947
|
+
enum:
|
|
948
|
+
- active
|
|
949
|
+
- unsupported
|
|
950
|
+
- relink
|
|
951
|
+
- initializing
|
|
952
|
+
x-updatable: false
|
|
953
|
+
created_by_name:
|
|
954
|
+
type: string
|
|
955
|
+
nullable: true
|
|
956
|
+
description: System defined name of the user who created the crypto asset. Ignored if set
|
|
957
|
+
x-updatable: false
|
|
958
|
+
created_at:
|
|
959
|
+
type: string
|
|
960
|
+
format: date-time
|
|
961
|
+
description: System defined date/time the crypto asset was created in ISO 8601 extended format. Ignored if set
|
|
962
|
+
x-updatable: false
|
|
963
|
+
updated_at:
|
|
964
|
+
type: string
|
|
965
|
+
format: date-time
|
|
966
|
+
description: System defined date/time the crypto asset was last updated in ISO 8601 extended format. Ignored if set
|
|
967
|
+
x-updatable: false
|
|
968
|
+
description: Update a manual crypto balance. System-defined properties are accepted but ignored
|
|
969
|
+
|
|
970
|
+
|
|
625
971
|
# The object containing information about a manual account
|
|
626
972
|
manualAccountObject:
|
|
627
973
|
type: object
|
|
@@ -4461,7 +4807,7 @@ paths:
|
|
|
4461
4807
|
example:
|
|
4462
4808
|
message: Not Found
|
|
4463
4809
|
errors:
|
|
4464
|
-
- errMsg: There is no category with the id:
|
|
4810
|
+
- errMsg: "There is no category with the id: 543210."
|
|
4465
4811
|
"429":
|
|
4466
4812
|
$ref: "#/components/responses/rateLimited"
|
|
4467
4813
|
"500":
|
|
@@ -4621,7 +4967,7 @@ paths:
|
|
|
4621
4967
|
example:
|
|
4622
4968
|
message: Not Found
|
|
4623
4969
|
errors:
|
|
4624
|
-
- errMsg: There is no category with the id:
|
|
4970
|
+
- errMsg: "There is no category with the id: 543210."
|
|
4625
4971
|
"429":
|
|
4626
4972
|
$ref: "#/components/responses/rateLimited"
|
|
4627
4973
|
"500":
|
|
@@ -4676,9 +5022,9 @@ paths:
|
|
|
4676
5022
|
example:
|
|
4677
5023
|
message: Not Found
|
|
4678
5024
|
errors:
|
|
4679
|
-
- errMsg: There is no category with the id:
|
|
5025
|
+
- errMsg: "There is no category with the id: 543210."
|
|
4680
5026
|
"422":
|
|
4681
|
-
description: Unprocessable
|
|
5027
|
+
description: Unprocessable Content
|
|
4682
5028
|
content:
|
|
4683
5029
|
application/json:
|
|
4684
5030
|
schema:
|
|
@@ -4710,46 +5056,648 @@ paths:
|
|
|
4710
5056
|
$ref: "#/components/responses/rateLimited"
|
|
4711
5057
|
"500":
|
|
4712
5058
|
$ref: "#/components/responses/serverError"
|
|
4713
|
-
/
|
|
5059
|
+
/crypto:
|
|
4714
5060
|
get:
|
|
4715
5061
|
tags:
|
|
4716
|
-
-
|
|
4717
|
-
summary: Get all
|
|
4718
|
-
description: Retrieve
|
|
4719
|
-
|
|
4720
|
-
operationId: getAllManualAccounts
|
|
5062
|
+
- crypto
|
|
5063
|
+
summary: Get all crypto balances
|
|
5064
|
+
description: Retrieve all crypto balances associated with the user's account, including both manual and synced sources.
|
|
5065
|
+
operationId: getAllCrypto
|
|
4721
5066
|
responses:
|
|
4722
5067
|
"200":
|
|
4723
|
-
description: A list of
|
|
5068
|
+
description: A list of crypto balances
|
|
4724
5069
|
content:
|
|
4725
5070
|
application/json:
|
|
4726
5071
|
schema:
|
|
4727
|
-
|
|
4728
|
-
properties:
|
|
4729
|
-
manual_accounts:
|
|
4730
|
-
type: array
|
|
4731
|
-
items:
|
|
4732
|
-
$ref: "#/components/schemas/manualAccountObject"
|
|
5072
|
+
$ref: "#/components/schemas/cryptoListResponseObject"
|
|
4733
5073
|
example:
|
|
4734
|
-
|
|
4735
|
-
- id:
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
display_name:
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
to_base:
|
|
4744
|
-
balance_as_of: "
|
|
5074
|
+
crypto:
|
|
5075
|
+
- id: 22001
|
|
5076
|
+
source: manual
|
|
5077
|
+
name: Cold Wallet BTC
|
|
5078
|
+
display_name: Long-term BTC
|
|
5079
|
+
institution_name: Ledger
|
|
5080
|
+
balance: "0.852341920145782301"
|
|
5081
|
+
currency: btc
|
|
5082
|
+
coingecko_id: bitcoin
|
|
5083
|
+
to_base: 53124.72
|
|
5084
|
+
balance_as_of: "2026-02-25T14:22:10.000Z"
|
|
5085
|
+
last_import: null
|
|
4745
5086
|
status: active
|
|
4746
|
-
closed_on: null
|
|
4747
|
-
external_id: null
|
|
4748
|
-
exclude_from_transactions: false
|
|
4749
5087
|
created_by_name: User 1
|
|
4750
|
-
created_at: "2025-
|
|
4751
|
-
updated_at: "
|
|
4752
|
-
- id:
|
|
5088
|
+
created_at: "2025-11-12T20:14:32.000Z"
|
|
5089
|
+
updated_at: "2026-02-25T14:22:10.000Z"
|
|
5090
|
+
- id: 33004
|
|
5091
|
+
source: synced
|
|
5092
|
+
name: ETH
|
|
5093
|
+
display_name: Coinbase Main
|
|
5094
|
+
institution_name: Coinbase
|
|
5095
|
+
balance: "12.004500000000000000"
|
|
5096
|
+
currency: eth
|
|
5097
|
+
coingecko_id: ethereum
|
|
5098
|
+
to_base: 28998.44
|
|
5099
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5100
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5101
|
+
status: active
|
|
5102
|
+
created_by_name: User 1
|
|
5103
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5104
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5105
|
+
"401":
|
|
5106
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5107
|
+
"429":
|
|
5108
|
+
$ref: "#/components/responses/rateLimited"
|
|
5109
|
+
"500":
|
|
5110
|
+
$ref: "#/components/responses/serverError"
|
|
5111
|
+
/crypto/manual:
|
|
5112
|
+
get:
|
|
5113
|
+
tags:
|
|
5114
|
+
- crypto
|
|
5115
|
+
summary: Get all manual crypto balances
|
|
5116
|
+
description: Retrieve all manually managed crypto balances associated with the user's account.
|
|
5117
|
+
operationId: getAllCryptoManual
|
|
5118
|
+
responses:
|
|
5119
|
+
"200":
|
|
5120
|
+
description: A list of manual crypto balances
|
|
5121
|
+
content:
|
|
5122
|
+
application/json:
|
|
5123
|
+
schema:
|
|
5124
|
+
$ref: "#/components/schemas/cryptoManualListResponseObject"
|
|
5125
|
+
example:
|
|
5126
|
+
crypto_manual:
|
|
5127
|
+
- id: 22001
|
|
5128
|
+
source: manual
|
|
5129
|
+
name: Cold Wallet BTC
|
|
5130
|
+
display_name: Long-term BTC
|
|
5131
|
+
institution_name: Ledger
|
|
5132
|
+
balance: "0.852341920145782301"
|
|
5133
|
+
currency: btc
|
|
5134
|
+
coingecko_id: bitcoin
|
|
5135
|
+
to_base: 53124.72
|
|
5136
|
+
balance_as_of: "2026-02-25T14:22:10.000Z"
|
|
5137
|
+
last_import: null
|
|
5138
|
+
status: active
|
|
5139
|
+
created_by_name: User 1
|
|
5140
|
+
created_at: "2025-11-12T20:14:32.000Z"
|
|
5141
|
+
updated_at: "2026-02-25T14:22:10.000Z"
|
|
5142
|
+
"401":
|
|
5143
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5144
|
+
"429":
|
|
5145
|
+
$ref: "#/components/responses/rateLimited"
|
|
5146
|
+
"500":
|
|
5147
|
+
$ref: "#/components/responses/serverError"
|
|
5148
|
+
post:
|
|
5149
|
+
tags:
|
|
5150
|
+
- crypto
|
|
5151
|
+
summary: Create a manual crypto balance
|
|
5152
|
+
description: Create a manually managed crypto asset.
|
|
5153
|
+
operationId: createCryptoManual
|
|
5154
|
+
requestBody:
|
|
5155
|
+
required: true
|
|
5156
|
+
content:
|
|
5157
|
+
application/json:
|
|
5158
|
+
schema:
|
|
5159
|
+
$ref: "#/components/schemas/createCryptoManualRequestObject"
|
|
5160
|
+
examples:
|
|
5161
|
+
minimum request body:
|
|
5162
|
+
summary: Minimum required fields
|
|
5163
|
+
value:
|
|
5164
|
+
name: Cold Wallet BTC
|
|
5165
|
+
balance: "0.852341920145782301"
|
|
5166
|
+
currency: btc
|
|
5167
|
+
coingecko_id: bitcoin
|
|
5168
|
+
full request body:
|
|
5169
|
+
summary: Full example with optional display fields
|
|
5170
|
+
value:
|
|
5171
|
+
name: Coinbase ETH Holdings
|
|
5172
|
+
display_name: Trading ETH
|
|
5173
|
+
institution_name: Coinbase
|
|
5174
|
+
balance: "12.004500000000000000"
|
|
5175
|
+
currency: eth
|
|
5176
|
+
coingecko_id: ethereum
|
|
5177
|
+
responses:
|
|
5178
|
+
"201":
|
|
5179
|
+
description: Manual crypto balance created successfully
|
|
5180
|
+
content:
|
|
5181
|
+
application/json:
|
|
5182
|
+
schema:
|
|
5183
|
+
$ref: "#/components/schemas/cryptoManualObject"
|
|
5184
|
+
example:
|
|
5185
|
+
id: 22045
|
|
5186
|
+
source: manual
|
|
5187
|
+
name: Coinbase ETH Holdings
|
|
5188
|
+
display_name: Trading ETH
|
|
5189
|
+
institution_name: Coinbase
|
|
5190
|
+
balance: "12.004500000000000000"
|
|
5191
|
+
currency: eth
|
|
5192
|
+
coingecko_id: ethereum
|
|
5193
|
+
to_base: 28998.44
|
|
5194
|
+
balance_as_of: "2026-03-01T09:20:41.000Z"
|
|
5195
|
+
last_import: null
|
|
5196
|
+
status: active
|
|
5197
|
+
created_by_name: User 1
|
|
5198
|
+
created_at: "2026-03-01T09:20:41.000Z"
|
|
5199
|
+
updated_at: "2026-03-01T09:20:41.000Z"
|
|
5200
|
+
"400":
|
|
5201
|
+
description: Invalid request body
|
|
5202
|
+
content:
|
|
5203
|
+
application/json:
|
|
5204
|
+
schema:
|
|
5205
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5206
|
+
examples:
|
|
5207
|
+
missing required properties:
|
|
5208
|
+
value:
|
|
5209
|
+
message: Request Validation Failure
|
|
5210
|
+
errors:
|
|
5211
|
+
- errMsg: "Missing required property 'name' in request body."
|
|
5212
|
+
- errMsg: "Missing required property 'balance' in request body."
|
|
5213
|
+
- errMsg: "Missing required property 'currency' in request body."
|
|
5214
|
+
- errMsg: "Missing required property 'coingecko_id' in request body."
|
|
5215
|
+
"401":
|
|
5216
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5217
|
+
"429":
|
|
5218
|
+
$ref: "#/components/responses/rateLimited"
|
|
5219
|
+
"500":
|
|
5220
|
+
$ref: "#/components/responses/serverError"
|
|
5221
|
+
/crypto/manual/{id}:
|
|
5222
|
+
get:
|
|
5223
|
+
tags:
|
|
5224
|
+
- crypto
|
|
5225
|
+
summary: Get a single manual crypto balance
|
|
5226
|
+
description: Retrieve a single manually managed crypto balance by ID.
|
|
5227
|
+
operationId: getCryptoManualById
|
|
5228
|
+
parameters:
|
|
5229
|
+
- name: id
|
|
5230
|
+
in: path
|
|
5231
|
+
description: ID of the manual crypto balance to retrieve
|
|
5232
|
+
required: true
|
|
5233
|
+
schema:
|
|
5234
|
+
type: integer
|
|
5235
|
+
format: int32
|
|
5236
|
+
examples:
|
|
5237
|
+
existing manual crypto:
|
|
5238
|
+
summary: Existing manual crypto ID
|
|
5239
|
+
value: 22001
|
|
5240
|
+
id not found:
|
|
5241
|
+
summary: Example of an id that doesn't exist
|
|
5242
|
+
value: 99999999
|
|
5243
|
+
responses:
|
|
5244
|
+
"200":
|
|
5245
|
+
description: Manual crypto balance object
|
|
5246
|
+
content:
|
|
5247
|
+
application/json:
|
|
5248
|
+
schema:
|
|
5249
|
+
$ref: "#/components/schemas/cryptoManualObject"
|
|
5250
|
+
example:
|
|
5251
|
+
id: 22001
|
|
5252
|
+
source: manual
|
|
5253
|
+
name: Cold Wallet BTC
|
|
5254
|
+
display_name: Long-term BTC
|
|
5255
|
+
institution_name: Ledger
|
|
5256
|
+
balance: "0.852341920145782301"
|
|
5257
|
+
currency: btc
|
|
5258
|
+
coingecko_id: bitcoin
|
|
5259
|
+
to_base: 53124.72
|
|
5260
|
+
balance_as_of: "2026-02-25T14:22:10.000Z"
|
|
5261
|
+
last_import: null
|
|
5262
|
+
status: active
|
|
5263
|
+
created_by_name: User 1
|
|
5264
|
+
created_at: "2025-11-12T20:14:32.000Z"
|
|
5265
|
+
updated_at: "2026-02-25T14:22:10.000Z"
|
|
5266
|
+
"400":
|
|
5267
|
+
description: Bad Request
|
|
5268
|
+
content:
|
|
5269
|
+
application/json:
|
|
5270
|
+
schema:
|
|
5271
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5272
|
+
example:
|
|
5273
|
+
message: Invalid Path Parameters
|
|
5274
|
+
errors:
|
|
5275
|
+
- errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'."
|
|
5276
|
+
"401":
|
|
5277
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5278
|
+
"404":
|
|
5279
|
+
description: Not Found
|
|
5280
|
+
content:
|
|
5281
|
+
application/json:
|
|
5282
|
+
schema:
|
|
5283
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5284
|
+
example:
|
|
5285
|
+
message: Not Found
|
|
5286
|
+
errors:
|
|
5287
|
+
- errMsg: "There is no manual crypto balance with the id: 99999999."
|
|
5288
|
+
"429":
|
|
5289
|
+
$ref: "#/components/responses/rateLimited"
|
|
5290
|
+
"500":
|
|
5291
|
+
$ref: "#/components/responses/serverError"
|
|
5292
|
+
put:
|
|
5293
|
+
tags:
|
|
5294
|
+
- crypto
|
|
5295
|
+
summary: Update a manual crypto balance
|
|
5296
|
+
description: >-
|
|
5297
|
+
Modify a manually managed crypto balance.<br><br>
|
|
5298
|
+
|
|
5299
|
+
You may submit the response from `GET /crypto/manual/{id}` as the request body. System-defined properties
|
|
5300
|
+
are accepted and ignored according to the `x-updatable` metadata in the update schema.
|
|
5301
|
+
operationId: updateCryptoManual
|
|
5302
|
+
parameters:
|
|
5303
|
+
- name: id
|
|
5304
|
+
in: path
|
|
5305
|
+
description: ID of the manual crypto balance to update
|
|
5306
|
+
required: true
|
|
5307
|
+
schema:
|
|
5308
|
+
type: integer
|
|
5309
|
+
format: int32
|
|
5310
|
+
examples:
|
|
5311
|
+
existing manual crypto:
|
|
5312
|
+
summary: Existing manual crypto ID
|
|
5313
|
+
value: 22001
|
|
5314
|
+
id not found:
|
|
5315
|
+
summary: Example of an id that doesn't exist
|
|
5316
|
+
value: 99999999
|
|
5317
|
+
requestBody:
|
|
5318
|
+
required: true
|
|
5319
|
+
content:
|
|
5320
|
+
application/json:
|
|
5321
|
+
schema:
|
|
5322
|
+
$ref: "#/components/schemas/updateCryptoManualRequestObject"
|
|
5323
|
+
examples:
|
|
5324
|
+
minimum request body:
|
|
5325
|
+
summary: Update balance only
|
|
5326
|
+
value:
|
|
5327
|
+
balance: "0.900000000000000000"
|
|
5328
|
+
full get response body:
|
|
5329
|
+
summary: Full object payload with system fields tolerated
|
|
5330
|
+
value:
|
|
5331
|
+
id: 22001
|
|
5332
|
+
source: manual
|
|
5333
|
+
name: Cold Wallet BTC
|
|
5334
|
+
display_name: Long-term BTC
|
|
5335
|
+
institution_name: Ledger
|
|
5336
|
+
balance: "0.900000000000000000"
|
|
5337
|
+
currency: btc
|
|
5338
|
+
coingecko_id: bitcoin
|
|
5339
|
+
to_base: 56011.12
|
|
5340
|
+
balance_as_of: "2026-03-01T09:41:18.000Z"
|
|
5341
|
+
last_import: null
|
|
5342
|
+
status: active
|
|
5343
|
+
created_by_name: User 1
|
|
5344
|
+
created_at: "2025-11-12T20:14:32.000Z"
|
|
5345
|
+
updated_at: "2026-02-25T14:22:10.000Z"
|
|
5346
|
+
responses:
|
|
5347
|
+
"200":
|
|
5348
|
+
description: Manual crypto balance updated successfully
|
|
5349
|
+
content:
|
|
5350
|
+
application/json:
|
|
5351
|
+
schema:
|
|
5352
|
+
$ref: "#/components/schemas/cryptoManualObject"
|
|
5353
|
+
example:
|
|
5354
|
+
id: 22001
|
|
5355
|
+
source: manual
|
|
5356
|
+
name: Cold Wallet BTC
|
|
5357
|
+
display_name: Long-term BTC
|
|
5358
|
+
institution_name: Ledger
|
|
5359
|
+
balance: "0.900000000000000000"
|
|
5360
|
+
currency: btc
|
|
5361
|
+
coingecko_id: bitcoin
|
|
5362
|
+
to_base: 56011.12
|
|
5363
|
+
balance_as_of: "2026-03-01T09:41:18.000Z"
|
|
5364
|
+
last_import: null
|
|
5365
|
+
status: active
|
|
5366
|
+
created_by_name: User 1
|
|
5367
|
+
created_at: "2025-11-12T20:14:32.000Z"
|
|
5368
|
+
updated_at: "2026-03-01T09:41:18.000Z"
|
|
5369
|
+
"400":
|
|
5370
|
+
description: Bad Request
|
|
5371
|
+
content:
|
|
5372
|
+
application/json:
|
|
5373
|
+
schema:
|
|
5374
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5375
|
+
examples:
|
|
5376
|
+
missing updatable properties:
|
|
5377
|
+
value:
|
|
5378
|
+
message: Invalid Request Body
|
|
5379
|
+
errors:
|
|
5380
|
+
- errMsg: "A request to update a manual crypto balance must include at least one updatable property: name, display_name, institution_name, balance"
|
|
5381
|
+
"401":
|
|
5382
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5383
|
+
"404":
|
|
5384
|
+
description: Not Found
|
|
5385
|
+
content:
|
|
5386
|
+
application/json:
|
|
5387
|
+
schema:
|
|
5388
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5389
|
+
example:
|
|
5390
|
+
message: Not Found
|
|
5391
|
+
errors:
|
|
5392
|
+
- errMsg: "There is no manual crypto balance with the id: 99999999."
|
|
5393
|
+
"429":
|
|
5394
|
+
$ref: "#/components/responses/rateLimited"
|
|
5395
|
+
"500":
|
|
5396
|
+
$ref: "#/components/responses/serverError"
|
|
5397
|
+
delete:
|
|
5398
|
+
tags:
|
|
5399
|
+
- crypto
|
|
5400
|
+
summary: Delete a manual crypto balance
|
|
5401
|
+
description: Delete a single manually managed crypto asset by ID.<p>
|
|
5402
|
+
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`.
|
|
5403
|
+
operationId: deleteCryptoManual
|
|
5404
|
+
parameters:
|
|
5405
|
+
- name: id
|
|
5406
|
+
in: path
|
|
5407
|
+
description: ID of the manual crypto balance to delete
|
|
5408
|
+
required: true
|
|
5409
|
+
schema:
|
|
5410
|
+
type: integer
|
|
5411
|
+
format: int32
|
|
5412
|
+
examples:
|
|
5413
|
+
existing manual crypto:
|
|
5414
|
+
summary: Existing manual crypto ID
|
|
5415
|
+
value: 22001
|
|
5416
|
+
id not found:
|
|
5417
|
+
summary: Example of an id that doesn't exist
|
|
5418
|
+
value: 99999999
|
|
5419
|
+
- name: keep_history
|
|
5420
|
+
in: query
|
|
5421
|
+
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.
|
|
5422
|
+
required: false
|
|
5423
|
+
schema:
|
|
5424
|
+
type: boolean
|
|
5425
|
+
responses:
|
|
5426
|
+
"204":
|
|
5427
|
+
description: No Content. The crypto asset has been deleted.
|
|
5428
|
+
"401":
|
|
5429
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5430
|
+
"404":
|
|
5431
|
+
description: Not Found
|
|
5432
|
+
content:
|
|
5433
|
+
application/json:
|
|
5434
|
+
schema:
|
|
5435
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5436
|
+
example:
|
|
5437
|
+
message: Not Found
|
|
5438
|
+
errors:
|
|
5439
|
+
- errMsg: "There is no manual crypto balance with the id: 99999999."
|
|
5440
|
+
"422":
|
|
5441
|
+
description: Unprocessable Content
|
|
5442
|
+
content:
|
|
5443
|
+
application/json:
|
|
5444
|
+
schema:
|
|
5445
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5446
|
+
example:
|
|
5447
|
+
message: Explicit confirmation required
|
|
5448
|
+
errors:
|
|
5449
|
+
- errMsg: This crypto manual account has existing balance history. To delete this account, you must explicitly set keep_history to true or false.
|
|
5450
|
+
crypto_manual_id: 22001
|
|
5451
|
+
has_balance_history: true
|
|
5452
|
+
required_parameter: keep_history
|
|
5453
|
+
allowed_values:
|
|
5454
|
+
- true
|
|
5455
|
+
- false
|
|
5456
|
+
"429":
|
|
5457
|
+
$ref: "#/components/responses/rateLimited"
|
|
5458
|
+
"500":
|
|
5459
|
+
$ref: "#/components/responses/serverError"
|
|
5460
|
+
/crypto/synced:
|
|
5461
|
+
get:
|
|
5462
|
+
tags:
|
|
5463
|
+
- crypto
|
|
5464
|
+
summary: Get all synced crypto balances
|
|
5465
|
+
description: Retrieves the balances for all synced crypto accounts associated with the user's account.
|
|
5466
|
+
operationId: getAllCryptoSynced
|
|
5467
|
+
responses:
|
|
5468
|
+
"200":
|
|
5469
|
+
description: A list of synced crypto balances
|
|
5470
|
+
content:
|
|
5471
|
+
application/json:
|
|
5472
|
+
schema:
|
|
5473
|
+
$ref: "#/components/schemas/cryptoSyncedListResponseObject"
|
|
5474
|
+
example:
|
|
5475
|
+
crypto_synced:
|
|
5476
|
+
- id: 33004
|
|
5477
|
+
source: synced
|
|
5478
|
+
name: ETH
|
|
5479
|
+
display_name: Coinbase Main
|
|
5480
|
+
institution_name: Coinbase
|
|
5481
|
+
balance: "12.004500000000000000"
|
|
5482
|
+
currency: eth
|
|
5483
|
+
coingecko_id: ethereum
|
|
5484
|
+
to_base: 28998.44
|
|
5485
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5486
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5487
|
+
status: active
|
|
5488
|
+
created_by_name: User 1
|
|
5489
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5490
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5491
|
+
- id: 33004
|
|
5492
|
+
source: synced
|
|
5493
|
+
name: BTC
|
|
5494
|
+
display_name: Coinbase Main
|
|
5495
|
+
institution_name: Coinbase
|
|
5496
|
+
balance: "0.100020003000400050"
|
|
5497
|
+
currency: btc
|
|
5498
|
+
coingecko_id: bitcoin
|
|
5499
|
+
to_base: 6231.28
|
|
5500
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5501
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5502
|
+
status: active
|
|
5503
|
+
created_by_name: User 1
|
|
5504
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5505
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5506
|
+
"401":
|
|
5507
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5508
|
+
"429":
|
|
5509
|
+
$ref: "#/components/responses/rateLimited"
|
|
5510
|
+
"500":
|
|
5511
|
+
$ref: "#/components/responses/serverError"
|
|
5512
|
+
/crypto/synced/{id}:
|
|
5513
|
+
get:
|
|
5514
|
+
tags:
|
|
5515
|
+
- crypto
|
|
5516
|
+
summary: Get synced crypto balances for a single synced connection
|
|
5517
|
+
description: Retrieves the balances for all currencies connected from the specified synced crypto account ID.
|
|
5518
|
+
operationId: getCryptoSyncedById
|
|
5519
|
+
parameters:
|
|
5520
|
+
- name: id
|
|
5521
|
+
in: path
|
|
5522
|
+
description: Synced crypto account ID
|
|
5523
|
+
required: true
|
|
5524
|
+
schema:
|
|
5525
|
+
type: integer
|
|
5526
|
+
format: int32
|
|
5527
|
+
examples:
|
|
5528
|
+
existing synced connection:
|
|
5529
|
+
summary: Existing synced account ID
|
|
5530
|
+
value: 33004
|
|
5531
|
+
id not found:
|
|
5532
|
+
summary: Example of an id that doesn't exist
|
|
5533
|
+
value: 99999999
|
|
5534
|
+
responses:
|
|
5535
|
+
"200":
|
|
5536
|
+
description: Synced crypto balances for a single synced account
|
|
5537
|
+
content:
|
|
5538
|
+
application/json:
|
|
5539
|
+
schema:
|
|
5540
|
+
$ref: "#/components/schemas/cryptoSyncedListResponseObject"
|
|
5541
|
+
example:
|
|
5542
|
+
crypto_synced:
|
|
5543
|
+
- id: 33004
|
|
5544
|
+
source: synced
|
|
5545
|
+
name: ETH
|
|
5546
|
+
display_name: Coinbase Main
|
|
5547
|
+
institution_name: Coinbase
|
|
5548
|
+
balance: "12.004500000000000000"
|
|
5549
|
+
currency: eth
|
|
5550
|
+
coingecko_id: ethereum
|
|
5551
|
+
to_base: 28998.44
|
|
5552
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5553
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5554
|
+
status: active
|
|
5555
|
+
created_by_name: User 1
|
|
5556
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5557
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5558
|
+
"400":
|
|
5559
|
+
description: Bad Request
|
|
5560
|
+
content:
|
|
5561
|
+
application/json:
|
|
5562
|
+
schema:
|
|
5563
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5564
|
+
example:
|
|
5565
|
+
message: Invalid Path Parameters
|
|
5566
|
+
errors:
|
|
5567
|
+
- errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'."
|
|
5568
|
+
"401":
|
|
5569
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5570
|
+
"404":
|
|
5571
|
+
description: Not Found
|
|
5572
|
+
content:
|
|
5573
|
+
application/json:
|
|
5574
|
+
schema:
|
|
5575
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5576
|
+
example:
|
|
5577
|
+
message: Not Found
|
|
5578
|
+
errors:
|
|
5579
|
+
- errMsg: "There is no synced crypto connection with the id: 99999999."
|
|
5580
|
+
"429":
|
|
5581
|
+
$ref: "#/components/responses/rateLimited"
|
|
5582
|
+
"500":
|
|
5583
|
+
$ref: "#/components/responses/serverError"
|
|
5584
|
+
/crypto/synced/{id}/refresh:
|
|
5585
|
+
post:
|
|
5586
|
+
tags:
|
|
5587
|
+
- crypto
|
|
5588
|
+
summary: Refresh balances for a synced crypto account
|
|
5589
|
+
description: Trigger a balance refresh for the specified synced crypto account and return provider pass-through results. This payload may use provider/internal field names such as currency_ref.
|
|
5590
|
+
operationId: refreshCryptoSynced
|
|
5591
|
+
parameters:
|
|
5592
|
+
- name: id
|
|
5593
|
+
in: path
|
|
5594
|
+
description: Synced crypto account ID
|
|
5595
|
+
required: true
|
|
5596
|
+
schema:
|
|
5597
|
+
type: integer
|
|
5598
|
+
format: int32
|
|
5599
|
+
examples:
|
|
5600
|
+
existing synced connection:
|
|
5601
|
+
summary: Existing synced account ID
|
|
5602
|
+
value: 33004
|
|
5603
|
+
id not found:
|
|
5604
|
+
summary: Example of an id that doesn't exist
|
|
5605
|
+
value: 99999999
|
|
5606
|
+
responses:
|
|
5607
|
+
"200":
|
|
5608
|
+
description: Refreshed balances for the synced crypto account
|
|
5609
|
+
content:
|
|
5610
|
+
application/json:
|
|
5611
|
+
schema:
|
|
5612
|
+
$ref: "#/components/schemas/cryptoSyncedListResponseObject"
|
|
5613
|
+
example:
|
|
5614
|
+
crypto_synced:
|
|
5615
|
+
- id: 33004
|
|
5616
|
+
source: synced
|
|
5617
|
+
name: ETH
|
|
5618
|
+
display_name: Coinbase Main
|
|
5619
|
+
institution_name: Coinbase
|
|
5620
|
+
balance: "12.004500000000000000"
|
|
5621
|
+
currency: eth
|
|
5622
|
+
coingecko_id: ethereum
|
|
5623
|
+
to_base: 28998.44
|
|
5624
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5625
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5626
|
+
status: active
|
|
5627
|
+
created_by_name: User 1
|
|
5628
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5629
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5630
|
+
- id: 33004
|
|
5631
|
+
source: synced
|
|
5632
|
+
name: BTC
|
|
5633
|
+
display_name: Coinbase Main
|
|
5634
|
+
institution_name: Coinbase
|
|
5635
|
+
balance: "0.100020003000400050"
|
|
5636
|
+
currency: btc
|
|
5637
|
+
coingecko_id: bitcoin
|
|
5638
|
+
to_base: 6231.28
|
|
5639
|
+
balance_as_of: "2026-02-25T14:25:00.000Z"
|
|
5640
|
+
last_import: "2026-02-25T14:25:01.000Z"
|
|
5641
|
+
status: active
|
|
5642
|
+
created_by_name: User 1
|
|
5643
|
+
created_at: "2025-10-02T11:02:09.000Z"
|
|
5644
|
+
updated_at: "2026-02-25T14:25:01.000Z"
|
|
5645
|
+
"401":
|
|
5646
|
+
$ref: "#/components/responses/unauthorizedToken"
|
|
5647
|
+
"404":
|
|
5648
|
+
description: Not Found
|
|
5649
|
+
content:
|
|
5650
|
+
application/json:
|
|
5651
|
+
schema:
|
|
5652
|
+
$ref: "#/components/schemas/errorResponseObject"
|
|
5653
|
+
example:
|
|
5654
|
+
message: Not Found
|
|
5655
|
+
errors:
|
|
5656
|
+
- errMsg: "There is no synced crypto connection with the id: 99999999."
|
|
5657
|
+
"429":
|
|
5658
|
+
$ref: "#/components/responses/rateLimited"
|
|
5659
|
+
"500":
|
|
5660
|
+
$ref: "#/components/responses/serverError"
|
|
5661
|
+
/manual_accounts:
|
|
5662
|
+
get:
|
|
5663
|
+
tags:
|
|
5664
|
+
- manual_accounts
|
|
5665
|
+
summary: Get all manual accounts
|
|
5666
|
+
description: Retrieve a list of all manually-managed accounts associated with
|
|
5667
|
+
the user's account.
|
|
5668
|
+
operationId: getAllManualAccounts
|
|
5669
|
+
responses:
|
|
5670
|
+
"200":
|
|
5671
|
+
description: A list of manual accounts
|
|
5672
|
+
content:
|
|
5673
|
+
application/json:
|
|
5674
|
+
schema:
|
|
5675
|
+
type: object
|
|
5676
|
+
properties:
|
|
5677
|
+
manual_accounts:
|
|
5678
|
+
type: array
|
|
5679
|
+
items:
|
|
5680
|
+
$ref: "#/components/schemas/manualAccountObject"
|
|
5681
|
+
example:
|
|
5682
|
+
manual_accounts:
|
|
5683
|
+
- id: 119807
|
|
5684
|
+
name: Individual Brokerage
|
|
5685
|
+
institution_name: Fidelity
|
|
5686
|
+
display_name: null
|
|
5687
|
+
type: investment
|
|
5688
|
+
subtype: brokerage
|
|
5689
|
+
balance: "41211.8000"
|
|
5690
|
+
currency: usd
|
|
5691
|
+
to_base: 41211.8
|
|
5692
|
+
balance_as_of: "2025-06-25T17:00:04.000Z"
|
|
5693
|
+
status: active
|
|
5694
|
+
closed_on: null
|
|
5695
|
+
external_id: null
|
|
5696
|
+
exclude_from_transactions: false
|
|
5697
|
+
created_by_name: User 1
|
|
5698
|
+
created_at: "2025-06-25T17:00:04.414Z"
|
|
5699
|
+
updated_at: "2025-06-26T19:03:38.312Z"
|
|
5700
|
+
- id: 119909
|
|
4753
5701
|
name: Euro Travel Card
|
|
4754
5702
|
institution_name: WeBank
|
|
4755
5703
|
display_name: null
|
|
@@ -5139,7 +6087,7 @@ paths:
|
|
|
5139
6087
|
example:
|
|
5140
6088
|
message: Not Found
|
|
5141
6089
|
errors:
|
|
5142
|
-
- errMsg: There is no manual account with the id:
|
|
6090
|
+
- errMsg: "There is no manual account with the id: 543210."
|
|
5143
6091
|
"429":
|
|
5144
6092
|
$ref: "#/components/responses/rateLimited"
|
|
5145
6093
|
"500":
|
|
@@ -5196,7 +6144,7 @@ paths:
|
|
|
5196
6144
|
example:
|
|
5197
6145
|
message: Not Found
|
|
5198
6146
|
errors:
|
|
5199
|
-
- errMsg: There is no manual account with the id:
|
|
6147
|
+
- errMsg: "There is no manual account with the id: 543210."
|
|
5200
6148
|
"429":
|
|
5201
6149
|
$ref: "#/components/responses/rateLimited"
|
|
5202
6150
|
"500":
|
|
@@ -6358,7 +7306,7 @@ paths:
|
|
|
6358
7306
|
examples:
|
|
6359
7307
|
invalid ids in new transactions:
|
|
6360
7308
|
value:
|
|
6361
|
-
message:
|
|
7309
|
+
message: Request Validation Failure
|
|
6362
7310
|
errors:
|
|
6363
7311
|
- errMsg: "transactions[0] manual account ID does not exist: 9999999"
|
|
6364
7312
|
transaction_index: 0
|
|
@@ -6377,7 +7325,7 @@ paths:
|
|
|
6377
7325
|
recurring_id: 88888888
|
|
6378
7326
|
duplicate external_ids within request:
|
|
6379
7327
|
value:
|
|
6380
|
-
message:
|
|
7328
|
+
message: Request Validation Failure
|
|
6381
7329
|
errors:
|
|
6382
7330
|
- errMsg: Duplicate External IDs found in the request body
|
|
6383
7331
|
error: Duplicate External ID
|
|
@@ -6653,7 +7601,7 @@ paths:
|
|
|
6653
7601
|
examples:
|
|
6654
7602
|
invalid ids in id list:
|
|
6655
7603
|
value:
|
|
6656
|
-
message:
|
|
7604
|
+
message: Request Validation Failure
|
|
6657
7605
|
errors:
|
|
6658
7606
|
- errMsg: "transactions[0] manual account ID does not exist: 999999999"
|
|
6659
7607
|
transaction_index: 0
|
|
@@ -6672,7 +7620,7 @@ paths:
|
|
|
6672
7620
|
recurring_id: 888888888
|
|
6673
7621
|
update with errors:
|
|
6674
7622
|
value:
|
|
6675
|
-
message:
|
|
7623
|
+
message: Request Validation Failure
|
|
6676
7624
|
errors:
|
|
6677
7625
|
- errMsg: "There is no transaction with the id: 9999999"
|
|
6678
7626
|
error: Invalid Transaction ID
|
|
@@ -6730,7 +7678,7 @@ paths:
|
|
|
6730
7678
|
locked_property: amount
|
|
6731
7679
|
duplicate external_ids within request:
|
|
6732
7680
|
value:
|
|
6733
|
-
message:
|
|
7681
|
+
message: Request Validation Failure
|
|
6734
7682
|
errors:
|
|
6735
7683
|
- errMsg: Duplicate External IDs found in the request body
|
|
6736
7684
|
error: Duplicate External ID
|
|
@@ -6748,7 +7696,7 @@ paths:
|
|
|
6748
7696
|
- 3
|
|
6749
7697
|
invalid ids:
|
|
6750
7698
|
value:
|
|
6751
|
-
message:
|
|
7699
|
+
message: Request Validation Failure
|
|
6752
7700
|
errors:
|
|
6753
7701
|
- errMsg: "There is no transaction with the id: 1"
|
|
6754
7702
|
error: Invalid Transaction ID
|
|
@@ -7117,7 +8065,7 @@ paths:
|
|
|
7117
8065
|
example:
|
|
7118
8066
|
message: Not Found
|
|
7119
8067
|
errors:
|
|
7120
|
-
- errMsg: There is no transaction with the id:
|
|
8068
|
+
- errMsg: "There is no transaction with the id: 543210."
|
|
7121
8069
|
"429":
|
|
7122
8070
|
$ref: "#/components/responses/rateLimited"
|
|
7123
8071
|
"500":
|
|
@@ -7256,7 +8204,7 @@ paths:
|
|
|
7256
8204
|
example:
|
|
7257
8205
|
message: Not Found
|
|
7258
8206
|
errors:
|
|
7259
|
-
- errMsg: There is no transaction with the id:
|
|
8207
|
+
- errMsg: "There is no transaction with the id: 543210."
|
|
7260
8208
|
"429":
|
|
7261
8209
|
$ref: "#/components/responses/rateLimited"
|
|
7262
8210
|
"500":
|
|
@@ -7309,7 +8257,7 @@ paths:
|
|
|
7309
8257
|
example:
|
|
7310
8258
|
message: Not Found
|
|
7311
8259
|
errors:
|
|
7312
|
-
- errMsg: There is no transaction with the id:
|
|
8260
|
+
- errMsg: "There is no transaction with the id: 543210."
|
|
7313
8261
|
"429":
|
|
7314
8262
|
$ref: "#/components/responses/rateLimited"
|
|
7315
8263
|
"500":
|
|
@@ -7830,30 +8778,30 @@ paths:
|
|
|
7830
8778
|
examples:
|
|
7831
8779
|
bad math:
|
|
7832
8780
|
value:
|
|
7833
|
-
message:
|
|
8781
|
+
message: Request Validation Failure
|
|
7834
8782
|
errors:
|
|
7835
|
-
- errMsg:
|
|
7836
|
-
amount!
|
|
8783
|
+
- errMsg: Sum of split transactions do not add up to the original transaction amount.
|
|
7837
8784
|
split recurring:
|
|
7838
8785
|
value:
|
|
7839
|
-
message:
|
|
8786
|
+
message: Request Validation Failure
|
|
7840
8787
|
errors:
|
|
7841
|
-
- errMsg: You cannot split a recurring transaction
|
|
8788
|
+
- errMsg: You cannot split a recurring transaction.
|
|
8789
|
+
id: 2112150655
|
|
7842
8790
|
split group:
|
|
7843
8791
|
value:
|
|
7844
|
-
message:
|
|
8792
|
+
message: Request Validation Failure
|
|
7845
8793
|
errors:
|
|
7846
|
-
- errMsg: You cannot split a
|
|
8794
|
+
- errMsg: You cannot split a group transaction. Ungroup it before splitting.
|
|
7847
8795
|
split split:
|
|
7848
8796
|
value:
|
|
7849
|
-
message:
|
|
8797
|
+
message: Request Validation Failure
|
|
7850
8798
|
errors:
|
|
7851
|
-
- errMsg: You cannot split an already split transaction
|
|
8799
|
+
- errMsg: You cannot split an already split transaction. Unsplit it before splitting again.
|
|
7852
8800
|
missing amount in child transaction:
|
|
7853
8801
|
value:
|
|
7854
8802
|
message: Invalid Request Body
|
|
7855
8803
|
errors:
|
|
7856
|
-
- errMsg: "child_transactions[0] amount
|
|
8804
|
+
- errMsg: "child_transactions[0] is missing required property 'amount' in request body."
|
|
7857
8805
|
child_transactions_index: 0
|
|
7858
8806
|
error: Missing required property
|
|
7859
8807
|
invalid_property: amount
|
|
@@ -8407,9 +9355,9 @@ paths:
|
|
|
8407
9355
|
schema:
|
|
8408
9356
|
$ref: "#/components/schemas/errorResponseObject"
|
|
8409
9357
|
example:
|
|
8410
|
-
message:
|
|
9358
|
+
message: Request Validation Failure
|
|
8411
9359
|
errors:
|
|
8412
|
-
- errMsg: "A request to update a tag must include at least one of the following properties: name, description, archived"
|
|
9360
|
+
- errMsg: "A request to update a tag must include at least one of the following properties: name, description, archived."
|
|
8413
9361
|
"401":
|
|
8414
9362
|
$ref: "#/components/responses/unauthorizedToken"
|
|
8415
9363
|
"404":
|
|
@@ -8421,7 +9369,7 @@ paths:
|
|
|
8421
9369
|
example:
|
|
8422
9370
|
message: Not Found
|
|
8423
9371
|
errors:
|
|
8424
|
-
- errMsg: There is no tag with the id:
|
|
9372
|
+
- errMsg: "There is no tag with the id: 543210."
|
|
8425
9373
|
"429":
|
|
8426
9374
|
$ref: "#/components/responses/rateLimited"
|
|
8427
9375
|
"500":
|
|
@@ -8476,9 +9424,9 @@ paths:
|
|
|
8476
9424
|
example:
|
|
8477
9425
|
message: Not Found
|
|
8478
9426
|
errors:
|
|
8479
|
-
- errMsg: There is no tag with the id:
|
|
9427
|
+
- errMsg: "There is no tag with the id: 543210."
|
|
8480
9428
|
"422":
|
|
8481
|
-
description: Unprocessable
|
|
9429
|
+
description: Unprocessable Content
|
|
8482
9430
|
content:
|
|
8483
9431
|
application/json:
|
|
8484
9432
|
schema:
|
package/package.json
CHANGED
package/version-history.md
CHANGED
|
@@ -5,13 +5,20 @@ The Lunch Money API spec uses a modified version of SEMVER for its versioning me
|
|
|
5
5
|
- The minor version represents the number of main endpoints the current version of the spec supports. For example, a version of the API that supports the /me, /categories, and /transactions endpoints would have a minor version of 3.
|
|
6
6
|
- The revision number represents the number of updates since the last endpoint was added. For example, each time changes are made to one of the existing three APIs as described above, the revision number will be bumped.
|
|
7
7
|
|
|
8
|
+
## v2.10.0 - TBD
|
|
9
|
+
- Add v2 crypto endpoints which support:
|
|
10
|
+
- Managing the complete lifecycle of manually managed crypto assets (create, read, update, delete)
|
|
11
|
+
- Viewing the balances for currencies associated with both manually managed crypto assets and those that are synced via a synced crypto account (ie: coinbase, kraken, ethereum wallet)
|
|
12
|
+
deferred.
|
|
13
|
+
- Refreshing synced crypto account balances
|
|
14
|
+
|
|
8
15
|
## v2.9.0 - Feb 26, 2026
|
|
9
16
|
- Add initial `/budgets` endpoint support:
|
|
10
17
|
- `GET /budgets/settings` for account budget settings
|
|
11
18
|
- `PUT /budgets` to create or update budget amounts
|
|
12
19
|
- `DELETE /budgets` to remove budget amounts
|
|
13
20
|
- Updates the GET `/summary` endpoint to return an `occurrences` array for both aligned and non-aligned summary responses when `include_occurrences=true`.
|
|
14
|
-
- It can be useful to inspect the `start_date` and `end_date` of occurrences in a non-aligned response for use in subsequent requests to get an aligned response which will include complete budget information.
|
|
21
|
+
- It can be useful to inspect the `start_date` and `end_date` of occurrences in a non-aligned response for use in subsequent requests to get an aligned response, which will include complete budget information.
|
|
15
22
|
- Add support for setting `tag_ids` on child transactions in `POST /transactions/split/{id}`.
|
|
16
23
|
|
|
17
24
|
## v2.8.5 - Feb 2, 2026
|
|
@@ -146,7 +153,7 @@ The Lunch Money API spec uses a modified version of SEMVER for its versioning me
|
|
|
146
153
|
- It is also now permissible to include strings in the `children` property. These will be used as the names of new child categories that will be created.
|
|
147
154
|
- This release also updates the following schemas:
|
|
148
155
|
- Correctly specifies that all properties of the manualAccountObject are required
|
|
149
|
-
- Updates the
|
|
156
|
+
- Updates the updateManualAccountObject and updatePlaidManualAccountObject to allow the `balance` property to be either a string or a number.
|
|
150
157
|
- Updates the userObject to include the `debits_as_negative` property. The documentation for Transaction Objects returned by GET requests have been updated to reflect how/if this setting affects the `amount` property of the transaction.
|
|
151
158
|
- Updates the childCategoryObject to restore the `exclude_from_budget`, `exclude_from_totals` and `is_income` properties. These properties are inherited from the Category Group and not settable but are provided for convenience.
|
|
152
159
|
|
|
@@ -346,4 +353,3 @@ This is the initial branch using the versioning described above
|
|
|
346
353
|
- It is the v2 version of the API - hence the major version 2.
|
|
347
354
|
- The API Spec currently supports 3 endpoints /me, /categories, and /transactions. hence the minor version 3.
|
|
348
355
|
- This version of the spec contains minor modifications to the previously published spec and therefore has a revision number 1
|
|
349
|
-
|