@lunch-money/developer-docs 2.11.0-preview.10

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.
@@ -0,0 +1,117 @@
1
+ # v2 API Overview
2
+
3
+ Welcome to the Lunch Money v2 API. This page covers the core concepts you need to work with the API effectively — authentication, response shapes, naming conventions, error handling, and more. If you're migrating from v1, see the [Migration Guide](./migration-guide.md).
4
+
5
+ ## Authentication
6
+
7
+ All API requests require a Bearer token in the `Authorization` header:
8
+
9
+ ```http
10
+ Authorization: Bearer YOUR_ACCESS_TOKEN
11
+ ```
12
+
13
+ Get your access token from the <a href="https://my.lunchmoney.app/developers" target="_blank" rel="noopener noreferrer">Lunch Money developers page</a>. See the [Getting Started guide](/v2/getting-started) for a step-by-step walkthrough including how to create a test budget.
14
+
15
+ ## Base URL
16
+
17
+ ```
18
+ https://api.lunchmoney.dev/v2
19
+ ```
20
+
21
+ ## Response Shapes
22
+
23
+ The v2 API uses consistent HTTP status codes and response bodies across all endpoints.
24
+
25
+ ### Successful responses
26
+
27
+ - **GET** → `200 OK`. Response body contains either a single object or an array property named after the endpoint (e.g., `{ "transactions": [...] }`).
28
+ - **POST** → `201 Created`. Response body contains the complete created object including system-defined properties like `id` and `created_at`.
29
+ - **PUT** → `200 OK`. Response body contains the complete updated object.
30
+ - **DELETE** → `204 No Content`. No response body.
31
+
32
+ ### Error responses
33
+
34
+ All errors return an appropriate 4XX status code — the v2 API never returns an error inside a `200 OK` response.
35
+
36
+ | Code | Meaning |
37
+ |------|---------|
38
+ | `400` | Bad Request — invalid parameters or request body |
39
+ | `401` | Unauthorized — missing or invalid Bearer token |
40
+ | `404` | Not Found — the requested object does not exist |
41
+ | `422` | Unprocessable Content — request is valid but cannot be fulfilled (e.g., deleting a category with dependents) |
42
+ | `429` | Too Many Requests — rate limit exceeded; response includes a `Retry-After` header. See the [Rate Limiting guide](/v2/rate-limits). |
43
+
44
+ All error responses share a consistent body format:
45
+
46
+ ```json
47
+ {
48
+ "message": "Overall error description",
49
+ "errors": [
50
+ { "errMsg": "Specific error about a parameter or field" }
51
+ ]
52
+ }
53
+ ```
54
+
55
+ > [!NOTE] Atomic Operations
56
+ > When a request fails, no part of it is applied to your data. For example, if one transaction in a bulk insert has a validation error, none of the transactions in that request are inserted. Fix the errors and retry — you don't need to worry about partial duplicates.
57
+ >
58
+ > If a request has multiple validation errors, the response will attempt to list as many as possible, but it is not guaranteed to catch all errors in a single response.
59
+
60
+ ### Request validation
61
+
62
+ The v2 API validates all requests strictly. A `400` is returned if the request includes unexpected parameters, missing required fields, fields with invalid values, or unexpected properties in the request body. This makes it easier to catch mistakes during development.
63
+
64
+ ## Naming Conventions
65
+
66
+ Object properties follow consistent rules across the entire API:
67
+
68
+ - Properties that belong to the object itself use simple names: `id`, `name`, `status`
69
+ - Properties that reference related objects include the object type: `category_id`, `tag_ids`, `manual_account_id`
70
+ - Timestamps end in `_at`: `created_at`, `updated_at`, `archived_at`
71
+ - Lists of IDs include the type: `tag_ids` (not `tags`)
72
+ - Child objects of the same type are always in a `children` property
73
+ - All `id` fields are `integer` type (not `number`)
74
+
75
+ ## Amounts, Balances & Sign Convention
76
+
77
+ The v2 API uses a consistent set of properties — `amount`, `balance`, `currency`, and `to_base` — across all objects that deal with money. See the [Amounts & Balances guide](/v2/amounts-and-balances) for a full explanation of how these properties work, including the sign convention and multi-currency support.
78
+
79
+ ## Hydrated vs. Non-Hydrated Responses
80
+
81
+ In v1, some endpoints returned "hydrated" objects — related object details were embedded directly in the response alongside their IDs. For example, a transaction included `category_name`, `asset_name`, and an array of full tag objects.
82
+
83
+ In v2, responses are **non-hydrated**: related objects are returned as IDs only. To get the full details, call the appropriate endpoint with the returned ID.
84
+
85
+ ```javascript
86
+ // v1 — category details embedded in transaction
87
+ { "category_id": 456, "category_name": "Groceries", "is_income": false }
88
+
89
+ // v2 — ID only; fetch separately when needed
90
+ { "category_id": 456 }
91
+ // GET /v2/categories/456 → { "id": 456, "name": "Groceries", ... }
92
+ ```
93
+
94
+ This improves response times and keeps the API consistent. For apps that need related object details frequently, maintaining a local cache of categories, accounts, and tags is the recommended pattern.
95
+
96
+ ## Updating Objects (PUT)
97
+
98
+ Most objects in the v2 API are updatable via `PUT /endpoint/{id}`. The rules are consistent:
99
+
100
+ - Request bodies may contain any mix of **user-definable** properties (will be updated) and **system-defined** properties like `id` or `created_at` (accepted but ignored).
101
+ - Any unexpected property that is neither user-definable nor system-defined will fail validation and return `400`.
102
+
103
+ > [!WARNING] Overwrite Behavior
104
+ > Complex properties — objects and arrays — are **replaced entirely** by whatever is in the request body. To add a tag to a transaction without removing existing tags, first fetch the transaction, add the new tag ID to the existing `tag_ids` array, then PUT the full updated array.
105
+
106
+ > [!TIP] Recommended Pattern
107
+ > Because system-defined properties are tolerated in PUT requests, you can safely GET an object, modify the properties you want to change, and PUT the whole thing back without stripping system fields first.
108
+
109
+ ## Versioning
110
+
111
+ The v2 API uses a modified SEMVER scheme:
112
+
113
+ - **Major** (always `2`) — a new major version would only be released for breaking changes
114
+ - **Minor** — the number of top-level endpoint groups currently supported (e.g., a version supporting `/me`, `/categories`, and `/transactions` has minor version `3`)
115
+ - **Revision** — the number of non-breaking updates since the last endpoint group was added
116
+
117
+ The [Version History](/v2/version-history) tracks changes release by release.