{
    "openapi": "3.1.2",
    "info": {
        "title": "Whisper Money API",
        "version": "v1",
        "description": "The Whisper Money REST API: your accounts, transactions and the rest of your data, for Pro users. Authenticate with a personal API token or an OAuth access token granted `api:use`. Amounts are integers in the currency's minor unit. Guides: https://whisper.money/documentation/api"
    },
    "servers": [
        {
            "url": "https://whisper.money/api/v1",
            "description": "Whisper Money"
        }
    ],
    "tags": [
        {
            "name": "Spaces",
            "description": "A space holds a set of accounts and everything recorded on them. Every user has a personal space and may be invited to others. Endpoints that work on one space take an optional `space` parameter, which defaults to the personal space."
        },
        {
            "name": "Accounts",
            "description": "An account is a bookkeeping record of money held somewhere: a manual one you keep up to date yourself, or a bank-connected one the bank sync keeps up to date. Nothing here moves money; that happens at the bank."
        },
        {
            "name": "Balances",
            "description": "A balance is a snapshot of what an account held at the end of one day, in the account currency's minor units. A bank-connected account gets its balances from the bank sync; you record those of a manual account yourself. A credit card has no balance: it has a credit limit, and what is in use of it comes from its transactions."
        },
        {
            "name": "Transactions",
            "description": "A transaction is money that moved in or out of an account: synced from the bank, imported from a file or recorded by hand. Whisper Money only keeps the books: recording a transaction moves no money. Amounts are signed, in the minor units of the transaction's own currency: negative for an expense, positive for income."
        },
        {
            "name": "Categories",
            "description": "A category says what a transaction was for. Each transaction has at most one. Categories form a tree up to 3 levels deep through `parent_id`, and a whole tree shares its root's type and cashflow direction. A budget that tracks a parent category also tracks its children."
        },
        {
            "name": "Labels",
            "description": "A label is a free tag: a transaction can carry any number of them next to its single category. Labels are also how a savings goal counts its contributions, and budgets and automation rules can use them. Names are unique within a space."
        },
        {
            "name": "Automation rules",
            "description": "An automation rule gives a category, labels and a note to the transactions that meet its conditions. Rules are evaluated in `priority` order, lowest first, and a new transaction gets the actions of the first rule it matches and no other. A rule only runs on transactions created after it: run it over the ones already there with the apply endpoint."
        },
        {
            "name": "Budgets",
            "description": "A budget is a spending limit per period over some of your categories and labels. Budgets cover your whole account, not a space, and only ever track your own categories and labels. Amounts are in the minor units of your account's currency, given as `currency`. A budget's period length, start day, rollover and what it tracks are fixed once it is created: to change them, delete the budget and create it again."
        },
        {
            "name": "Savings goals",
            "description": "A savings goal is tracked through a label: its contributions are the transactions tagged with it. A `one_off` goal saves towards a total, optionally by a date. A `monthly` goal starts over every calendar month with a target that is a fixed `amount` or an `income_rate`, a share of the average income of the three previous complete months, frozen when the month opens. A goal's kind is fixed once created. Archiving and deleting goals happen in the Whisper Money app."
        },
        {
            "name": "Analytics",
            "description": "Figures rolled up from your transactions and balances over a date range: cashflow, net worth and spending by category. They cover your whole account, not a space, and every amount is in the minor units of your account's currency, given as `currency`."
        },
        {
            "name": "Achievements",
            "description": "A medal (an achievement) records a milestone you reached: a visit or saving streak, a net worth or savings rate level, transactions recorded, data kept tidy. Medals cover your whole account, not a space."
        }
    ],
    "security": [
        {
            "personalAccessToken": []
        },
        {
            "oauth2": [
                "api:use"
            ]
        }
    ],
    "paths": {
        "/spaces": {
            "get": {
                "operationId": "v1.spaces.index",
                "description": "Every space you can access, your personal space first. You belong to a\nhandful of spaces at most, so the list is returned whole, without\npagination.",
                "summary": "List spaces",
                "tags": [
                    "Spaces"
                ],
                "responses": {
                    "200": {
                        "description": "Array of `Space`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Space"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            }
        },
        "/accounts": {
            "get": {
                "operationId": "v1.accounts.index",
                "description": "Your accounts in a space, newest first, archived ones included. As in\nthe app, another member's accounts are not listed.",
                "summary": "List accounts",
                "tags": [
                    "Accounts"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Account"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.accounts.store",
                "description": "Opens a manual account of any type, optionally with today's balance. A\nloan or a property takes its own details, and given a `balance` too it\ngets the monthly balance history in between generated, the older part\nin the background. A bank-connected account cannot be created here: it\nis only born when you connect your bank in the Whisper Money app, so\n`banking_connection_id`, `external_account_id` and `is_connected` are\nrefused.",
                "summary": "Create an account",
                "tags": [
                    "Accounts"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreAccountRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`Account`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Account"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/accounts/{account}": {
            "get": {
                "operationId": "v1.accounts.show",
                "summary": "Retrieve an account",
                "tags": [
                    "Accounts"
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Account`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Account"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.accounts.update",
                "description": "Changes only the fields you send. On a manual account that is all of\nthem; on a bank-connected one only the name, the type (among\n`checking`, `credit_card`, `savings` and `others`) and the ownership\nfields, since its currency and bank come from the bank. A loan\nwith no details yet needs `annual_interest_rate`, `loan_term_months` and\n`original_amount` together; sending only some of them is a `422` and\nnothing in the request is saved.\n\nChanging a loan or a property to another type keeps its details and any\nmortgage link on file but stops using them. Archiving, hiding and\ndeleting an account happen in the app.",
                "summary": "Update an account",
                "tags": [
                    "Accounts"
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateAccountRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Account`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Account"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/accounts/{account}/balances": {
            "get": {
                "operationId": "v1.accounts.balances.index",
                "description": "The account's balance snapshots, the most recent day first.",
                "summary": "List an account's balances",
                "tags": [
                    "Balances"
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/AccountBalance"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.accounts.balances.store",
                "description": "Records what a manual account held on a day, replacing the snapshot\nalready recorded for that day. Answers `201` when it adds a snapshot and\n`200` when it replaces one. A bank-connected account is refused, since\nthe next sync would overwrite the figure, and so is a credit card, which\nhas no balance; both answer `422` with the error under `account`.",
                "summary": "Record a balance",
                "tags": [
                    "Balances"
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreAccountBalanceRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`AccountBalance`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AccountBalance"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/transactions": {
            "get": {
                "operationId": "v1.transactions.index",
                "description": "Your transactions in a space, the most recent day first, narrowed by\nany of the filters. As in the app, another member's transactions are\nnot listed. A transaction that was split is not listed: its parts are, each with the\nsame `split_parent_id`. To find recurring charges, such as\nsubscriptions, search them and group the results by merchant and\ncadence.",
                "summary": "List transactions",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "query",
                        "in": "query",
                        "description": "Free text matched against the description and the creditor and debtor names.",
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "example": "coffee"
                    },
                    {
                        "name": "account_id",
                        "in": "query",
                        "description": "Only the transactions of this account.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "category_id",
                        "in": "query",
                        "description": "Only the transactions in this category.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "label_ids[]",
                        "in": "query",
                        "description": "Only the transactions tagged with any of these labels.",
                        "schema": {
                            "type": "array",
                            "format": "uuid",
                            "items": {
                                "type": "string",
                                "format": "uuid"
                            }
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "description": "The earliest transaction date, inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-01-01"
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "description": "The latest transaction date, inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-01-31"
                    },
                    {
                        "name": "min_amount",
                        "in": "query",
                        "description": "The smallest signed amount, in minor units. `-5000` keeps all income and the expenses of up to 5000 minor units.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "max_amount",
                        "in": "query",
                        "description": "The largest signed amount, in minor units. `0` keeps expenses only.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Transaction"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.transactions.store",
                "description": "Records a transaction by hand on one of your accounts in the space,\nbank-connected ones included: a sync never removes it. Nothing\ndeduplicates it against what the bank sends, so add only what the bank\nwill not sync, such as a cash payment or a transfer you made elsewhere.\nThe response adds `balance_updated`, whether\n`update_balance` moved the account's balance snapshots.",
                "summary": "Create a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreTransactionRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Transaction"
                                        },
                                        "balance_updated": {
                                            "type": "boolean",
                                            "description": "Whether `update_balance` moved the account's balance snapshots."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "balance_updated"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/transactions/{transaction}": {
            "get": {
                "operationId": "v1.transactions.show",
                "summary": "Retrieve a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The transaction's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Transaction"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.transactions.update",
                "description": "Changes only the fields you send, and also sets or clears the category.\nThe labels are not changed here. The notes and the category can be\nchanged on any transaction, and the date on any but one part of a\nsplit. The rest (description, amount, currency, account and\ncounterparty names) only on one you recorded by hand that is not one\npart of a split: on any other, sending them is a `422` and nothing is\nsaved. The response\nadds `balance_updated`, whether `update_balance` moved the account's\nbalance snapshots.",
                "summary": "Update a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The transaction's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateTransactionRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Transaction"
                                        },
                                        "balance_updated": {
                                            "type": "boolean",
                                            "description": "Whether `update_balance` moved the account's balance snapshots."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "balance_updated"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            },
            "delete": {
                "operationId": "v1.transactions.destroy",
                "description": "Deletes a transaction, one that came from a bank or an import included:\nas in the app, the next sync does not bring it back. One part of a split\ncannot be deleted on its own and answers `422` with the error under\n`transaction`.",
                "summary": "Delete a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The transaction's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "update_balance",
                        "in": "query",
                        "description": "Whether to take the transaction back out of the account's balance snapshots. Has no effect on a bank-connected account or a credit card; `balance_updated` in the response says whether they moved. Defaults to `false`.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The deleted transaction's id."
                                        },
                                        "deleted": {
                                            "type": "boolean",
                                            "description": "Always `true`."
                                        },
                                        "balance_updated": {
                                            "type": "boolean",
                                            "description": "Whether `update_balance` took the transaction back out of the account's balance snapshots."
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deleted",
                                        "balance_updated"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/transactions/{transaction}/labels": {
            "put": {
                "operationId": "v1.transactions.labels.update",
                "description": "Sets the transaction's labels to exactly `label_ids`: a label it had\nthat is not in the list is removed, and an empty list removes them\nall. Works on any transaction you own, including one from a bank or an\nimport and one part of a split. Labelling is also how a transaction\ncounts towards a savings goal: it does once it carries the goal's\nlabel.",
                "summary": "Replace the labels of a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The transaction's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ReplaceTransactionLabelsRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Transaction"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/transactions/{transaction}/split": {
            "post": {
                "operationId": "v1.transactions.split",
                "description": "Replaces a transaction that covered several things with 2 to 20 parts,\neach with its own amount, category and labels. Works on bank and\nimported transactions too. The parts must add up to the original\nexactly and all move money the same way. From then on the parts are\nwhat exists: the original is out of every list and every total, and\neach part carries a `split_parent_id` shared with its siblings. A part\ncannot be split again, deleted on its own, or have its amount, date or\naccount changed; categorizing, labelling and editing its notes work as\nusual. Splitting a part again answers `422` with the error under\n`transaction`, and the original's id answers `404` once it is split.\nAnswers the parts, in the order they were sent.",
                "summary": "Split a transaction",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The transaction's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SplitTransactionRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Array of `Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Transaction"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/transactions/{transaction}/merge-splits": {
            "post": {
                "operationId": "v1.transactions.merge-splits",
                "description": "Puts back the transaction a split came from, with the category it had\nbefore, and deletes every part along with the category, labels and\nnotes set on them. Pass the id of any one of the parts; one that is not\npart of a split answers `422` with the error under `transaction`, and\nthe original's own id answers `404`: it is out of every list until the\nmerge. Answers the original transaction, under its id from before the\nsplit.",
                "summary": "Merge a split back",
                "tags": [
                    "Transactions"
                ],
                "parameters": [
                    {
                        "name": "transaction",
                        "in": "path",
                        "required": true,
                        "description": "The id of any part of the split.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Transaction`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Transaction"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/categories": {
            "get": {
                "operationId": "v1.categories.index",
                "description": "Your categories in a space, newest first, roots and children alike:\nrebuild the tree from `parent_id`. As in the app, another member's\ncategories are not listed.",
                "summary": "List categories",
                "tags": [
                    "Categories"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Category"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.categories.store",
                "description": "A root category takes the `type` you send, and its cashflow direction\nfollows from it: `savings` and `investment` count as an outflow, a\n`transfer` keeps the `cashflow_direction` you send (`hidden` when you\nsend none) and the rest are left out of the cashflow. A child, created\nwith a `parent_id`, takes its parent's type and direction whatever you\nsend.",
                "summary": "Create a category",
                "tags": [
                    "Categories"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreCategoryRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`Category`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Category"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/categories/{category}": {
            "get": {
                "operationId": "v1.categories.show",
                "summary": "Retrieve a category",
                "tags": [
                    "Categories"
                ],
                "parameters": [
                    {
                        "name": "category",
                        "in": "path",
                        "required": true,
                        "description": "The category's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Category`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Category"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.categories.update",
                "description": "Changes only the fields you send. Moving it under another parent,\nor making it a root with `parent_id: null`, re-derives its type and\ncashflow direction as on create, and its whole subtree follows: its\nchildren and their children take its new type and direction. While it\nhas a parent, `type` and `cashflow_direction` are ignored.",
                "summary": "Update a category",
                "tags": [
                    "Categories"
                ],
                "parameters": [
                    {
                        "name": "category",
                        "in": "path",
                        "required": true,
                        "description": "The category's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateCategoryRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Category`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Category"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            },
            "delete": {
                "operationId": "v1.categories.destroy",
                "description": "Deletes the category and takes it off its transactions, which are left\nuncategorized. `strategy` decides what happens to its children; when moving them\nwould leave two categories with the same name at one level, nothing is\ndeleted and the answer is a `422` under `strategy`: rename one first.",
                "summary": "Delete a category",
                "tags": [
                    "Categories"
                ],
                "parameters": [
                    {
                        "name": "category",
                        "in": "path",
                        "required": true,
                        "description": "The category's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "strategy",
                        "in": "query",
                        "description": "What happens to the category's children: `reparent` moves them up to its parent (or makes them roots when it is one), `promote` makes them roots, `cascade` deletes them too, with their own children. Defaults to `reparent`.",
                        "schema": {
                            "$ref": "#/components/schemas/CategoryDeletionStrategy"
                        },
                        "example": "reparent"
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The deleted category's id."
                                        },
                                        "deleted": {
                                            "type": "boolean",
                                            "description": "Always `true`."
                                        },
                                        "strategy": {
                                            "type": "string",
                                            "description": "The strategy that was applied to the children.",
                                            "enum": [
                                                "reparent",
                                                "promote",
                                                "cascade"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deleted",
                                        "strategy"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/labels": {
            "get": {
                "operationId": "v1.labels.index",
                "description": "Your labels in a space, newest first, the ones that track a savings goal\nincluded. As in the app, another member's labels are not listed.",
                "summary": "List labels",
                "tags": [
                    "Labels"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Label"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.labels.store",
                "description": "Tag transactions with it through `PUT /api/v1/transactions/{id}/labels`.",
                "summary": "Create a label",
                "tags": [
                    "Labels"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreLabelRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`Label`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Label"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/labels/{label}": {
            "get": {
                "operationId": "v1.labels.show",
                "summary": "Retrieve a label",
                "tags": [
                    "Labels"
                ],
                "parameters": [
                    {
                        "name": "label",
                        "in": "path",
                        "required": true,
                        "description": "The label's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Label`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Label"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.labels.update",
                "description": "Changes only the fields you send. The label of a savings goal\n(`source: saving_goal`) carries the goal's name, so renaming it is a\n`422`; its color can still be changed.",
                "summary": "Update a label",
                "tags": [
                    "Labels"
                ],
                "parameters": [
                    {
                        "name": "label",
                        "in": "path",
                        "required": true,
                        "description": "The label's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateLabelRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Label`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Label"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            },
            "delete": {
                "operationId": "v1.labels.destroy",
                "description": "Deletes the label; the transactions that carried it no longer show it.\nThe label of a savings goal (`source: saving_goal`) is how the goal counts its\ncontributions, so it cannot be deleted on its own: that answers `422`\nwith the error under `label`.",
                "summary": "Delete a label",
                "tags": [
                    "Labels"
                ],
                "parameters": [
                    {
                        "name": "label",
                        "in": "path",
                        "required": true,
                        "description": "The label's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The deleted label's id."
                                        },
                                        "deleted": {
                                            "type": "boolean",
                                            "description": "Always `true`."
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deleted"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/automation-rules": {
            "get": {
                "operationId": "v1.automation-rules.index",
                "description": "Your rules in a space in the order they are evaluated: `priority`\nascending, then `title`. As in the app, another member's rules are not\nlisted.",
                "summary": "List automation rules",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/AutomationRule"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.automation-rules.store",
                "description": "The rule needs at least one action: `action_category_id`,\n`action_label_ids` or both. It only runs on the transactions created\nfrom now on. Conditions that say something other than what you meant\nstill save and then quietly match nothing, so preview a new rule with\nthe apply endpoint before trusting it.",
                "summary": "Create an automation rule",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreAutomationRuleRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`AutomationRule`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AutomationRule"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/automation-rules/{automation_rule}": {
            "get": {
                "operationId": "v1.automation-rules.show",
                "summary": "Retrieve an automation rule",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "automation_rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`AutomationRule`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AutomationRule"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.automation-rules.update",
                "description": "Changes only the fields you send. `conditions` and `action_label_ids`\nreplace the rule's whole set. The rule must keep at least one action, a\ncategory or labels: leaving it without one is a `422` under\n`action_category_id`. The transactions it already touched keep what it gave\nthem.",
                "summary": "Update an automation rule",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "automation_rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateAutomationRuleRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`AutomationRule`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AutomationRule"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            },
            "delete": {
                "operationId": "v1.automation-rules.destroy",
                "description": "The rule stops running on new transactions. The transactions it already\ncategorized or labelled keep their category and labels.",
                "summary": "Delete an automation rule",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "automation_rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The deleted rule's id."
                                        },
                                        "deleted": {
                                            "type": "boolean",
                                            "description": "Always `true`."
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deleted"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/automation-rules/{automation_rule}/apply": {
            "post": {
                "operationId": "v1.automation-rules.apply",
                "description": "Runs the rule over the transactions already in the space, which it\notherwise never touches. By default this is a preview (`dry_run: true`):\nit answers `status: preview` with how many transactions match and the\nfirst 20 of them, newest first, and changes nothing.\n\nWith `dry_run: false` it **overwrites your data**: every match gets the\nrule's category (replacing the one it had when `only_uncategorized` is\n`false`), its labels added and its note appended. It cannot be undone.\nUp to 100 matches are applied right away and answer `200` with\n`status: done`; more are applied in the background over the next few\nminutes and answer `202` with `status: queued`. There is no progress\nendpoint: preview again to see what the rule still matches.\n\nPreviewing and applying both need a write token, and both only reach\nyour own transactions. The matches are worked\nout once and reused for up to 15 minutes, so the apply that follows a\npreview goes over the transactions that preview reported; editing the\nrule starts over.",
                "summary": "Apply an automation rule to existing transactions",
                "tags": [
                    "Automation rules"
                ],
                "parameters": [
                    {
                        "name": "automation_rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ApplyAutomationRuleRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`RuleApplication`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/RuleApplication"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/budgets": {
            "get": {
                "operationId": "v1.budgets.index",
                "description": "Your budgets, newest first, each with the period in progress. Archived\nbudgets are left out; retrieve one by its id to read it.",
                "summary": "List budgets",
                "tags": [
                    "Budgets"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Budget"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.budgets.store",
                "description": "The budget needs at least one category or label to track, or\n`is_catch_all: true`. It starts with the period in progress and the one\nbefore it. The transactions already in them are added in the\nbackground, so `current_period.spent_amount` is provisional while\n`current_period.processing_historical` is `true`: read the budget again\na few seconds later.",
                "summary": "Create a budget",
                "tags": [
                    "Budgets"
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreBudgetRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`Budget`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Budget"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/budgets/{budget}": {
            "get": {
                "operationId": "v1.budgets.show",
                "description": "Archived budgets included.",
                "summary": "Retrieve a budget",
                "tags": [
                    "Budgets"
                ],
                "parameters": [
                    {
                        "name": "budget",
                        "in": "path",
                        "required": true,
                        "description": "The budget's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Budget`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Budget"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.budgets.update",
                "description": "Changes only the fields you send: the name, the limit and the expense\ntype. A new `allocated_amount` applies to the period in progress and\nevery later one; past periods keep theirs. `period_type`,\n`period_start_day`, `rollover_type`, `is_catch_all`, `category_ids` and\n`label_ids` are fixed, since the budget's periods are calculated over\nits history: sending any of them is a `422` under that field, and the\nway to change them is to delete the budget and create it again. An\narchived budget can no longer change: `422` under `budget`.",
                "summary": "Update a budget",
                "tags": [
                    "Budgets"
                ],
                "parameters": [
                    {
                        "name": "budget",
                        "in": "path",
                        "required": true,
                        "description": "The budget's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateBudgetRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`Budget`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Budget"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            },
            "delete": {
                "operationId": "v1.budgets.destroy",
                "description": "Deletes the budget with its periods and their spending history,\narchived budgets included. The transactions it tracked are untouched.",
                "summary": "Delete a budget",
                "tags": [
                    "Budgets"
                ],
                "parameters": [
                    {
                        "name": "budget",
                        "in": "path",
                        "required": true,
                        "description": "The budget's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The deleted budget's id."
                                        },
                                        "deleted": {
                                            "type": "boolean",
                                            "description": "Always `true`."
                                        }
                                    },
                                    "required": [
                                        "id",
                                        "deleted"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/savings-goals": {
            "get": {
                "operationId": "v1.savings-goals.index",
                "description": "Your goals in a space, newest first, archived ones included. As in the\napp, another member's goals are not listed.",
                "summary": "List savings goals",
                "tags": [
                    "Savings goals"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "How many objects to return, between 1 and 100. Defaults to 25.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        },
                        "example": 25
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "description": "An object id: return the page that follows it. Pass the last id of the page you have.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "ending_before",
                        "in": "query",
                        "description": "An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with `starting_after`.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of objects.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/SavingsGoal"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether more objects exist past this page, in the direction being walked."
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "has_more"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "post": {
                "operationId": "v1.savings-goals.store",
                "description": "Creates the goal in the space, with a label of the same name to tag its\ncontributions with. A one-off goal needs `target_amount`; a monthly\ngoal needs `monthly_target_type` with its `monthly_target_amount` or\n`monthly_target_rate`, and its first month opens right away. The\nfields of the other kind are refused. A monthly goal given\n`auto_tag_account_id` also gets an automation rule, listed with the\nothers, that tags the transfers into that savings account to the goal,\nthe ones already there since the start of this month included. The\nrule goes last in your order, so an older rule that matches the same\ntransfers keeps them.",
                "summary": "Create a savings goal",
                "tags": [
                    "Savings goals"
                ],
                "parameters": [
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "description": "Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "9b2f4c1e-5d3a-4e7b-8c6d-0a1b2c3d4e5f"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreSavingsGoalRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "`SavingsGoal`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/SavingsGoal"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotencyConflict"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/savings-goals/{savings_goal}": {
            "get": {
                "operationId": "v1.savings-goals.show",
                "summary": "Retrieve a savings goal",
                "tags": [
                    "Savings goals"
                ],
                "parameters": [
                    {
                        "name": "savings_goal",
                        "in": "path",
                        "required": true,
                        "description": "The goal's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`SavingsGoal`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/SavingsGoal"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            },
            "patch": {
                "operationId": "v1.savings-goals.update",
                "description": "Changes only the fields you send, and only the fields of the goal's\nkind: the others, and `kind` itself, are refused. A new name renames\nthe goal's label too. A new monthly target applies to the month in\nprogress and later ones, never to the months already over. Only the\nmember of the space who created the goal can change it, and an\narchived goal can no longer change: `422` under `savings_goal`.",
                "summary": "Update a savings goal",
                "tags": [
                    "Savings goals"
                ],
                "parameters": [
                    {
                        "name": "savings_goal",
                        "in": "path",
                        "required": true,
                        "description": "The goal's id.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "space",
                        "in": "query",
                        "description": "The id of the space to work in (see `GET /spaces`). Defaults to your personal space. On writes it may also be sent in the JSON body.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateSavingsGoalRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "`SavingsGoal`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/SavingsGoal"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:write"
            }
        },
        "/analytics/cashflow": {
            "get": {
                "operationId": "v1.analytics.cashflow",
                "description": "The cashflow of a date range: income, expenses, savings and investments\nagainst the previous period, your expenses split by the budgets that\ntrack them (fixed, variable and general), what your budgets still\nreserve, where the money came from and went by category, and the\nmonthly trend. The range can touch at most 24 calendar months.",
                "summary": "Retrieve the cashflow",
                "tags": [
                    "Analytics"
                ],
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "description": "The first day of the range, inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-01"
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "description": "The last day of the range, inclusive. Not before `from`.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-31"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`Cashflow`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Cashflow"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            }
        },
        "/analytics/net-worth": {
            "get": {
                "operationId": "v1.analytics.net-worth",
                "description": "Your net worth at the end of a date range against the end of the\nprevious period, and every account's balance over the range, monthly or\ndaily. A monthly range can touch at most 120 calendar months, a daily\none cover at most 366 days.",
                "summary": "Retrieve the net worth",
                "tags": [
                    "Analytics"
                ],
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "description": "The first day of the range, inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-01"
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "description": "The last day of the range, inclusive. Not before `from`.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-31"
                    },
                    {
                        "name": "granularity",
                        "in": "query",
                        "description": "`monthly` (the default) for a point at the end of each month of the range, `daily` for one per day.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "monthly",
                                "daily"
                            ]
                        },
                        "example": "monthly"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`NetWorth`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/NetWorth"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            }
        },
        "/analytics/spending-by-category": {
            "get": {
                "operationId": "v1.analytics.spending-by-category",
                "description": "Your expenses in a date range by top-level category, each with its\nsubcategories rolled into it. Pass `parent_category_id` to drill into a\ncategory: its children come back instead, plus a row for what was booked\nto the category itself (`is_direct`). The range can touch at most 120\ncalendar months.",
                "summary": "Retrieve spending by category",
                "tags": [
                    "Analytics"
                ],
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": true,
                        "description": "The first day of the range, inclusive.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-01"
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": true,
                        "description": "The last day of the range, inclusive. Not before `from`.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "example": "2026-10-31"
                    },
                    {
                        "name": "parent_category_id",
                        "in": "query",
                        "description": "Drill into one of your categories: its children are returned instead of the top-level categories.",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "`SpendingByCategory`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/SpendingByCategory"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationException"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            }
        },
        "/achievements": {
            "get": {
                "operationId": "v1.achievements.index",
                "description": "The whole medal catalog, grouped into tracks, earned or not. On each\ntrack, the first medal you have not earned yet is `next` and comes named,\noften with how far along you are; the ones past it are `locked` and stay\nsilhouettes, with no name, icon or figure. The catalog is small and\nfixed, so it is not paginated.",
                "summary": "List achievements",
                "tags": [
                    "Achievements"
                ],
                "responses": {
                    "200": {
                        "description": "`Achievements`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Achievements"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthenticated"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                },
                "x-token-ability": "api:read"
            }
        }
    },
    "components": {
        "securitySchemes": {
            "personalAccessToken": {
                "type": "http",
                "description": "A personal API token (`wm_api_\u2026`) created in Settings \u2192 API. Read-only tokens carry `api:read`; read & write tokens also carry `api:write`.",
                "scheme": "bearer"
            },
            "oauth2": {
                "type": "oauth2",
                "description": "An OAuth 2.1 access token (authorization code with PKCE) granted the `api:use` scope, which reads and writes. Clients register through dynamic client registration.",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://whisper.money/oauth/authorize",
                        "tokenUrl": "https://whisper.money/oauth/token",
                        "refreshUrl": "https://whisper.money/oauth/token",
                        "scopes": {
                            "api:use": "Use the Whisper Money API"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Account": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The account's id.",
                        "examples": [
                            "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the account is in.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The account's name.",
                        "examples": [
                            "Main checking"
                        ]
                    },
                    "type": {
                        "type": "string",
                        "description": "The account type. `checking`, `credit_card`, `savings` and `others` keep a transaction ledger; `investment`, `retirement`, `loan` and `real_estate` track a balance only.",
                        "enum": [
                            "checking",
                            "credit_card",
                            "investment",
                            "loan",
                            "retirement",
                            "real_estate",
                            "savings",
                            "others"
                        ],
                        "examples": [
                            "checking"
                        ]
                    },
                    "currency": {
                        "type": "string",
                        "description": "The ISO 4217 currency the account is held in, which its amounts are in.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "bank": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The bank the account is held at, if one is set: its id and name.",
                        "examples": [
                            {
                                "id": "0199a3f1-5b2c-7e8d-9f0a-1b2c3d4e5f60",
                                "name": "BBVA"
                            }
                        ],
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "is_connected": {
                        "type": "boolean",
                        "description": "Whether the account is connected to a bank. A connected account's balances, currency and bank come from the sync: only its name, type and ownership can be changed, and it takes no manual balance.",
                        "examples": [
                            false
                        ]
                    },
                    "ownership_percentage": {
                        "type": "integer",
                        "description": "The owner's share of the account, 1 to 100. Below 100 only that slice counts in their figures.",
                        "examples": [
                            100
                        ]
                    },
                    "ownership_applies_to_balance": {
                        "type": "boolean",
                        "description": "Whether the ownership share applies to the balance too, not only to transactions."
                    },
                    "credit_card_detail": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "`credit_card` only, otherwise `null`: the card's limit and statement dates, in minor units and ISO dates. Later cycles repeat from the dates at `statement_frequency`. `null` while none is set.",
                        "examples": [
                            null
                        ],
                        "properties": {
                            "statement_closing_date": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "payment_due_date": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "statement_frequency": {
                                "type": "string",
                                "enum": [
                                    "monthly",
                                    "weekly"
                                ]
                            },
                            "credit_limit": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "statement_closing_date",
                            "payment_due_date",
                            "statement_frequency",
                            "credit_limit"
                        ]
                    },
                    "credit_card_statement": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "`credit_card` only, otherwise `null`: an estimate of the card's next charge, computed from its statement dates and its transactions. It is not a transaction, and `next_payment.is_final` is false while the cycle is still open. `null` while the card has no statement dates.",
                        "examples": [
                            null
                        ],
                        "properties": {
                            "next_payment": {
                                "type": "object",
                                "properties": {
                                    "period_from": {
                                        "type": "string"
                                    },
                                    "closing_date": {
                                        "type": "string"
                                    },
                                    "due_date": {
                                        "type": "string"
                                    },
                                    "amount": {
                                        "type": "integer"
                                    },
                                    "is_final": {
                                        "type": "boolean"
                                    },
                                    "paid": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "period_from",
                                    "closing_date",
                                    "due_date",
                                    "amount",
                                    "is_final",
                                    "paid"
                                ]
                            },
                            "current_cycle": {
                                "type": "object",
                                "properties": {
                                    "period_from": {
                                        "type": "string"
                                    },
                                    "closing_date": {
                                        "type": "string"
                                    },
                                    "due_date": {
                                        "type": "string"
                                    },
                                    "amount": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "period_from",
                                    "closing_date",
                                    "due_date",
                                    "amount"
                                ]
                            },
                            "payments": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "transaction_id": {
                                            "type": "string"
                                        },
                                        "date": {
                                            "type": "string"
                                        },
                                        "amount": {
                                            "type": "integer"
                                        },
                                        "period_from": {
                                            "type": "string"
                                        },
                                        "closing_date": {
                                            "type": "string"
                                        },
                                        "due_date": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "transaction_id",
                                        "date",
                                        "amount",
                                        "period_from",
                                        "closing_date",
                                        "due_date"
                                    ]
                                }
                            },
                            "previous_statement": {
                                "type": "object",
                                "properties": {
                                    "period_from": {
                                        "type": "string"
                                    },
                                    "closing_date": {
                                        "type": "string"
                                    },
                                    "due_date": {
                                        "type": "string"
                                    },
                                    "purchases": {
                                        "type": "integer"
                                    },
                                    "paid": {
                                        "type": "integer"
                                    },
                                    "pending": {
                                        "type": "integer"
                                    },
                                    "has_recorded_purchases": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "period_from",
                                    "closing_date",
                                    "due_date",
                                    "purchases",
                                    "paid",
                                    "pending",
                                    "has_recorded_purchases"
                                ]
                            }
                        },
                        "required": [
                            "next_payment",
                            "current_cycle",
                            "payments",
                            "previous_statement"
                        ]
                    },
                    "credit_card_usage": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "`credit_card` only, otherwise `null`: how much of the card is in use. `used` is what is still to be charged between `period_from` and today, less the payments made on those statements, never below 0. `available` is `limit` minus it, negative over the limit; both `limit` and `available` are `null` while no credit limit is set.",
                        "examples": [
                            null
                        ],
                        "properties": {
                            "limit": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "used": {
                                "type": "integer"
                            },
                            "available": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "period_from": {
                                "type": "string"
                            },
                            "period_to": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "limit",
                            "used",
                            "available",
                            "period_from",
                            "period_to"
                        ]
                    },
                    "archived_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the account was archived in the app, or `null`. An archived account keeps its history and still answers here.",
                        "examples": [
                            null
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the account was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "name",
                    "type",
                    "currency",
                    "bank",
                    "is_connected",
                    "ownership_percentage",
                    "ownership_applies_to_balance",
                    "credit_card_detail",
                    "credit_card_statement",
                    "credit_card_usage",
                    "archived_at",
                    "created_at"
                ],
                "title": "Account"
            },
            "AccountBalance": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The snapshot's id.",
                        "examples": [
                            "0199a3f6-2b4c-7d5e-9f60-718293a4b5c6"
                        ]
                    },
                    "account_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id of the account the snapshot belongs to.",
                        "examples": [
                            "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01"
                        ]
                    },
                    "balance_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The day the balance is for. An account has at most one snapshot per day.",
                        "examples": [
                            "2026-01-31"
                        ]
                    },
                    "balance": {
                        "type": "integer",
                        "description": "The balance, in the account currency's minor units.",
                        "examples": [
                            250000
                        ]
                    },
                    "invested_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "How much of the balance is money put in rather than gains, in minor units, or `null`. Set on investment accounts.",
                        "examples": [
                            null
                        ]
                    },
                    "derived": {
                        "type": "boolean",
                        "description": "Whether the snapshot was worked out backwards from a bank-connected account's transactions, rather than reported by the bank or recorded by you. A balance recorded through the API is never derived."
                    }
                },
                "required": [
                    "id",
                    "account_id",
                    "balance_date",
                    "balance",
                    "invested_amount",
                    "derived"
                ],
                "title": "AccountBalance"
            },
            "Achievement": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string",
                        "description": "The medal's key, unique in the catalog.",
                        "examples": [
                            "transactions.2"
                        ]
                    },
                    "rarity": {
                        "type": "string",
                        "description": "How rare the medal is: `common`, `uncommon`, `rare` or `epic`.",
                        "examples": [
                            "common"
                        ]
                    },
                    "share": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "The percentage of Whisper Money users who hold it, or `null` while there are too few users to tell or nobody holds it yet.",
                        "examples": [
                            42.5
                        ]
                    },
                    "state": {
                        "type": "string",
                        "description": "`earned`; `next` for the one rung of its track you are working towards; or `locked` for the ones past it.",
                        "enum": [
                            "earned",
                            "next",
                            "locked"
                        ],
                        "examples": [
                            "next"
                        ]
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The medal's name. `null` on a `locked` medal, which stays a silhouette: only the `next` one is named.",
                        "examples": [
                            "50 transactions"
                        ]
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The medal's pictogram, a Lucide icon name; `null` on a `locked` medal.",
                        "examples": [
                            "ListChecks"
                        ]
                    },
                    "figure": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The milestone the medal stands for: its `type` (`money`, `count`, `percent`, `months`, `weeks` or `days`), its `value` (in minor units of `currency` for money) and that `currency`, `null` for the other types. `null` on a `locked` medal and on the ones that are an event with no number to them.",
                        "examples": [
                            {
                                "type": "count",
                                "value": 50,
                                "currency": null
                            }
                        ],
                        "properties": {
                            "type": {
                                "type": "string"
                            },
                            "value": {
                                "type": "number"
                            },
                            "currency": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "type",
                            "value",
                            "currency"
                        ]
                    },
                    "reached": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "On an `earned` medal, what you had reached on the day, shaped like `figure`; `null` otherwise.",
                        "examples": [
                            null
                        ],
                        "properties": {
                            "type": {
                                "type": "string"
                            },
                            "value": {
                                "type": "number"
                            },
                            "currency": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "type",
                            "value",
                            "currency"
                        ]
                    },
                    "achieved_on": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "The day the medal was earned, or `null`.",
                        "examples": [
                            null
                        ]
                    },
                    "progress": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "On the `next` medal of the tracks whose figure is cheap to read, how far along you are: `now` against `goal`, and `unlocking` once you are past the goal but the medal still waits for the nightly check that awards it. `null` otherwise.",
                        "examples": [
                            {
                                "now": 23,
                                "goal": 50,
                                "unlocking": false
                            }
                        ],
                        "properties": {
                            "now": {
                                "type": "integer"
                            },
                            "goal": {
                                "type": "number"
                            },
                            "unlocking": {
                                "type": "boolean"
                            }
                        },
                        "required": [
                            "now",
                            "goal",
                            "unlocking"
                        ]
                    }
                },
                "required": [
                    "key",
                    "rarity",
                    "share",
                    "state",
                    "name",
                    "icon",
                    "figure",
                    "reached",
                    "achieved_on",
                    "progress"
                ],
                "title": "Achievement"
            },
            "AchievementTrack": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string",
                        "description": "The track's key.",
                        "examples": [
                            "transactions"
                        ]
                    },
                    "label": {
                        "type": "string",
                        "description": "The track's name.",
                        "examples": [
                            "Transactions recorded"
                        ]
                    },
                    "note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the track has to explain about itself, or `null`.",
                        "examples": [
                            null
                        ]
                    },
                    "unlocked": {
                        "type": "integer",
                        "description": "How many of its medals you have earned.",
                        "examples": [
                            1
                        ]
                    },
                    "medals": {
                        "type": "array",
                        "description": "Its medals, from the first rung up.",
                        "items": {
                            "$ref": "#/components/schemas/Achievement"
                        }
                    }
                },
                "required": [
                    "key",
                    "label",
                    "note",
                    "unlocked",
                    "medals"
                ],
                "title": "AchievementTrack"
            },
            "Achievements": {
                "type": "object",
                "properties": {
                    "currency": {
                        "type": "string",
                        "description": "The currency the money milestones are set in: your account's currency when the medals have levels for it, `USD` otherwise.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "unlocked": {
                        "type": "integer",
                        "description": "How many medals you have earned.",
                        "examples": [
                            12
                        ]
                    },
                    "total": {
                        "type": "integer",
                        "description": "How many medals there are.",
                        "examples": [
                            59
                        ]
                    },
                    "streak": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Your saving streak as it stands: how many months in a row you have saved, from the last monthly report, and the first day of the first of them. It is a live figure, not a medal, and it can break. `null` with no streak running.",
                        "examples": [
                            {
                                "months": 3,
                                "since": "2026-07-01"
                            }
                        ],
                        "properties": {
                            "months": {
                                "type": "integer"
                            },
                            "since": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "months",
                            "since"
                        ]
                    },
                    "latest": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The medal you earned last, or `null` with none.",
                        "examples": [
                            {
                                "name": "First transaction",
                                "achieved_on": "2026-03-02"
                            }
                        ],
                        "properties": {
                            "name": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "achieved_on": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "achieved_on"
                        ]
                    },
                    "tracks": {
                        "type": "array",
                        "description": "The tracks, each a ladder of medals.",
                        "items": {
                            "$ref": "#/components/schemas/AchievementTrack"
                        }
                    }
                },
                "required": [
                    "currency",
                    "unlocked",
                    "total",
                    "streak",
                    "latest",
                    "tracks"
                ],
                "title": "Achievements"
            },
            "ApplyAutomationRuleRequest": {
                "type": "object",
                "properties": {
                    "dry_run": {
                        "type": "boolean",
                        "description": "`true` (the default) only previews: it reports how many transactions the rule matches, with a sample of them, and changes nothing. Send `false` to apply the rule's actions to every match.",
                        "default": true,
                        "examples": [
                            true
                        ]
                    },
                    "only_uncategorized": {
                        "type": "boolean",
                        "description": "`true` (the default) skips the transactions that already have a category or, for a rule with labels and no category, that already carry all its labels. Send `false` to also take the categorized ones: the rule then overwrites the category the user or another rule gave them. Preview that combination before applying it.",
                        "default": true
                    }
                },
                "title": "ApplyAutomationRuleRequest"
            },
            "AutomationRule": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The rule's id.",
                        "examples": [
                            "0199a3f9-5d6e-7f8a-9b0c-1d2e3f4a5b6c"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the rule is in.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "title": {
                        "type": "string",
                        "description": "The rule's name.",
                        "examples": [
                            "Groceries"
                        ]
                    },
                    "priority": {
                        "type": "integer",
                        "description": "The order the rule is evaluated in, lowest first. A new transaction gets the actions of the first rule it matches, and no other.",
                        "examples": [
                            10
                        ]
                    },
                    "conditions": {
                        "type": "object",
                        "description": "The conditions a transaction must meet, as one JsonLogic object. Amounts in here are in MAJOR units, unlike every other amount in the API. A rule the AI categorization learned can still have none: `{}`.",
                        "examples": [
                            {
                                "and": [
                                    {
                                        "in": [
                                            "mercadona",
                                            {
                                                "var": "description"
                                            }
                                        ]
                                    },
                                    {
                                        "<": [
                                            {
                                                "var": "amount"
                                            },
                                            0
                                        ]
                                    }
                                ]
                            }
                        ],
                        "additionalProperties": {}
                    },
                    "action_category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category the rule gives the matching transactions, or `null` for none.",
                        "examples": [
                            "0199a3f5-2b3c-7d4e-8f5a-6b7c8d9e0f12"
                        ]
                    },
                    "action_label_ids": {
                        "type": "array",
                        "description": "The ids of the labels the rule adds to the matching transactions.",
                        "examples": [
                            [
                                "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                            ]
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "action_note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The note the rule appends to the matching transactions' notes, or `null` for none.",
                        "examples": [
                            "Weekly shop"
                        ]
                    },
                    "origin": {
                        "type": "string",
                        "description": "Who made the rule: `user` for one made by hand (in the app, the AI connector or this API), `ai` for one Whisper Money's AI categorization learned, and `correction` for one it learned from your own recategorizations.",
                        "enum": [
                            "user",
                            "ai",
                            "correction"
                        ],
                        "examples": [
                            "user"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the rule was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the rule was last changed.",
                        "examples": [
                            "2026-01-20T18:05:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "title",
                    "priority",
                    "conditions",
                    "action_category_id",
                    "action_label_ids",
                    "action_note",
                    "origin",
                    "created_at",
                    "updated_at"
                ],
                "title": "AutomationRule"
            },
            "Budget": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The budget's id.",
                        "examples": [
                            "0199a3f8-4c5d-7e6f-8a9b-0c1d2e3f4a5b"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The budget's name.",
                        "examples": [
                            "Groceries"
                        ]
                    },
                    "period_type": {
                        "type": "string",
                        "description": "How often the budget starts over: `monthly`, `weekly`, `biweekly`, `quarterly` or `yearly`. Fixed once created.",
                        "enum": [
                            "monthly",
                            "weekly",
                            "biweekly",
                            "yearly",
                            "quarterly"
                        ],
                        "examples": [
                            "monthly"
                        ]
                    },
                    "period_start_day": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The day a period starts: the day of the month (1\u201331) for a monthly budget, the day of the week (0 is Sunday) for a weekly or biweekly one. Quarterly and yearly budgets follow the calendar. `null` when not set. Fixed once created.",
                        "examples": [
                            1
                        ]
                    },
                    "rollover_type": {
                        "type": "string",
                        "description": "What happens to what is left at the end of a period: `carry_over` adds it to the next period, `reset` starts every period at the limit. Fixed once created.",
                        "enum": [
                            "carry_over",
                            "reset"
                        ],
                        "examples": [
                            "reset"
                        ]
                    },
                    "expense_type": {
                        "type": "string",
                        "description": "`fixed` for spending that repeats at the same amount every period (rent, subscriptions), `variable` for spending you can adjust (groceries, leisure). It decides how the cashflow analytics split your expenses. A catch-all budget is always `variable`.",
                        "enum": [
                            "fixed",
                            "variable"
                        ],
                        "examples": [
                            "variable"
                        ]
                    },
                    "is_catch_all": {
                        "type": "boolean",
                        "description": "Whether the budget tracks every expense category no other budget tracks. An account has at most one. Fixed once created."
                    },
                    "categories": {
                        "type": "array",
                        "description": "The categories the budget tracks; tracking a parent category also tracks its children. Fixed once created.",
                        "examples": [
                            [
                                {
                                    "id": "0199a3f5-2b3c-7d4e-8f5a-6b7c8d9e0f12",
                                    "name": "Groceries"
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "id",
                                "name"
                            ]
                        }
                    },
                    "labels": {
                        "type": "array",
                        "description": "The labels the budget tracks. Fixed once created.",
                        "examples": [
                            [
                                {
                                    "id": "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23",
                                    "name": "Essentials"
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "id",
                                "name"
                            ]
                        }
                    },
                    "currency": {
                        "type": "string",
                        "description": "The currency of the budget's amounts: your account's currency, as an ISO 4217 code.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "current_period": {
                        "anyOf": [
                            {
                                "description": "The period that covers today, or `null` when no period does.",
                                "$ref": "#/components/schemas/BudgetPeriod"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "archived_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the budget was archived in the app, or `null`. An archived budget keeps its history but can no longer change; it can still be deleted.",
                        "examples": [
                            null
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the budget was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the budget was last changed.",
                        "examples": [
                            "2026-01-20T18:05:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "name",
                    "period_type",
                    "period_start_day",
                    "rollover_type",
                    "expense_type",
                    "is_catch_all",
                    "categories",
                    "labels",
                    "currency",
                    "current_period",
                    "archived_at",
                    "created_at",
                    "updated_at"
                ],
                "title": "Budget"
            },
            "BudgetExpenseType": {
                "type": "string",
                "description": "Whether a budget covers spending that repeats at the same amount every period (rent, subscriptions) or spending the user can adjust (groceries, restaurants). Cashflow splits expenses by it.\n",
                "enum": [
                    "fixed",
                    "variable"
                ],
                "title": "BudgetExpenseType"
            },
            "BudgetPeriod": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The period's id.",
                        "examples": [
                            "0199a3fa-1b2c-7d3e-8f4a-5b6c7d8e9f01"
                        ]
                    },
                    "start_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The period's first day.",
                        "examples": [
                            "2026-10-01"
                        ]
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The period's last day, included.",
                        "examples": [
                            "2026-10-31"
                        ]
                    },
                    "allocated_amount": {
                        "type": "integer",
                        "description": "The limit for this period.",
                        "examples": [
                            50000
                        ]
                    },
                    "carried_over_amount": {
                        "type": "integer",
                        "description": "What the previous period left over, carried into this one when the budget's `rollover_type` is `carry_over`.",
                        "examples": [
                            0
                        ]
                    },
                    "spent_amount": {
                        "type": "integer",
                        "description": "What the tracked transactions of the period add up to, as a positive number; a refund lowers it. Provisional while `processing_historical` is `true`.",
                        "examples": [
                            32050
                        ]
                    },
                    "remaining_amount": {
                        "type": "integer",
                        "description": "`allocated_amount` minus `spent_amount`, the figure the app shows. It leaves out `carried_over_amount`, and it is negative once the period goes over its limit.",
                        "examples": [
                            17950
                        ]
                    },
                    "processing_historical": {
                        "type": "boolean",
                        "description": "`true` while the transactions that were already in the period when the budget was created are still being added to it, in the background. Until then `spent_amount` and `remaining_amount` are provisional: read the budget again in a few seconds."
                    }
                },
                "required": [
                    "id",
                    "start_date",
                    "end_date",
                    "allocated_amount",
                    "carried_over_amount",
                    "spent_amount",
                    "remaining_amount",
                    "processing_historical"
                ],
                "title": "BudgetPeriod"
            },
            "BudgetPeriodType": {
                "type": "string",
                "enum": [
                    "monthly",
                    "weekly",
                    "biweekly",
                    "yearly",
                    "quarterly"
                ],
                "title": "BudgetPeriodType"
            },
            "Cashflow": {
                "type": "object",
                "properties": {
                    "currency": {
                        "type": "string",
                        "description": "The currency of every amount: your account's currency, as an ISO 4217 code.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "summary": {
                        "type": "object",
                        "properties": {
                            "current": {
                                "description": "The range's cashflow.",
                                "$ref": "#/components/schemas/CashflowPeriod"
                            },
                            "previous": {
                                "description": "The cashflow of the period before it, to compare with: the same number of days right before `from`, or the same number of whole months when the range is whole months. It has the expense split but no `reserved` or `budgets`, which are about today.",
                                "$ref": "#/components/schemas/CashflowPeriod"
                            }
                        },
                        "required": [
                            "current",
                            "previous"
                        ]
                    },
                    "sankey": {
                        "type": "object",
                        "properties": {
                            "income_categories": {
                                "type": "array",
                                "description": "Where the money came from, by top-level category. A category is netted and lands on the side its net points at, so an expense category that got more back than it spent is listed here as a refund. Savings and investment withdrawals and transfers set to count as an inflow appear here too, and the uncategorized money that came in is one row with no `category_id`.",
                                "items": {
                                    "$ref": "#/components/schemas/CategoryAmount"
                                }
                            },
                            "expense_categories": {
                                "type": "array",
                                "description": "Where the money went, by top-level category, built the same way. Savings, investments and transfers set to count as an outflow appear here too.",
                                "items": {
                                    "$ref": "#/components/schemas/CategoryAmount"
                                }
                            },
                            "total_income": {
                                "type": "integer",
                                "description": "What `income_categories` adds up to.",
                                "examples": [
                                    260000
                                ]
                            },
                            "total_expense": {
                                "type": "integer",
                                "description": "What `expense_categories` adds up to. Savings, investments and outflow transfers are in it, so it is not `summary.current.expense`.",
                                "examples": [
                                    106122
                                ]
                            }
                        },
                        "required": [
                            "income_categories",
                            "expense_categories",
                            "total_income",
                            "total_expense"
                        ]
                    },
                    "trend": {
                        "type": "array",
                        "description": "Income, expense and net per calendar month the range touches, oldest first. Counted like `current`: savings, investments and transfers left out.",
                        "examples": [
                            [
                                {
                                    "month": "2026-10",
                                    "income": 260000,
                                    "expense": 96122,
                                    "net": 163878
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "month": {
                                    "type": "string"
                                },
                                "income": {
                                    "type": "integer"
                                },
                                "expense": {
                                    "type": "integer"
                                },
                                "net": {
                                    "type": "integer"
                                }
                            },
                            "required": [
                                "month",
                                "income",
                                "expense",
                                "net"
                            ]
                        }
                    }
                },
                "required": [
                    "currency",
                    "summary",
                    "sankey",
                    "trend"
                ],
                "title": "Cashflow"
            },
            "CashflowBudget": {
                "type": "object",
                "properties": {
                    "budget_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The budget's id.",
                        "examples": [
                            "0199a3f8-4c5d-7e6f-8a9b-0c1d2e3f4a5b"
                        ]
                    },
                    "budget_period_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id of the budget's period in progress.",
                        "examples": [
                            "0199a3fa-1b2c-7d3e-8f4a-5b6c7d8e9f01"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The budget's name.",
                        "examples": [
                            "Groceries"
                        ]
                    },
                    "start_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The period's first day.",
                        "examples": [
                            "2026-10-01"
                        ]
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The period's last day, included.",
                        "examples": [
                            "2026-10-31"
                        ]
                    },
                    "expense_type": {
                        "type": "string",
                        "description": "`fixed` or `variable`: which part of the expense split the budget's spending counts in.",
                        "enum": [
                            "fixed",
                            "variable"
                        ],
                        "examples": [
                            "variable"
                        ]
                    },
                    "allocated": {
                        "type": "integer",
                        "description": "The period's limit, in minor units of `currency`.",
                        "examples": [
                            50000
                        ]
                    },
                    "spent": {
                        "type": "integer",
                        "description": "What was spent against it so far.",
                        "examples": [
                            32050
                        ]
                    },
                    "margin": {
                        "type": "integer",
                        "description": "`allocated` minus `spent`, negative once the period goes over its limit. Like the budgets endpoints, it leaves out any carried-over amount.",
                        "examples": [
                            17950
                        ]
                    }
                },
                "required": [
                    "budget_id",
                    "budget_period_id",
                    "name",
                    "start_date",
                    "end_date",
                    "expense_type",
                    "allocated",
                    "spent",
                    "margin"
                ],
                "title": "CashflowBudget"
            },
            "CashflowPeriod": {
                "type": "object",
                "properties": {
                    "income": {
                        "type": "integer",
                        "description": "What came in: the transactions in income categories, and the uncategorized ones that brought money in.",
                        "examples": [
                            260000
                        ]
                    },
                    "expense": {
                        "type": "integer",
                        "description": "What went out: the transactions in expense categories, and the uncategorized ones that took money out. Savings, investments and transfers are not in it.",
                        "examples": [
                            96122
                        ]
                    },
                    "net": {
                        "type": "integer",
                        "description": "`income` minus `expense`.",
                        "examples": [
                            163878
                        ]
                    },
                    "savings_rate": {
                        "type": "number",
                        "description": "`net` as a percentage of `income`, rounded to one decimal and never above 100. `0` with no income.",
                        "examples": [
                            63
                        ]
                    },
                    "savings": {
                        "type": "integer",
                        "description": "What was set aside into savings categories, net of withdrawals.",
                        "examples": [
                            10000
                        ]
                    },
                    "investments": {
                        "type": "integer",
                        "description": "What was set aside into investment categories, net of withdrawals.",
                        "examples": [
                            0
                        ]
                    },
                    "fixed_expense": {
                        "type": "integer",
                        "description": "The part of `expense` tracked by budgets marked fixed (rent, subscriptions). Budgets are variable unless marked fixed, so `0` may only mean none has been marked yet. A transaction tracked by a fixed and a variable budget counts here, once.",
                        "examples": [
                            90000
                        ]
                    },
                    "variable_expense": {
                        "type": "integer",
                        "description": "The part of `expense` tracked by budgets marked variable (groceries, leisure). Catch-all budgets do not count.",
                        "examples": [
                            5345
                        ]
                    },
                    "general_expense": {
                        "type": "integer",
                        "description": "The rest of `expense`, which no budget tracks. The three parts add up to `expense`, and any can be negative in a period of refunds.",
                        "examples": [
                            777
                        ]
                    },
                    "reserved": {
                        "type": "integer",
                        "description": "Current period only: what the budgets in `budgets` still hold back for spending, adding up their positive margins. An over-budget period adds nothing.",
                        "examples": [
                            17950
                        ]
                    },
                    "budgets": {
                        "type": "array",
                        "description": "Current period only: the budget periods in progress today that overlap the range. A range of up to 31 days counts weekly, bi-weekly and monthly budgets, one of up to 92 days those plus quarterly ones, and a longer one only yearly budgets.",
                        "items": {
                            "$ref": "#/components/schemas/CashflowBudget"
                        }
                    }
                },
                "required": [
                    "income",
                    "expense",
                    "net",
                    "savings_rate",
                    "savings",
                    "investments",
                    "fixed_expense",
                    "variable_expense",
                    "general_expense"
                ],
                "title": "CashflowPeriod"
            },
            "Category": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The category's id.",
                        "examples": [
                            "0199a3f5-2b3c-7d4e-8f5a-6b7c8d9e0f12"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the category is in.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The category's name, unique among its siblings.",
                        "examples": [
                            "Groceries"
                        ]
                    },
                    "icon": {
                        "type": "string",
                        "description": "The name of the icon the app shows for it, a Lucide icon name.",
                        "examples": [
                            "ShoppingBag"
                        ]
                    },
                    "color": {
                        "type": "string",
                        "description": "The category's color.",
                        "examples": [
                            "green"
                        ]
                    },
                    "type": {
                        "type": "string",
                        "description": "What the category's transactions are: `income`, `expense`, `transfer`, `savings` or `investment`. A whole tree shares its root's type.",
                        "enum": [
                            "income",
                            "expense",
                            "transfer",
                            "savings",
                            "investment"
                        ],
                        "examples": [
                            "expense"
                        ]
                    },
                    "cashflow_direction": {
                        "type": "string",
                        "description": "How the category's transactions count in the cashflow: `inflow`, `outflow`, or `hidden` to leave them out of it. A whole tree shares its root's direction.",
                        "enum": [
                            "hidden",
                            "inflow",
                            "outflow"
                        ],
                        "examples": [
                            "hidden"
                        ]
                    },
                    "parent_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category it is nested under, or `null` for a root.",
                        "examples": [
                            null
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the category was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "name",
                    "icon",
                    "color",
                    "type",
                    "cashflow_direction",
                    "parent_id",
                    "created_at"
                ],
                "title": "Category"
            },
            "CategoryAmount": {
                "type": "object",
                "properties": {
                    "category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The category's id, or `null` for the row that gathers the transactions with no category.",
                        "examples": [
                            "0199a3f5-2b3c-7d4e-8f5a-6b7c8d9e0f12"
                        ]
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The category's name. The row with no category is `Unknown Income` or `Unknown Expense`. On the cashflow's top level, a category whose net crossed to the other side says so: `Groceries (refund)`, `Savings (withdrawal)`, `Salary (reversal)`.",
                        "examples": [
                            "Groceries"
                        ]
                    },
                    "type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The category's type: `income`, `expense`, `savings`, `investment` or `transfer`.",
                        "examples": [
                            "expense"
                        ]
                    },
                    "color": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The category's colour in the app.",
                        "examples": [
                            "orange"
                        ]
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The category's icon in the app, a Lucide icon name.",
                        "examples": [
                            "ShoppingCart"
                        ]
                    },
                    "amount": {
                        "type": "integer",
                        "description": "What the category adds up to over the period, as a positive amount in minor units of `currency`.",
                        "examples": [
                            15345
                        ]
                    },
                    "has_children": {
                        "type": "boolean",
                        "description": "Whether the category has subcategories to drill into.",
                        "examples": [
                            false
                        ]
                    },
                    "is_direct": {
                        "type": "boolean",
                        "description": "When drilling into a category, `true` on the row for the transactions booked to that category itself rather than to one of its children.",
                        "examples": [
                            false
                        ]
                    }
                },
                "required": [
                    "category_id",
                    "name",
                    "type",
                    "color",
                    "icon",
                    "amount",
                    "has_children",
                    "is_direct"
                ],
                "title": "CategoryAmount"
            },
            "CategoryCashflowDirection": {
                "type": "string",
                "enum": [
                    "hidden",
                    "inflow",
                    "outflow"
                ],
                "title": "CategoryCashflowDirection"
            },
            "CategoryColor": {
                "type": "string",
                "enum": [
                    "amber",
                    "blue",
                    "cyan",
                    "emerald",
                    "fuchsia",
                    "gray",
                    "green",
                    "indigo",
                    "lime",
                    "neutral",
                    "orange",
                    "pink",
                    "purple",
                    "red",
                    "rose",
                    "slate",
                    "stone",
                    "teal",
                    "violet",
                    "yellow"
                ],
                "title": "CategoryColor"
            },
            "CategoryDeletionStrategy": {
                "type": "string",
                "enum": [
                    "reparent",
                    "promote",
                    "cascade"
                ],
                "title": "CategoryDeletionStrategy"
            },
            "CategoryType": {
                "type": "string",
                "enum": [
                    "income",
                    "expense",
                    "transfer",
                    "savings",
                    "investment"
                ],
                "title": "CategoryType"
            },
            "Error": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "What went wrong, in a sentence meant for a developer."
                    },
                    "code": {
                        "type": "string",
                        "description": "A stable, machine-readable error code, such as `not_found`."
                    },
                    "subscribe_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Only on `plan_required`: where to subscribe."
                    }
                },
                "required": [
                    "message",
                    "code"
                ],
                "title": "Error"
            },
            "Label": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The label's id.",
                        "examples": [
                            "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the label is in.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The label's name, unique within the space.",
                        "examples": [
                            "Holidays"
                        ]
                    },
                    "color": {
                        "type": "string",
                        "description": "The label's color.",
                        "examples": [
                            "blue"
                        ]
                    },
                    "source": {
                        "type": "string",
                        "description": "Where the label comes from: `user` for one made by hand, `saving_goal` for the one a savings goal tracks its contributions with.",
                        "enum": [
                            "user",
                            "saving_goal"
                        ],
                        "examples": [
                            "user"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the label was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "name",
                    "color",
                    "source",
                    "created_at"
                ],
                "title": "Label"
            },
            "LabelColor": {
                "type": "string",
                "enum": [
                    "amber",
                    "blue",
                    "cyan",
                    "emerald",
                    "fuchsia",
                    "gray",
                    "green",
                    "indigo",
                    "lime",
                    "neutral",
                    "orange",
                    "pink",
                    "purple",
                    "red",
                    "rose",
                    "slate",
                    "stone",
                    "teal",
                    "violet",
                    "yellow"
                ],
                "title": "LabelColor"
            },
            "MonthlyTargetType": {
                "type": "string",
                "description": "How a monthly savings goal sets its target: a fixed amount every month, or a share of the income the user usually earns.\n",
                "enum": [
                    "amount",
                    "income_rate"
                ],
                "title": "MonthlyTargetType"
            },
            "NetWorth": {
                "type": "object",
                "properties": {
                    "currency": {
                        "type": "string",
                        "description": "The currency of every amount: your account's currency, as an ISO 4217 code. Balances in another currency are converted at each day's exchange rate.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "granularity": {
                        "type": "string",
                        "description": "`monthly` or `daily`, as requested.",
                        "enum": [
                            "monthly",
                            "daily"
                        ],
                        "examples": [
                            "monthly"
                        ]
                    },
                    "net_worth": {
                        "type": "integer",
                        "description": "Your net worth on `to`: the balances of the accounts with `counts_in_net_worth`, converted to `currency`, a loan's debt counting against it. Credit cards are never part of it, and loans and real estate only when your net worth settings include them.",
                        "examples": [
                            366364
                        ]
                    },
                    "previous_net_worth": {
                        "type": "integer",
                        "description": "Your net worth at the end of the previous period: the same number of days right before `from`, or the same number of whole months when the range is whole months.",
                        "examples": [
                            360000
                        ]
                    },
                    "accounts": {
                        "type": "array",
                        "description": "Every account the evolution covers, archived ones and the ones left out of `net_worth` included: its id, name, type, own currency, and whether it is part of `net_worth`.",
                        "examples": [
                            [
                                {
                                    "id": "0199a3f2-8b1c-7d4e-9f5a-1b2c3d4e5f60",
                                    "name": "Main checking",
                                    "type": "checking",
                                    "currency": "EUR",
                                    "counts_in_net_worth": true
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                },
                                "type": {
                                    "type": "string"
                                },
                                "currency": {
                                    "type": "string"
                                },
                                "counts_in_net_worth": {
                                    "type": "boolean"
                                }
                            },
                            "required": [
                                "id",
                                "name",
                                "type",
                                "currency",
                                "counts_in_net_worth"
                            ]
                        }
                    },
                    "evolution": {
                        "type": "array",
                        "description": "One point per month the range touches, at the month's last day even when `to` falls before it, or one per day of the range; oldest first, with each account's balance on it.",
                        "items": {
                            "$ref": "#/components/schemas/NetWorthPoint"
                        }
                    }
                },
                "required": [
                    "currency",
                    "granularity",
                    "net_worth",
                    "previous_net_worth",
                    "accounts",
                    "evolution"
                ],
                "title": "NetWorth"
            },
            "NetWorthPoint": {
                "type": "object",
                "properties": {
                    "period": {
                        "type": "string",
                        "description": "The month (`2026-10`) or, with `daily` granularity, the day (`2026-10-15`).",
                        "examples": [
                            "2026-10"
                        ]
                    },
                    "balances": {
                        "type": "array",
                        "description": "One entry per account in `accounts`, in the same order: `balance` in `currency`, a loan's as the positive amount owed; `original_balance` and `original_currency` the account's own figure when its currency is another one, `null` otherwise; `invested_amount` what was put into an investment or retirement account on a monthly point, `null` for other types, on daily points or when not recorded.",
                        "examples": [
                            [
                                {
                                    "account_id": "0199a3f2-8b1c-7d4e-9f5a-1b2c3d4e5f60",
                                    "balance": 130000,
                                    "original_balance": null,
                                    "original_currency": null,
                                    "invested_amount": null
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "account_id": {
                                    "type": "string"
                                },
                                "balance": {
                                    "type": "integer"
                                },
                                "original_balance": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ]
                                },
                                "original_currency": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "invested_amount": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ]
                                }
                            },
                            "required": [
                                "account_id",
                                "balance",
                                "original_balance",
                                "original_currency",
                                "invested_amount"
                            ]
                        }
                    }
                },
                "required": [
                    "period",
                    "balances"
                ],
                "title": "NetWorthPoint"
            },
            "ReplaceTransactionLabelsRequest": {
                "type": "object",
                "properties": {
                    "label_ids": {
                        "type": "array",
                        "description": "The ids of every label the transaction should carry, each one of your labels in the space, up to 100. The transaction ends up with exactly these: a label left out is removed, and an empty list removes them all.",
                        "examples": [
                            [
                                "0199a3f7-3b4c-7d5e-8f6a-7b8c9d0e1f2a"
                            ]
                        ],
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 100,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "label_ids"
                ],
                "title": "ReplaceTransactionLabelsRequest"
            },
            "RolloverType": {
                "type": "string",
                "enum": [
                    "carry_over",
                    "reset"
                ],
                "title": "RolloverType"
            },
            "RuleApplication": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "description": "`preview` when nothing was changed, `done` when the rule was applied to every match, `queued` when it is being applied in the background.",
                        "enum": [
                            "preview",
                            "done",
                            "queued"
                        ],
                        "examples": [
                            "preview"
                        ]
                    },
                    "automation_rule_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The rule's id.",
                        "examples": [
                            "0199a3f9-5d6e-7f8a-9b0c-1d2e3f4a5b6c"
                        ]
                    },
                    "total": {
                        "type": "integer",
                        "description": "How many transactions the rule matches.",
                        "examples": [
                            42
                        ]
                    },
                    "sample": {
                        "type": "array",
                        "description": "On a preview, the first 20 matches, newest first; empty otherwise.",
                        "items": {
                            "$ref": "#/components/schemas/Transaction"
                        }
                    },
                    "applied": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "When `done`, how many matches the rule went over; `null` otherwise.",
                        "examples": [
                            null
                        ]
                    },
                    "updated": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "When `done`, how many of them it changed: one that already had the rule's category, labels and note is applied but not updated. `null` otherwise.",
                        "examples": [
                            null
                        ]
                    }
                },
                "required": [
                    "status",
                    "automation_rule_id",
                    "total",
                    "sample",
                    "applied",
                    "updated"
                ],
                "title": "RuleApplication"
            },
            "SavingsGoal": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The goal's id.",
                        "examples": [
                            "0199a3fb-2c3d-7e4f-8a5b-6c7d8e9f0a12"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the goal is in.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The goal's name, which is also the name of its label.",
                        "examples": [
                            "Emergency fund"
                        ]
                    },
                    "kind": {
                        "type": "string",
                        "description": "`one_off` to reach a total once, `monthly` to save towards a target every calendar month. Fixed once created.",
                        "enum": [
                            "one_off",
                            "monthly"
                        ],
                        "examples": [
                            "monthly"
                        ]
                    },
                    "label_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the goal's label. A transaction counts towards the goal once it carries this label: set it with `PUT /api/v1/transactions/{id}/labels`.",
                        "examples": [
                            "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                        ]
                    },
                    "currency": {
                        "type": "string",
                        "description": "The currency of the goal's amounts: the currency of the account of the member who created it, as an ISO 4217 code.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "target_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "One-off goals: the total to reach. `null` on a monthly goal.",
                        "examples": [
                            null
                        ]
                    },
                    "initial_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "One-off goals: what was already saved when the goal was created. `null` on a monthly goal.",
                        "examples": [
                            null
                        ]
                    },
                    "target_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "One-off goals: the day to reach the total by, or `null` for none.",
                        "examples": [
                            null
                        ]
                    },
                    "progress": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "One-off goals: where the goal stands. `saved` and `target` are amounts, `percentage` how much of the target is saved, `rate_per_day` what was added per day since the goal started, `status` (`completed`, `ahead`, `on_track` or `behind`, `null` without a target date) its pace against the target date, `expected_today` what that pace asks to have saved by now, `estimated_date` when the current rate reaches the target and `required_per_month` what is left to save each month to make the target date. `null` on a monthly goal.",
                        "examples": [
                            null
                        ],
                        "properties": {
                            "saved": {
                                "type": "integer"
                            },
                            "target": {
                                "type": "integer"
                            },
                            "percentage": {
                                "type": "number"
                            },
                            "target_date": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "rate_per_day": {
                                "type": "number"
                            },
                            "expected_today": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "status": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "estimated_date": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "required_per_month": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "saved",
                            "target",
                            "percentage",
                            "target_date",
                            "rate_per_day",
                            "expected_today",
                            "status",
                            "estimated_date",
                            "required_per_month"
                        ]
                    },
                    "monthly_target_type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Monthly goals: `amount` for a fixed sum each month, `income_rate` for a share of the average income of the three previous complete months, frozen when the month opens. `null` on a one-off goal.",
                        "enum": [
                            "amount",
                            "income_rate",
                            null
                        ],
                        "examples": [
                            "amount"
                        ]
                    },
                    "monthly_target_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Monthly goals with an `amount` target: the sum to save each month. `null` otherwise.",
                        "examples": [
                            30000
                        ]
                    },
                    "monthly_target_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Monthly goals with an `income_rate` target: the percentage of income to save each month. `null` otherwise.",
                        "examples": [
                            null
                        ]
                    },
                    "notify_on_month_end_reminder": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "Monthly goals: whether you get an email 5 days before the month ends while the month is short of its target. `null` on a one-off goal.",
                        "examples": [
                            true
                        ]
                    },
                    "auto_tag_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "Monthly goals: the savings account whose incoming transfers an automation rule tags to this goal, or `null` for none.",
                        "examples": [
                            "0199a3f3-7d2e-7c5f-8b9a-3e6d2c4b5a71"
                        ]
                    },
                    "monthly": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Monthly goals: each month judged against its own target, with nothing carried over between months. `current` is the month in progress (or `null`), with what is `remaining` and the `days_left`; `history` lists every month since the goal was created, oldest first. Each month has its `target`, `saved`, signed `difference`, `income_base` (the income an `income_rate` target was worked out from) and `status`: `met`, `missed`, `in_progress`, `partial` (the goal was created in the month's last 5 days) or `archived` (the goal was archived during it). A `partial` or `archived` month has no verdict and is left out of `months_met`, `months_closed`, `streak`, `best_streak` and `cumulative_difference`. A transaction tagged late recalculates the month it belongs to. `null` on a one-off goal.",
                        "examples": [
                            {
                                "current": {
                                    "month": "2026-10",
                                    "target": 30000,
                                    "saved": 25000,
                                    "difference": -5000,
                                    "status": "in_progress",
                                    "income_base": null,
                                    "remaining": 5000,
                                    "days_left": 29
                                },
                                "history": [
                                    {
                                        "month": "2026-09",
                                        "target": 30000,
                                        "saved": 32000,
                                        "difference": 2000,
                                        "status": "met",
                                        "income_base": null
                                    }
                                ],
                                "months_met": 1,
                                "months_closed": 1,
                                "cumulative_difference": 2000,
                                "streak": 1,
                                "best_streak": 1
                            }
                        ],
                        "properties": {
                            "current": {
                                "type": [
                                    "object",
                                    "null"
                                ],
                                "properties": {
                                    "month": {
                                        "type": "string"
                                    },
                                    "target": {
                                        "type": "integer"
                                    },
                                    "saved": {
                                        "type": "integer"
                                    },
                                    "difference": {
                                        "type": "integer"
                                    },
                                    "status": {
                                        "type": "string"
                                    },
                                    "income_base": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ]
                                    },
                                    "remaining": {
                                        "type": "integer"
                                    },
                                    "days_left": {
                                        "type": "integer"
                                    }
                                },
                                "required": [
                                    "month",
                                    "target",
                                    "saved",
                                    "difference",
                                    "status",
                                    "income_base",
                                    "remaining",
                                    "days_left"
                                ]
                            },
                            "history": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "month": {
                                            "type": "string"
                                        },
                                        "target": {
                                            "type": "integer"
                                        },
                                        "saved": {
                                            "type": "integer"
                                        },
                                        "difference": {
                                            "type": "integer"
                                        },
                                        "status": {
                                            "type": "string"
                                        },
                                        "income_base": {
                                            "type": [
                                                "integer",
                                                "null"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "month",
                                        "target",
                                        "saved",
                                        "difference",
                                        "status",
                                        "income_base"
                                    ]
                                }
                            },
                            "months_met": {
                                "type": "integer"
                            },
                            "months_closed": {
                                "type": "integer"
                            },
                            "cumulative_difference": {
                                "type": "integer"
                            },
                            "streak": {
                                "type": "integer"
                            },
                            "best_streak": {
                                "type": "integer"
                            }
                        },
                        "required": [
                            "current",
                            "history",
                            "months_met",
                            "months_closed",
                            "cumulative_difference",
                            "streak",
                            "best_streak"
                        ]
                    },
                    "archived_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the goal was archived in the app, or `null`. An archived goal keeps what it saved but can no longer change.",
                        "examples": [
                            null
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the goal was created.",
                        "examples": [
                            "2026-09-10T09:30:00+00:00"
                        ]
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the goal was last changed.",
                        "examples": [
                            "2026-10-03T18:05:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "name",
                    "kind",
                    "label_id",
                    "currency",
                    "target_amount",
                    "initial_amount",
                    "target_date",
                    "progress",
                    "monthly_target_type",
                    "monthly_target_amount",
                    "monthly_target_rate",
                    "notify_on_month_end_reminder",
                    "auto_tag_account_id",
                    "monthly",
                    "archived_at",
                    "created_at",
                    "updated_at"
                ],
                "title": "SavingsGoal"
            },
            "SavingsGoalKind": {
                "type": "string",
                "enum": [
                    "one_off",
                    "monthly"
                ],
                "title": "SavingsGoalKind"
            },
            "Space": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The space's id, which the `space` parameter takes.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "The space's name.",
                        "examples": [
                            "Personal"
                        ]
                    },
                    "personal": {
                        "type": "boolean",
                        "description": "Whether this is your personal space, the default when `space` is left out."
                    },
                    "owned": {
                        "type": "boolean",
                        "description": "Whether you own the space, rather than being a member of it."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the space was created.",
                        "examples": [
                            "2026-01-15T09:30:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "name",
                    "personal",
                    "owned",
                    "created_at"
                ],
                "title": "Space"
            },
            "SpendingByCategory": {
                "type": "object",
                "properties": {
                    "currency": {
                        "type": "string",
                        "description": "The currency of every amount: your account's currency, as an ISO 4217 code.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "total": {
                        "type": "integer",
                        "description": "What `categories` adds up to.",
                        "examples": [
                            105345
                        ]
                    },
                    "categories": {
                        "type": "array",
                        "description": "The expense categories with spending in the range, largest first, each with its subcategories rolled into it. Only the ones whose spending is above zero: a category that refunds took below zero is left out, and so are uncategorized transactions, so `total` can be above the cashflow's `expense` for the same range.",
                        "items": {
                            "$ref": "#/components/schemas/CategoryAmount"
                        }
                    }
                },
                "required": [
                    "currency",
                    "total",
                    "categories"
                ],
                "title": "SpendingByCategory"
            },
            "SplitTransactionRequest": {
                "type": "object",
                "properties": {
                    "splits": {
                        "type": "array",
                        "description": "The parts to replace the transaction with, 2 to 20 of them. Their amounts must add up to the transaction's amount exactly.",
                        "examples": [
                            [
                                {
                                    "amount": -3000,
                                    "category_id": "0199a3f5-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
                                    "label_ids": [
                                        "0199a3f7-3b4c-7d5e-8f6a-7b8c9d0e1f2a"
                                    ]
                                },
                                {
                                    "amount": -1250
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "amount": {
                                    "type": "integer",
                                    "description": "The part's signed amount, in the minor units of the transaction's currency. It has the sign of the original: the parts of an expense are all negative.",
                                    "examples": [
                                        -3000
                                    ]
                                },
                                "category_id": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "uuid",
                                    "description": "The id of the part's category, one of your categories in the space. Left out or `null`, the part is uncategorized."
                                },
                                "label_ids": {
                                    "type": [
                                        "array",
                                        "null"
                                    ],
                                    "description": "The ids of the part's labels, each one of your labels in the space, up to 100. Defaults to none: the original's labels are not copied.",
                                    "items": {
                                        "type": "string",
                                        "format": "uuid"
                                    },
                                    "maxItems": 100,
                                    "uniqueItems": true
                                }
                            },
                            "required": [
                                "amount"
                            ]
                        },
                        "minItems": 2,
                        "maxItems": 20
                    }
                },
                "required": [
                    "splits"
                ],
                "title": "SplitTransactionRequest"
            },
            "StatementFrequency": {
                "type": "string",
                "description": "How often a credit card statement closes: once a month on the same day, or once a week on the same weekday.\n",
                "enum": [
                    "monthly",
                    "weekly"
                ],
                "title": "StatementFrequency"
            },
            "StoreAccountBalanceRequest": {
                "type": "object",
                "properties": {
                    "balance": {
                        "type": "integer",
                        "description": "The balance, in the account currency's minor units.",
                        "examples": [
                            250000
                        ]
                    },
                    "balance_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The day the balance is for. Defaults to today.",
                        "examples": [
                            "2026-01-31"
                        ]
                    },
                    "invested_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "How much of the balance is money put in rather than gains, in minor units, for investment accounts. Left out, the one already recorded for that day stays."
                    }
                },
                "required": [
                    "balance"
                ],
                "title": "StoreAccountBalanceRequest"
            },
            "StoreAccountRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The account's name.",
                        "examples": [
                            "Main checking"
                        ]
                    },
                    "type": {
                        "type": "string",
                        "description": "The account type. `checking`, `credit_card`, `savings` and `others` keep a transaction ledger; `investment`, `retirement`, `loan` and `real_estate` track a balance only.",
                        "enum": [
                            "checking",
                            "credit_card",
                            "investment",
                            "loan",
                            "retirement",
                            "real_estate",
                            "savings",
                            "others"
                        ],
                        "examples": [
                            "checking"
                        ]
                    },
                    "currency_code": {
                        "type": "string",
                        "description": "The ISO 4217 currency the account is held in. Your first account also sets the currency your whole account is reported in, so it must be one of the primary currencies.",
                        "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "JPY",
                            "CHF",
                            "CZK",
                            "CAD",
                            "AUD",
                            "NZD",
                            "CNY",
                            "INR",
                            "PKR",
                            "MXN",
                            "ARS",
                            "BOB",
                            "CLP",
                            "PYG",
                            "PEN",
                            "UYU",
                            "VES",
                            "BRL",
                            "COP",
                            "DOP",
                            "SAR",
                            "KWD",
                            "BTC",
                            "RSD",
                            "NGN",
                            "GHS",
                            "SEK",
                            "GTQ",
                            "HNL",
                            "HKD",
                            "THB",
                            "DKK",
                            "SGD"
                        ],
                        "examples": [
                            "EUR"
                        ]
                    },
                    "bank_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The id of the bank the account is held at, for its name and logo. It does not connect anything."
                    },
                    "balance": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The balance today, in minor units. On a loan or a property it is also where the generated balance history ends. Refused on a credit card, which takes a `credit_limit` instead.",
                        "examples": [
                            125000
                        ]
                    },
                    "linked_real_estate_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "`loan` only: id of the `real_estate` account this loan is the mortgage of. The property must have its details set and not be linked to another loan yet."
                    },
                    "property_type": {
                        "type": "string",
                        "description": "`real_estate` only: what kind of property it is. Required when the property's details are first created.",
                        "enum": [
                            "residential",
                            "commercial",
                            "land",
                            "vacation",
                            "other"
                        ]
                    },
                    "address": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: the property's address.",
                        "maxLength": 500
                    },
                    "purchase_price": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`real_estate` only: what it was bought for, in minor units. With `purchase_date` and a `balance`, the value history in between is filled in.",
                        "minimum": 0
                    },
                    "purchase_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`real_estate` only: when it was bought. Not in the future, not before 1900."
                    },
                    "area_value": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`real_estate` only: floor area, in `area_unit`.",
                        "minimum": 0,
                        "maximum": 99999999.99
                    },
                    "area_unit": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: the unit of `area_value`.",
                        "enum": [
                            "sqm",
                            "sqft",
                            "acres",
                            "hectares",
                            null
                        ]
                    },
                    "revaluation_percentage": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`real_estate` only: expected yearly revaluation, as a percentage.",
                        "minimum": -100,
                        "maximum": 100
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: free-text notes on the property.",
                        "maxLength": 2000
                    },
                    "linked_loan_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "`real_estate` only: id of one of your `loan` accounts that is this property's mortgage."
                    },
                    "annual_interest_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`loan` only: yearly interest rate, as a percentage.",
                        "minimum": 0,
                        "maximum": 100
                    },
                    "loan_term_months": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`loan` only: the term, in months.",
                        "minimum": 1,
                        "maximum": 600
                    },
                    "original_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`loan` only: the amount originally borrowed, in minor units. A loan's details are created once `annual_interest_rate`, `loan_term_months` and `original_amount` are all known.",
                        "minimum": 0
                    },
                    "loan_start_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`loan` only: when the loan started. Defaults to today."
                    },
                    "statement_closing_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`credit_card` only: a statement closing date. Later cycles repeat from it at `statement_frequency`. Send it with `payment_due_date`; both `null` clears them."
                    },
                    "payment_due_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`credit_card` only: when that statement is charged. On or after the closing date, at most 45 days later on a monthly card and 7 on a weekly one."
                    },
                    "statement_frequency": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`credit_card` only: how often a statement closes. Left out, the stored one stays (monthly on a new card).",
                        "enum": [
                            "monthly",
                            "weekly",
                            null
                        ]
                    },
                    "credit_limit": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`credit_card` only: the card's credit limit, in minor units. `null` clears it.",
                        "minimum": 1,
                        "maximum": 1000000000000000
                    }
                },
                "required": [
                    "name",
                    "type",
                    "currency_code"
                ],
                "title": "StoreAccountRequest"
            },
            "StoreAutomationRuleRequest": {
                "type": "object",
                "properties": {
                    "title": {
                        "type": "string",
                        "description": "The rule's name.",
                        "examples": [
                            "Groceries"
                        ],
                        "maxLength": 255
                    },
                    "priority": {
                        "type": "integer",
                        "description": "The order the rule is evaluated in, lowest first. A new transaction gets the actions of the first rule it matches, and no other.",
                        "examples": [
                            10
                        ],
                        "minimum": 0,
                        "maximum": 2147483647
                    },
                    "conditions": {
                        "type": "object",
                        "description": "The conditions a transaction must meet, as one JsonLogic object. Amounts in here are in MAJOR units (`12.50`), unlike every other amount in the API, and signed: an expense is negative. Text is compared lowercased, so write values in lowercase. Only these operators are accepted: `and`, `or`, `!`, `==`, `!=`, `>`, `>=`, `<`, `<=`, `in` and `var`; and only these variables: `description`, `notes`, `creditor_name`, `debtor_name`, `account_name`, `bank_name`, `category`, `transaction_date` (`YYYY-MM-DD`) and `amount`. \"Contains\" is `{\"in\": [\"netflix\", {\"var\": \"description\"}]}`, a negation wraps a condition in `!`, and `and` / `or` take a list and nest freely. \"Is not\" and \"does not contain\" also match a transaction whose field is empty.",
                        "examples": [
                            {
                                "and": [
                                    {
                                        "in": [
                                            "mercadona",
                                            {
                                                "var": "description"
                                            }
                                        ]
                                    },
                                    {
                                        "<": [
                                            {
                                                "var": "amount"
                                            },
                                            0
                                        ]
                                    }
                                ]
                            }
                        ],
                        "additionalProperties": {}
                    },
                    "action_category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category to give the matching transactions, one of your categories in the space, or `null` for none. A rule needs a category, labels or both."
                    },
                    "action_label_ids": {
                        "type": "array",
                        "description": "The ids of the labels to add to the matching transactions, each one of your labels in the space, 50 at most. On update the list replaces the rule's labels; an empty one removes them all.",
                        "examples": [
                            [
                                "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                            ]
                        ],
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 50,
                        "uniqueItems": true
                    },
                    "action_note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A note to append to the matching transactions' notes, or `null` for none.",
                        "examples": [
                            "Weekly shop"
                        ],
                        "maxLength": 10000
                    }
                },
                "required": [
                    "title",
                    "priority",
                    "conditions"
                ],
                "title": "StoreAutomationRuleRequest"
            },
            "StoreBudgetRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The budget's name.",
                        "examples": [
                            "Groceries"
                        ],
                        "maxLength": 255
                    },
                    "allocated_amount": {
                        "type": "integer",
                        "description": "The limit for each period, in the minor units of your account's currency.",
                        "examples": [
                            50000
                        ],
                        "minimum": 0,
                        "maximum": 100000000000
                    },
                    "period_type": {
                        "description": "How often the budget starts over.",
                        "examples": [
                            "monthly"
                        ],
                        "$ref": "#/components/schemas/BudgetPeriodType"
                    },
                    "rollover_type": {
                        "description": "`carry_over` adds what is left at the end of a period to the next one, `reset` starts every period at the limit.",
                        "examples": [
                            "reset"
                        ],
                        "$ref": "#/components/schemas/RolloverType"
                    },
                    "period_start_day": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The day a period starts: the day of the month (1\u201331) for a monthly budget, the day of the week (0 is Sunday, 6 Saturday) for a weekly or biweekly one. Quarterly and yearly budgets follow the calendar and ignore it.",
                        "examples": [
                            1
                        ]
                    },
                    "expense_type": {
                        "description": "`fixed` for spending that repeats at the same amount every period (rent, subscriptions), `variable` (the default) for spending you can adjust. A catch-all budget is always `variable`.",
                        "examples": [
                            "variable"
                        ],
                        "$ref": "#/components/schemas/BudgetExpenseType"
                    },
                    "is_catch_all": {
                        "type": "boolean",
                        "description": "Track every expense category no other budget tracks. A catch-all budget takes no `category_ids` or `label_ids`, and an account has at most one.",
                        "examples": [
                            false
                        ]
                    },
                    "category_ids": {
                        "type": "array",
                        "description": "The ids of the categories to track, each one of your own, 100 at most. Tracking a parent also tracks its children. A budget needs at least one category or label, unless it is the catch-all.",
                        "examples": [
                            [
                                "0199a3f5-2b3c-7d4e-8f5a-6b7c8d9e0f12"
                            ]
                        ],
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 100,
                        "uniqueItems": true
                    },
                    "label_ids": {
                        "type": "array",
                        "description": "The ids of the labels to track, each one of your own, 100 at most.",
                        "examples": [
                            [
                                "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                            ]
                        ],
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 100,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "name",
                    "allocated_amount",
                    "period_type",
                    "rollover_type"
                ],
                "title": "StoreBudgetRequest"
            },
            "StoreCategoryRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The category's name, unique among its siblings: two categories can share a name only under different parents. Your categories at one level of the tree also need different names across all your spaces.",
                        "examples": [
                            "Groceries"
                        ],
                        "maxLength": 255
                    },
                    "icon": {
                        "type": "string",
                        "description": "The name of the icon the app shows for it, a Lucide icon name.",
                        "examples": [
                            "ShoppingBag"
                        ],
                        "maxLength": 255
                    },
                    "color": {
                        "description": "The category's color.",
                        "examples": [
                            "green"
                        ],
                        "$ref": "#/components/schemas/CategoryColor"
                    },
                    "type": {
                        "description": "What the category's transactions are: `income`, `expense`, `transfer`, `savings` or `investment`. Ignored on a child, which always takes its parent's type.",
                        "examples": [
                            "expense"
                        ],
                        "$ref": "#/components/schemas/CategoryType"
                    },
                    "cashflow_direction": {
                        "description": "How the category's transactions count in the cashflow. Only a root `transfer` category keeps the one you send: a `savings` or `investment` root is always `outflow`, any other root `hidden`, and a child takes its parent's.",
                        "examples": [
                            "outflow"
                        ],
                        "$ref": "#/components/schemas/CategoryCashflowDirection"
                    },
                    "parent_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category to nest it under, or `null` for a root. It must be one of your categories in the space. Categories nest up to 3 levels deep, and a category cannot sit under itself or one of its own children."
                    }
                },
                "required": [
                    "name",
                    "icon",
                    "color",
                    "type"
                ],
                "title": "StoreCategoryRequest"
            },
            "StoreLabelRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The label's name, unique within the space.",
                        "examples": [
                            "Holidays"
                        ],
                        "maxLength": 255
                    },
                    "color": {
                        "description": "The label's color.",
                        "examples": [
                            "blue"
                        ],
                        "$ref": "#/components/schemas/LabelColor"
                    }
                },
                "required": [
                    "name",
                    "color"
                ],
                "title": "StoreLabelRequest"
            },
            "StoreSavingsGoalRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The goal's name. It also names the label its contributions are tagged with, so it must not clash with one of your labels.",
                        "examples": [
                            "Emergency fund"
                        ],
                        "maxLength": 255
                    },
                    "kind": {
                        "description": "`one_off` to reach a total once, `monthly` to save towards a target every calendar month. Fixed once created.",
                        "examples": [
                            "monthly"
                        ],
                        "$ref": "#/components/schemas/SavingsGoalKind"
                    },
                    "auto_tag_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "Monthly goals: the id of one of your savings accounts in the goal's space. A new automation rule then tags the transfers into it to this goal, from the start of this month on. An account can feed only one running monthly goal."
                    },
                    "target_amount": {
                        "type": "integer",
                        "description": "One-off goals: the total to reach, in the minor units of your account's currency.",
                        "examples": [
                            1000000
                        ]
                    },
                    "initial_amount": {
                        "type": "integer",
                        "description": "One-off goals: what is already saved towards it, in minor units. Defaults to `0`.",
                        "examples": [
                            50000
                        ]
                    },
                    "target_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "One-off goals: the day to reach the total by, `YYYY-MM-DD`; in the future for a new goal. `null` clears it.",
                        "examples": [
                            "2027-06-30"
                        ]
                    },
                    "monthly_target_type": {
                        "description": "Monthly goals: `amount` for a fixed sum each month, `income_rate` for a share of the average income of the three previous complete months. Required on a new monthly goal, and on an edit alongside `monthly_target_amount` or `monthly_target_rate`; switching type clears the other value.",
                        "examples": [
                            "amount"
                        ],
                        "$ref": "#/components/schemas/MonthlyTargetType"
                    },
                    "monthly_target_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Monthly goals with an `amount` target: the sum to save each month, in minor units.",
                        "examples": [
                            30000
                        ]
                    },
                    "monthly_target_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Monthly goals with an `income_rate` target: the percentage of income to save each month, above 0 and up to 100, two decimals at most.",
                        "examples": [
                            15
                        ]
                    },
                    "notify_on_month_end_reminder": {
                        "type": "boolean",
                        "description": "Monthly goals: email a reminder 5 days before the month ends while the month is short of its target. A new goal defaults to your notification setting.",
                        "examples": [
                            true
                        ]
                    }
                },
                "required": [
                    "name",
                    "kind"
                ],
                "title": "StoreSavingsGoalRequest"
            },
            "StoreTransactionRequest": {
                "type": "object",
                "properties": {
                    "account_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id of the account the transaction is on: one of your accounts in the space, bank-connected ones included, since a sync never removes a transaction you added by hand.",
                        "examples": [
                            "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01"
                        ]
                    },
                    "description": {
                        "type": "string",
                        "description": "What the transaction was for.",
                        "examples": [
                            "Groceries at the market"
                        ],
                        "maxLength": 1000
                    },
                    "amount": {
                        "type": "integer",
                        "description": "The signed amount, in the minor units of `currency_code`: negative for an expense, positive for income.",
                        "examples": [
                            -4250
                        ]
                    },
                    "transaction_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The day the transaction happened.",
                        "examples": [
                            "2026-01-31"
                        ]
                    },
                    "currency_code": {
                        "type": "string",
                        "description": "The ISO 4217 currency the amount is in. Defaults to the account's.",
                        "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "JPY",
                            "CHF",
                            "CZK",
                            "CAD",
                            "AUD",
                            "NZD",
                            "CNY",
                            "INR",
                            "PKR",
                            "MXN",
                            "ARS",
                            "BOB",
                            "CLP",
                            "PYG",
                            "PEN",
                            "UYU",
                            "VES",
                            "BRL",
                            "COP",
                            "DOP",
                            "SAR",
                            "KWD",
                            "BTC",
                            "RSD",
                            "NGN",
                            "GHS",
                            "SEK",
                            "GTQ",
                            "HNL",
                            "HKD",
                            "THB",
                            "DKK",
                            "SGD"
                        ],
                        "examples": [
                            "EUR"
                        ]
                    },
                    "category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category, or `null` for none. Setting it marks the category as assigned by you, so the automatic categorization leaves it alone."
                    },
                    "creditor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who was paid, or `null`.",
                        "examples": [
                            "Fresh Market"
                        ],
                        "maxLength": 255
                    },
                    "debtor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who paid, or `null`.",
                        "maxLength": 255
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Free-text notes, or `null`.",
                        "maxLength": 10000
                    },
                    "update_balance": {
                        "type": "boolean",
                        "description": "Whether to move the account's balance snapshots by what this write changes. Has no effect on a bank-connected account, whose balances come from the bank, or on a credit card, which has a credit limit instead of a balance; `balance_updated` in the response says whether they moved. Defaults to `false`."
                    },
                    "label_ids": {
                        "type": "array",
                        "description": "The ids of the labels to tag the transaction with.",
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 100,
                        "uniqueItems": true
                    }
                },
                "required": [
                    "account_id",
                    "description",
                    "amount",
                    "transaction_date"
                ],
                "title": "StoreTransactionRequest"
            },
            "Transaction": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The transaction's id.",
                        "examples": [
                            "0199a3f8-4c5d-7e6f-8a9b-0c1d2e3f4a5b"
                        ]
                    },
                    "space_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the space the transaction is in, its account's.",
                        "examples": [
                            "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60"
                        ]
                    },
                    "account": {
                        "type": "object",
                        "description": "The account the transaction is on: its id and name.",
                        "examples": [
                            {
                                "id": "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01",
                                "name": "Main checking"
                            }
                        ],
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "transaction_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The day the transaction happened.",
                        "examples": [
                            "2026-01-31"
                        ]
                    },
                    "description": {
                        "type": "string",
                        "description": "What the transaction was for.",
                        "examples": [
                            "Groceries at the market"
                        ]
                    },
                    "amount": {
                        "type": "integer",
                        "description": "The signed amount, in the minor units of `currency`: negative for an expense, positive for income.",
                        "examples": [
                            -4250
                        ]
                    },
                    "currency": {
                        "type": "string",
                        "description": "The ISO 4217 currency the amount is in.",
                        "examples": [
                            "EUR"
                        ]
                    },
                    "category": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The category, if one is set: its id and name.",
                        "examples": [
                            {
                                "id": "0199a3f5-7a8b-7c9d-8e0f-1a2b3c4d5e6f",
                                "name": "Groceries"
                            }
                        ],
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "category_source": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who set the category: `manual` (you), `rule` (an automation rule), `ai` (the automatic categorization) or `bank`. `null` while there is none.",
                        "enum": [
                            "manual",
                            "rule",
                            "ai",
                            "bank",
                            null
                        ],
                        "examples": [
                            "manual"
                        ]
                    },
                    "labels": {
                        "type": "array",
                        "description": "The labels the transaction is tagged with: their ids and names.",
                        "examples": [
                            [
                                {
                                    "id": "0199a3f7-3b4c-7d5e-8f6a-7b8c9d0e1f2a",
                                    "name": "Holidays"
                                }
                            ]
                        ],
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "id",
                                "name"
                            ]
                        }
                    },
                    "source": {
                        "type": "string",
                        "description": "Where the transaction came from: `manually_created` (recorded by hand), `imported` (from a file), `enablebanking` or `wise` (a bank sync). Only a manually-created one can change its description, amount, currency, account or counterparty names; notes and the category can be changed on any, the date on any but one part of a split, and any but one part of a split can be deleted.",
                        "enum": [
                            "manually_created",
                            "imported",
                            "enablebanking",
                            "wise"
                        ],
                        "examples": [
                            "manually_created"
                        ]
                    },
                    "creditor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who was paid, or `null`.",
                        "examples": [
                            "Fresh Market"
                        ]
                    },
                    "debtor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who paid, or `null`.",
                        "examples": [
                            null
                        ]
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Free-text notes, or `null`.",
                        "examples": [
                            null
                        ]
                    },
                    "split_parent_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "Set when this transaction is one part of a split, otherwise `null`. Every part of the same split carries the same value. The split original is out of every list, and a part cannot be deleted or have its core fields changed on its own.",
                        "examples": [
                            null
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the transaction was recorded in Whisper Money.",
                        "examples": [
                            "2026-01-31T18:12:00+00:00"
                        ]
                    }
                },
                "required": [
                    "id",
                    "space_id",
                    "account",
                    "transaction_date",
                    "description",
                    "amount",
                    "currency",
                    "category",
                    "category_source",
                    "labels",
                    "source",
                    "creditor_name",
                    "debtor_name",
                    "notes",
                    "split_parent_id",
                    "created_at"
                ],
                "title": "Transaction"
            },
            "UpdateAccountRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The account's new name. The sync never rewrites it, so a bank-connected account can be renamed too.",
                        "examples": [
                            "Joint checking"
                        ]
                    },
                    "type": {
                        "type": "string",
                        "description": "The new account type. On a bank-connected account only `checking`, `credit_card`, `savings` and `others` are possible: the rest keep no transaction ledger for the sync to write into.",
                        "enum": [
                            "checking",
                            "credit_card",
                            "investment",
                            "loan",
                            "retirement",
                            "real_estate",
                            "savings",
                            "others"
                        ]
                    },
                    "currency_code": {
                        "type": "string",
                        "description": "The new ISO 4217 currency. Refused on a bank-connected account, whose currency comes from the bank.",
                        "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "JPY",
                            "CHF",
                            "CZK",
                            "CAD",
                            "AUD",
                            "NZD",
                            "CNY",
                            "INR",
                            "PKR",
                            "MXN",
                            "ARS",
                            "BOB",
                            "CLP",
                            "PYG",
                            "PEN",
                            "UYU",
                            "VES",
                            "BRL",
                            "COP",
                            "DOP",
                            "SAR",
                            "KWD",
                            "BTC",
                            "RSD",
                            "NGN",
                            "GHS",
                            "SEK",
                            "GTQ",
                            "HNL",
                            "HKD",
                            "THB",
                            "DKK",
                            "SGD"
                        ]
                    },
                    "bank_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The new bank id, or `null` to clear it. Refused on a bank-connected account, whose bank comes from the connection."
                    },
                    "ownership_percentage": {
                        "type": "integer",
                        "description": "Your share of the account, 1 to 100. Below 100 only that slice counts in your figures, and the budgets that already counted the account are reweighed.",
                        "examples": [
                            50
                        ],
                        "minimum": 1,
                        "maximum": 100
                    },
                    "ownership_applies_to_balance": {
                        "type": "boolean",
                        "description": "Whether the ownership share applies to the balance too, not only to transactions."
                    },
                    "property_type": {
                        "type": "string",
                        "description": "`real_estate` only: what kind of property it is. Required when the property's details are first created.",
                        "enum": [
                            "residential",
                            "commercial",
                            "land",
                            "vacation",
                            "other"
                        ]
                    },
                    "address": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: the property's address.",
                        "maxLength": 500
                    },
                    "purchase_price": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`real_estate` only: what it was bought for, in minor units. With `purchase_date` and a `balance`, the value history in between is filled in.",
                        "minimum": 0
                    },
                    "purchase_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`real_estate` only: when it was bought. Not in the future, not before 1900."
                    },
                    "area_value": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`real_estate` only: floor area, in `area_unit`.",
                        "minimum": 0,
                        "maximum": 99999999.99
                    },
                    "area_unit": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: the unit of `area_value`.",
                        "enum": [
                            "sqm",
                            "sqft",
                            "acres",
                            "hectares",
                            null
                        ]
                    },
                    "revaluation_percentage": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`real_estate` only: expected yearly revaluation, as a percentage.",
                        "minimum": -100,
                        "maximum": 100
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`real_estate` only: free-text notes on the property.",
                        "maxLength": 2000
                    },
                    "linked_loan_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "`real_estate` only: id of one of your `loan` accounts that is this property's mortgage."
                    },
                    "annual_interest_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "`loan` only: yearly interest rate, as a percentage.",
                        "minimum": 0,
                        "maximum": 100
                    },
                    "loan_term_months": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`loan` only: the term, in months.",
                        "minimum": 1,
                        "maximum": 600
                    },
                    "original_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`loan` only: the amount originally borrowed, in minor units. A loan's details are created once `annual_interest_rate`, `loan_term_months` and `original_amount` are all known.",
                        "minimum": 0
                    },
                    "loan_start_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`loan` only: when the loan started. Defaults to today."
                    },
                    "statement_closing_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`credit_card` only: a statement closing date. Later cycles repeat from it at `statement_frequency`. Send it with `payment_due_date`; both `null` clears them."
                    },
                    "payment_due_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "`credit_card` only: when that statement is charged. On or after the closing date, at most 45 days later on a monthly card and 7 on a weekly one."
                    },
                    "statement_frequency": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "`credit_card` only: how often a statement closes. Left out, the stored one stays (monthly on a new card).",
                        "enum": [
                            "monthly",
                            "weekly",
                            null
                        ]
                    },
                    "credit_limit": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "`credit_card` only: the card's credit limit, in minor units. `null` clears it.",
                        "minimum": 1,
                        "maximum": 1000000000000000
                    }
                },
                "title": "UpdateAccountRequest"
            },
            "UpdateAutomationRuleRequest": {
                "type": "object",
                "properties": {
                    "title": {
                        "type": "string",
                        "description": "The rule's name.",
                        "examples": [
                            "Groceries"
                        ],
                        "maxLength": 255
                    },
                    "priority": {
                        "type": "integer",
                        "description": "The order the rule is evaluated in, lowest first. A new transaction gets the actions of the first rule it matches, and no other.",
                        "examples": [
                            10
                        ],
                        "minimum": 0,
                        "maximum": 2147483647
                    },
                    "conditions": {
                        "type": "object",
                        "description": "The conditions a transaction must meet, as one JsonLogic object. Amounts in here are in MAJOR units (`12.50`), unlike every other amount in the API, and signed: an expense is negative. Text is compared lowercased, so write values in lowercase. Only these operators are accepted: `and`, `or`, `!`, `==`, `!=`, `>`, `>=`, `<`, `<=`, `in` and `var`; and only these variables: `description`, `notes`, `creditor_name`, `debtor_name`, `account_name`, `bank_name`, `category`, `transaction_date` (`YYYY-MM-DD`) and `amount`. \"Contains\" is `{\"in\": [\"netflix\", {\"var\": \"description\"}]}`, a negation wraps a condition in `!`, and `and` / `or` take a list and nest freely. \"Is not\" and \"does not contain\" also match a transaction whose field is empty.",
                        "examples": [
                            {
                                "and": [
                                    {
                                        "in": [
                                            "mercadona",
                                            {
                                                "var": "description"
                                            }
                                        ]
                                    },
                                    {
                                        "<": [
                                            {
                                                "var": "amount"
                                            },
                                            0
                                        ]
                                    }
                                ]
                            }
                        ],
                        "additionalProperties": {}
                    },
                    "action_category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category to give the matching transactions, one of your categories in the space, or `null` for none. A rule needs a category, labels or both."
                    },
                    "action_label_ids": {
                        "type": "array",
                        "description": "The ids of the labels to add to the matching transactions, each one of your labels in the space, 50 at most. On update the list replaces the rule's labels; an empty one removes them all.",
                        "examples": [
                            [
                                "0199a3f6-3c4d-7e5f-9a6b-7c8d9e0f1a23"
                            ]
                        ],
                        "items": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "maxItems": 50,
                        "uniqueItems": true
                    },
                    "action_note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A note to append to the matching transactions' notes, or `null` for none.",
                        "examples": [
                            "Weekly shop"
                        ],
                        "maxLength": 10000
                    }
                },
                "title": "UpdateAutomationRuleRequest"
            },
            "UpdateBudgetRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The budget's new name.",
                        "examples": [
                            "Food"
                        ],
                        "maxLength": 255
                    },
                    "allocated_amount": {
                        "type": "integer",
                        "description": "The new limit, in the minor units of your account's currency. It applies to the period in progress and every later one; past periods keep theirs.",
                        "examples": [
                            60000
                        ],
                        "minimum": 0,
                        "maximum": 100000000000
                    },
                    "expense_type": {
                        "description": "`fixed` or `variable`. A catch-all budget stays `variable` whatever you send.",
                        "examples": [
                            "fixed"
                        ],
                        "$ref": "#/components/schemas/BudgetExpenseType"
                    }
                },
                "title": "UpdateBudgetRequest"
            },
            "UpdateCategoryRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The category's name, unique among its siblings: two categories can share a name only under different parents. Your categories at one level of the tree also need different names across all your spaces.",
                        "examples": [
                            "Groceries"
                        ],
                        "maxLength": 255
                    },
                    "icon": {
                        "type": "string",
                        "description": "The name of the icon the app shows for it, a Lucide icon name.",
                        "examples": [
                            "ShoppingBag"
                        ],
                        "maxLength": 255
                    },
                    "color": {
                        "description": "The category's color.",
                        "examples": [
                            "green"
                        ],
                        "$ref": "#/components/schemas/CategoryColor"
                    },
                    "type": {
                        "description": "What the category's transactions are: `income`, `expense`, `transfer`, `savings` or `investment`. Ignored on a child, which always takes its parent's type.",
                        "examples": [
                            "expense"
                        ],
                        "$ref": "#/components/schemas/CategoryType"
                    },
                    "cashflow_direction": {
                        "description": "How the category's transactions count in the cashflow. Only a root `transfer` category keeps the one you send: a `savings` or `investment` root is always `outflow`, any other root `hidden`, and a child takes its parent's.",
                        "examples": [
                            "outflow"
                        ],
                        "$ref": "#/components/schemas/CategoryCashflowDirection"
                    },
                    "parent_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category to nest it under, or `null` for a root. It must be one of your categories in the space. Categories nest up to 3 levels deep, and a category cannot sit under itself or one of its own children."
                    }
                },
                "title": "UpdateCategoryRequest"
            },
            "UpdateLabelRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The label's name, unique within the space.",
                        "examples": [
                            "Holidays"
                        ],
                        "maxLength": 255
                    },
                    "color": {
                        "description": "The label's color.",
                        "examples": [
                            "blue"
                        ],
                        "$ref": "#/components/schemas/LabelColor"
                    }
                },
                "title": "UpdateLabelRequest"
            },
            "UpdateSavingsGoalRequest": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The goal's name. It also names the label its contributions are tagged with, so it must not clash with one of your labels.",
                        "examples": [
                            "Emergency fund"
                        ],
                        "maxLength": 255
                    },
                    "target_amount": {
                        "type": "integer",
                        "description": "One-off goals: the total to reach, in the minor units of your account's currency.",
                        "examples": [
                            1000000
                        ]
                    },
                    "initial_amount": {
                        "type": "integer",
                        "description": "One-off goals: what is already saved towards it, in minor units. Defaults to `0`.",
                        "examples": [
                            50000
                        ]
                    },
                    "target_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "One-off goals: the day to reach the total by, `YYYY-MM-DD`; in the future for a new goal. `null` clears it.",
                        "examples": [
                            "2027-06-30"
                        ]
                    },
                    "monthly_target_type": {
                        "description": "Monthly goals: `amount` for a fixed sum each month, `income_rate` for a share of the average income of the three previous complete months. Required on a new monthly goal, and on an edit alongside `monthly_target_amount` or `monthly_target_rate`; switching type clears the other value.",
                        "examples": [
                            "amount"
                        ],
                        "$ref": "#/components/schemas/MonthlyTargetType"
                    },
                    "monthly_target_amount": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Monthly goals with an `amount` target: the sum to save each month, in minor units.",
                        "examples": [
                            30000
                        ]
                    },
                    "monthly_target_rate": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Monthly goals with an `income_rate` target: the percentage of income to save each month, above 0 and up to 100, two decimals at most.",
                        "examples": [
                            15
                        ]
                    },
                    "notify_on_month_end_reminder": {
                        "type": "boolean",
                        "description": "Monthly goals: email a reminder 5 days before the month ends while the month is short of its target. A new goal defaults to your notification setting.",
                        "examples": [
                            true
                        ]
                    }
                },
                "title": "UpdateSavingsGoalRequest"
            },
            "UpdateTransactionRequest": {
                "type": "object",
                "properties": {
                    "account_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id of the account the transaction is on: one of your accounts in the space, bank-connected ones included, since a sync never removes a transaction you added by hand.",
                        "examples": [
                            "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01"
                        ]
                    },
                    "description": {
                        "type": "string",
                        "description": "What the transaction was for.",
                        "examples": [
                            "Groceries at the market"
                        ],
                        "maxLength": 1000
                    },
                    "amount": {
                        "type": "integer",
                        "description": "The signed amount, in the minor units of `currency_code`: negative for an expense, positive for income.",
                        "examples": [
                            -4250
                        ]
                    },
                    "transaction_date": {
                        "type": "string",
                        "format": "date",
                        "description": "The day the transaction happened.",
                        "examples": [
                            "2026-01-31"
                        ]
                    },
                    "currency_code": {
                        "type": "string",
                        "description": "The ISO 4217 currency the amount is in. Defaults to the account's.",
                        "enum": [
                            "USD",
                            "EUR",
                            "GBP",
                            "JPY",
                            "CHF",
                            "CZK",
                            "CAD",
                            "AUD",
                            "NZD",
                            "CNY",
                            "INR",
                            "PKR",
                            "MXN",
                            "ARS",
                            "BOB",
                            "CLP",
                            "PYG",
                            "PEN",
                            "UYU",
                            "VES",
                            "BRL",
                            "COP",
                            "DOP",
                            "SAR",
                            "KWD",
                            "BTC",
                            "RSD",
                            "NGN",
                            "GHS",
                            "SEK",
                            "GTQ",
                            "HNL",
                            "HKD",
                            "THB",
                            "DKK",
                            "SGD"
                        ],
                        "examples": [
                            "EUR"
                        ]
                    },
                    "category_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uuid",
                        "description": "The id of the category, or `null` for none. Setting it marks the category as assigned by you, so the automatic categorization leaves it alone."
                    },
                    "creditor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who was paid, or `null`.",
                        "examples": [
                            "Fresh Market"
                        ],
                        "maxLength": 255
                    },
                    "debtor_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who paid, or `null`.",
                        "maxLength": 255
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Free-text notes, or `null`.",
                        "maxLength": 10000
                    },
                    "update_balance": {
                        "type": "boolean",
                        "description": "Whether to move the account's balance snapshots by what this write changes. Has no effect on a bank-connected account, whose balances come from the bank, or on a credit card, which has a credit limit instead of a balance; `balance_updated` in the response says whether they moved. Defaults to `false`."
                    }
                },
                "title": "UpdateTransactionRequest"
            }
        },
        "responses": {
            "Unauthenticated": {
                "description": "No bearer token, or one that is unknown, expired or revoked.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "Unauthenticated.",
                            "code": "unauthenticated"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "The token lacks the scope (`insufficient_scope`), the account has no Pro plan (`plan_required`, with a `subscribe_url`) or it is a shared demo account (`shared_account`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "This token is read-only. Create a read & write token to make changes.",
                            "code": "insufficient_scope"
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "The rate limit is exhausted. Wait the seconds in `Retry-After`.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "Too Many Attempts.",
                            "code": "too_many_requests"
                        }
                    }
                },
                "headers": {
                    "Retry-After": {
                        "$ref": "#/components/headers/Retry-After"
                    }
                }
            },
            "BadRequest": {
                "description": "A malformed request: an unknown pagination cursor (`invalid_cursor`) or an invalid `Idempotency-Key` (`invalid_idempotency_key`).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "No object with id 3f1e1a4c-1b2d-4c5e-9f00-1a2b3c4d5e6f exists in this list.",
                            "code": "invalid_cursor"
                        }
                    }
                }
            },
            "ValidationError": {
                "description": "The request failed validation.",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "The first error, and how many more there are."
                                },
                                "errors": {
                                    "type": "object",
                                    "description": "Every invalid field, with its messages.",
                                    "additionalProperties": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                }
                            },
                            "required": [
                                "message",
                                "errors"
                            ]
                        },
                        "example": {
                            "message": "You do not have access to a space with id 0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60. List the valid ids with GET /api/v1/spaces.",
                            "errors": {
                                "space": [
                                    "You do not have access to a space with id 0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60. List the valid ids with GET /api/v1/spaces."
                                ]
                            }
                        }
                    }
                }
            },
            "ValidationException": {
                "description": "Validation error",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "message": {
                                    "type": "string",
                                    "description": "Errors overview."
                                },
                                "errors": {
                                    "type": "object",
                                    "description": "A detailed description of each field that failed validation.",
                                    "additionalProperties": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                }
                            },
                            "required": [
                                "message",
                                "errors"
                            ]
                        }
                    }
                }
            },
            "IdempotencyConflict": {
                "description": "A request with the same `Idempotency-Key` is still being processed.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "A request with this Idempotency-Key is still being processed.",
                            "code": "idempotency_conflict"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No object with that id exists, or it belongs to someone else.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "Not Found",
                            "code": "not_found"
                        }
                    }
                }
            }
        },
        "headers": {
            "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                    "type": "integer"
                },
                "example": 42
            },
            "X-RateLimit-Limit": {
                "description": "Requests allowed per minute.",
                "schema": {
                    "type": "integer"
                },
                "example": 60
            },
            "X-RateLimit-Remaining": {
                "description": "Requests left in the current minute.",
                "schema": {
                    "type": "integer"
                },
                "example": 59
            }
        }
    }
}