openapi: 3.0.2 info: title: Lunch Money API - v2 description: |- Welcome to the Lunch Money v2 API. The API is available at `https://api.lunchmoney.dev/v2`. Get your access token from the [Lunch Money developers page](https://my.lunchmoney.app/developers). ### Introduction The v2 API is in open alpha and is still subject to change. Use the mock server or a test budget when getting started. **Static Mock Server** Explore the API without an access token or risk to real data. Select **"Static Mock v2 Lunch Money API Server"** from the Server dropdown, then set your Bearer token to any string with 11 or more characters. **Migrating from v1** The v2 API is not backwards compatible with v1. See the [Migration Guide](https://alpha.lunchmoney.dev/v2/migration-guide) for details. **Useful links** - [Developer Portal](https://lunchmoney.dev/v2/introduction) - [Getting Started Guide](https://lunchmoney.dev/v2/getting-started) - [v2 API Overview](https://lunchmoney.dev/v2/overview) - [v2 API Changelog](https://lunchmoney.dev/v2/changelog) - [Migration Guide](https://lunchmoney.dev/v2/migration-guide) - [Rate Limits](https://lunchmoney.dev/v2/rate-limits) termsOfService: https://lunchmoney.dev/#current-status contact: email: devsupport@lunchmoney.app license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 2.9.4 servers: - url: https://api.lunchmoney.dev/v2 description: v2 Lunch Money API Server - changes will affect real data! - url: https://mock.lunchmoney.dev/v2 description: Static mock version of the v2 Lunch Money API Server tags: - name: me description: View details and settings for the current user and account - name: categories description: Work with categories externalDocs: description: Learn more about categories url: https://support.lunchmoney.app/setup/categories - name: manual_accounts description: Work with manually managed accounts (formerly called assets) externalDocs: description: Learn more about manual accounts url: https://support.lunchmoney.app/setup/linked-accounts#how-are-manually-managed-account-balances-updated - name: plaid_accounts description: Work with accounts synced through Plaid externalDocs: description: Learn more about synced accounts url: https://support.lunchmoney.app/setup/linked-accounts#how-often-should-i-expect-new-transactions-to-get-imported - name: recurring_items description: Work with recurring items externalDocs: url: https://support.lunchmoney.app/finances/recurring-items - name: tags description: Work with tags externalDocs: description: Learn more about tags url: https://support.lunchmoney.app/setup/tags - name: transactions description: Work with transactions externalDocs: description: Learn more about transactions url: https://support.lunchmoney.app/finances/transactions - name: transactions (bulk) description: Perform bulk actions on transactions externalDocs: description: Learn more about transactions url: https://support.lunchmoney.app/finances/transactions - name: transactions (group) description: Group or ungroup transactions externalDocs: description: Learn more about transactions url: https://support.lunchmoney.app/finances/transactions - name: transactions (split) description: Split or unsplit transactions externalDocs: description: Learn more about transactions url: https://support.lunchmoney.app/finances/transactions - name: transactions (files) description: Manage files attached to transactions externalDocs: description: Learn more about transactions url: https://support.lunchmoney.app/finances/transactions - name: budgets description: View settings and modify budget amounts.

Use the [/summary](#tag/summary) endpoint to view the budget details performance. externalDocs: description: Learn more about budgets url: https://support.lunchmoney.app/finances/budgets - name: summary description: View a summary of the user's budget components: schemas: userObject: type: object title: user object (returned by /me) additionalProperties: false properties: name: type: string description: The user's name email: type: string description: The user's email id: type: integer format: int32 description: Unique ID for the user account_id: type: integer format: int64 description: Unique ID for the linked budgeting account budget_name: type: string description: Name of the linked budgeting account primary_currency: description: Primary currency set in the user's settings allOf: - $ref: "#/components/schemas/currencyEnum" api_key_label: type: string nullable: true description: Label assigned by the user to the API key being used. Returns null if no label is set required: - name - email - id - account_id - budget_name - primary_currency - api_key_label categoryObject: type: object title: category object additionalProperties: false properties: id: type: integer format: int32 nullable: false description: System defined unique ID for the category name: type: string nullable: false description: The name of the category. minLength: 1 maxLength: 100 description: type: string nullable: true description: The description of the category or `null` if not set. maxLength: 200 is_income: type: boolean nullable: false description: 'If `true`, the transactions in this category will be treated as income. (See Category Properties for more details)' exclude_from_budget: type: boolean nullable: false description: 'If `true`, the transactions in this category will be excluded from the budget. (See Category Properties for more details)' exclude_from_totals: type: boolean nullable: false description: 'If `true`, the transactions in this category will be excluded from totals. (See Category Properties for more details)' updated_at: type: string format: date-time nullable: false description: The date and time of when the category was last updated (in the ISO 8601 extended format). created_at: type: string format: date-time nullable: false description: The date and time of when the category was created (in the ISO 8601 extended format). group_id: type: integer format: int64 nullable: true description: The ID of the category group this category belongs to or `null` if the category doesn't belong to a group, or is itself a category group. is_group: type: boolean description: If `true`, the category is created as a category group. children: type: array items: $ref: "#/components/schemas/childCategoryObject" description: For category groups, this will populate with details about the categories that belong to this group. The objects in this array are similar to Category Objects but do not include the `is_income`, `exclude_from_budget`, and `exclude_from_totals` properties as these are inherited from the category group. In addition, the `is_group` property will always be `false`, and there will be no `children` attribute. archived: type: boolean description: If true, the category is archived and not displayed in relevant areas of the Lunch Money app. archived_at: type: string format: date-time nullable: true description: The date and time of when the category was last archived (in the ISO 8601 extended format). order: type: integer nullable: true default: null description: "An integer specifying the position in which the category is displayed on the categories page in the Lunch Money GUI. For categories within a category group the order is relative to the other categories within the group.
Categories with `order: null` will be displayed in alphabetical order by name, prior to any categories with an order" collapsed: type: boolean nullable: false default: false description: If `true`, the category is collapsed in the Lunch Money GUI. required: - id - name - description - is_income - exclude_from_budget - exclude_from_totals - updated_at - created_at - group_id - is_group - archived - archived_at - order - collapsed # The childCategoryObject is basically a categoryObject that has no # `children` attribute. We create this to ensure that no categories # are added to a category group if they have children and are a group childCategoryObject: type: object x-internal: true # Don't display in schemas section of docs additionalProperties: false properties: id: type: integer format: int32 nullable: false description: A system defined unique identifier for the category. name: type: string nullable: false description: The name of the category. minLength: 1 maxLength: 100 description: type: string nullable: true description: The description of the category or `null` if not set. maxLength: 200 is_income: type: boolean nullable: false description: If true, the transactions in this category will be treated as income. Inherited from Category Group. exclude_from_budget: type: boolean nullable: false description: If true, the transactions in this category will be excluded from the budget. Inherited from Category Group. exclude_from_totals: type: boolean nullable: false description: If true, the transactions in this category will be excluded from totals. Inherited from Category Group. updated_at: type: string format: date-time nullable: false description: The date and time of when the category was last updated (in the ISO 8601 extended format). created_at: type: string format: date-time nullable: false description: The date and time of when the category was created (in the ISO 8601 extended format). group_id: type: integer format: int64 nullable: true description: The ID of the category group this category belongs to or `null` if the category doesn't belong to a group, or is itself a category group. is_group: type: boolean enum: - false description: Will always be false for a category that is part of category group. archived: type: boolean description: If true, the category is archived and not displayed in relevant areas of the Lunch Money app. archived_at: type: string format: date-time nullable: true description: The date and time of when the category was last archived (in the ISO 8601 extended format). order: type: integer nullable: true description: An index specifying the position in which the category is displayed on the categories page in the Lunch Money GUI. For categories within a category group the order is relative to the other categories within the group.
API. collapsed: type: boolean nullable: true description: If `true`, the category is collapsed in the Lunch Money GUI. required: - id - name - description - is_income - exclude_from_budget - exclude_from_totals - updated_at - created_at - group_id - is_group - archived - archived_at - order # The request object for POST /categories # Prevent user from submitting any system created fields in a POST request createCategoryRequestObject: type: object additionalProperties: false x-internal: true properties: name: type: string nullable: false description: >- The name of the new category. Must be between 1 and 100 characters. Must not match the name of any existing categories or category groups. minLength: 1 maxLength: 100 description: type: string nullable: true default: null description: The description of the category. Must not exceed 200 characters. minLength: 0 # Allow empty strings maxLength: 200 is_income: type: boolean nullable: false default: false description: If `true`, the transactions in this category will be treated as income. (See Category Properties for more details) exclude_from_budget: type: boolean nullable: false default: false description: If `true`, the transactions in this category will be excluded from the budget. (See Category Properties for more details) exclude_from_totals: type: boolean nullable: false default: false description: If `true`, the transactions in this category will be excluded from totals. (See Category Properties for more details) is_group: type: boolean nullable: false default: false description: If `true`, the category is created as a category group. group_id: type: integer format: int64 nullable: true default: null description: If set to the ID of an existing category group, this new category will be assigned to that group. Cannot be set if `is_group` is true. archived: type: boolean default: false description: If `true`, the category is archived and not displayed in relevant areas of the Lunch Money app. children: type: array nullable: false description: The list of existing category objects, or existing category IDs or names of new categories to add to the new category group. This attribute should only be set if `is_group` is also set to true.
The categories or IDs specified must already exist and may not be category groups themselves. Categories that already belong to another category group will be moved. If strings are specified, they will be used as the names of new categories that will be added to the new category group. The request will fail if any names are the same as the name of an existing category.
It is permissible to provide both full category objects and IDs as well as strings for names in the same request. items: oneOf: - type: integer description: "ID of an existing category." - type: string description: "Name of a new child category to be created." maxLength: 100 - $ref: "#/components/schemas/categoryObject" order: type: integer nullable: true description: An index specifying the position in which the category is displayed on the categories page in the Lunch Money GUI. For categories within a category group the order is relative to the other categories within the group.
While this property can be set via the API it is generally set by the user in the Lunch Money GUI. API. collapsed: type: boolean nullable: true description: If `true`, the category is collapsed in the Lunch Money GUI.
While this property can be set via the API it is generally set by the user in the Lunch Money GUI. required: - name # Request object for a PUT /categories/:id request # Tolerates a request object that includes system created fields from a # previous GET request, but these are essentially ignored updateCategoryRequestObject: type: object x-internal: true additionalProperties: false properties: name: type: string nullable: false description: If set, the new name of the category. Must be between 1 and 100 characters. minLength: 1 maxLength: 100 x-updatable: true description: type: string nullable: true description: If set, the new description of the category. Must not exceed 200 characters. minLength: 0 # Allow empty strings maxLength: 200 x-updatable: true is_income: type: boolean nullable: false description: If set, will indicate if this category will be treated as income. (See Category Properties for more details) x-updatable: true exclude_from_budget: type: boolean nullable: false description: If set, will indicate if this category will be excluded from budgets. (See Category Properties for more details) x-updatable: true exclude_from_totals: type: boolean nullable: false description: If set, will indicate if this category will be excluded from totals. (See Category Properties for more details) x-updatable: true archived: type: boolean description: If set, will indicate if this category is archived. x-updatable: true group_id: type: integer format: int64 nullable: true description: If set to the ID of an existing category group, and this category is not itself a category group, this category will be a child of the specified group. x-updatable: true is_group: type: boolean nullable: true default: false description: This attribute may not be set to a value that is different than the current status of the category or category group. In other words, this API may not be used to convert a category to a category group or vice versa. children: type: array nullable: false description: The list of existing category objects, or existing category IDs or names of new categories to add to the new category group. This attribute should only be set if modifying an existing category group.
The categories or IDs specified must already exist and not belong to an existing category group. Categories that already belong to another category group will be moved. If strings are specified, they will be used as the names of new categories that will be added to the new category group. The request will fail if any names are the same as the name of an existing category.
It is permissible to provide both full category objects and IDs as well as strings for names in the same request. x-updatable: true items: oneOf: - type: integer description: "ID of an existing category." - type: string description: "Name of a new child category to be created." maxLength: 100 - $ref: "#/components/schemas/categoryObject" order: type: integer nullable: true description: An index specifying the position in which the category is displayed on the categories page in the Lunch Money GUI. For categories within a category group the order is relative to the other categories within the group.
While this property can be set via the API it is generally set by the user in the Lunch Money GUI. API. x-updatable: true collapsed: type: boolean nullable: true description: If `true`, the category is collapsed in the Lunch Money GUI.
While this property can be set via the API it is generally set by the user in the Lunch Money GUI. x-updatable: true id: type: integer format: int64 description: System defined unique identifier for the category. Ignored if set. x-updatable: false archived_at: type: string format: date-time nullable: true description: If set, updates the archived timestamp for the category. Provide an ISO 8601 extended datetime or `null` to clear it. x-updatable: true updated_at: type: string format: date-time nullable: false description: System set date and time of when the category was last updated (in the ISO 8601 extended format). Ignored if set. x-updatable: false created_at: type: string format: date-time nullable: false description: System set date and time of when the category was created (in the ISO 8601 extended format). Ignored if set. (in the ISO 8601 extended format). Ignored if set. x-updatable: false # The response object for a DELETE /category request with dependencies deleteCategoryResponseWithDependencies: type: object x-internal: true additionalProperties: false properties: category_name: type: string description: The name of the category dependents: type: object properties: budget: type: integer description: The number of budgets depending on the category category_rules: type: integer description: The number of category rules depending on the category transactions: type: integer description: The number of transactions depending on the category children: type: integer description: The number of child categories in the category group recurring: type: integer description: The number of recurring transactions depending on the category plaid_cats: type: integer description: The number of auto created categories based on Plaid categories required: - budget - category_rules - transactions - children - recurring - plaid_cats required: - category_name - dependents # The object containing information about a manual account manualAccountObject: type: object title: manual account object additionalProperties: false description: An object containing information about a manual account properties: id: type: integer format: int32 description: The unique identifier of this account name: type: string description: Name of the account minLength: 1 maxLength: 45 institution_name: type: string nullable: true minLength: 1 maxLength: 50 description: Name of institution holding the account display_name: type: string nullable: true description: Optional display name for the account as set by the user or derived from the `institution_name` and `name` if not explicitly set. type: description: Primary type of the account allOf: - $ref: "#/components/schemas/accountTypeEnum" subtype: type: string nullable: true description: Optional account subtype. Examples include
- retirement - checking - savings - prepaid credit card minLength: 1 maxLength: 100 balance: type: string pattern: ^-?\d+(\.\d{1,4})?$ description: Current balance of the account in numeric format to 4 decimal places currency: type: string minLength: 3 maxLength: 3 description: Three-letter lowercase currency code of the account balance to_base: type: number description: The balance converted to the user's primary currency balance_as_of: type: string format: date-time description: Date balance was last updated in ISO 8601 extended format, can be in date or date-time format status: type: string description: The status of the account enum: - active - closed closed_on: type: string format: date nullable: true description: The date this account was closed in YYYY-MM-DD format. Will be null if the account has not been marked as closed. external_id: type: string nullable: true minLength: 0 maxLength: 75 description: An optional external_id that may be set or updated via the API custom_metadata: type: object nullable: true description: User defined JSON data that can be set or cleared via the API additionalProperties: true exclude_from_transactions: type: boolean default: false description: If true, this account will not show up as an option for assignment when creating transactions manually created_by_name: type: string description: The name of the user who created the account created_at: type: string format: date-time description: Date/time the account was created in ISO 8601 extended format updated_at: type: string format: date-time description: Date/time the account was created in ISO 8601 extended format required: - id - name - type - subtype - display_name - balance - currency - to_base - balance_as_of - closed_on - institution_name - external_id - exclude_from_transactions - created_by_name - created_at - updated_at - status # The object that may be submitted to POST /manual_accounts createManualAccountRequestObject: type: object additionalProperties: false x-internal: true properties: name: type: string description: Name of the manual account minLength: 1 maxLength: 45 example: My Savings Account institution_name: type: string example: Bank of the West description: Name of institution holding the manual account minLength: 1 maxLength: 50 display_name: type: string description: Display name of the manual account as set by user or derived from the `institution_name` and `name` if not explicitly set.
This must be unique for the budgeting account. example: Savings type: description: The type of manual account allOf: - $ref: "#/components/schemas/accountTypeEnum" subtype: type: string description: An optional manual account subtype. Examples include
- retirement - checking - savings - prepaid credit card minLength: 1 maxLength: 100 example: prepaid credit card balance: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ example: "195.50" description: Numeric value of the current balance, up to four decimal places, of the account as a number or string. Do not include any special characters aside from a decimal point. balance_as_of: type: string oneOf: - format: date-time - format: date example: "2024-09-15" description: Date/time the balance of the manual account was last updated in ISO 8601 extended format currency: description: Three-letter lowercase currency code of the transaction in ISO 4217 format allOf: - $ref: "#/components/schemas/currencyEnum" status: type: string description: The status of the account enum: - active - closed default: active closed_on: oneOf: - type: string format: date - type: string format: date-time nullable: true example: "2024-10-01" description: The date this manual account was closed in YYYY-MM-DD format. If set, `status` must also be set to `closed`. external_id: type: string nullable: true minLength: 0 maxLength: 75 description: An optional user-defined ID for the manual account custom_metadata: type: object nullable: true description: An optional JSON object that includes additional data related to this account. This must be a valid JSON object and, when stringified, must not exceed 4096 characters. additionalProperties: true exclude_from_transactions: type: boolean description: If `true`, transactions may not be assigned to this manual account default: false required: - name - type - balance # The object that may be submitted to PUT /manual_accounts/:id updateManualAccountRequestObject: type: object x-internal: true additionalProperties: false properties: id: type: integer format: int32 description: System defined unique identifier of this account. Ignored if set x-updatable: false name: type: string description: If set, the new name of the manual account minLength: 1 maxLength: 45 x-updatable: true institution_name: type: string nullable: true description: If set, the name of institution holding the account minLength: 1 maxLength: 50 x-updatable: true display_name: type: string nullable: true description: If set, the new display name for the manual account.
This must be unique for the user. x-updatable: true type: description: If set, the new type of the manual account x-updatable: true allOf: - $ref: "#/components/schemas/accountTypeEnum" subtype: type: string description: If set, an optional account subtype. Examples include
- retirement - checking - savings - prepaid credit card minLength: 1 maxLength: 100 x-updatable: true balance: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ example: "195.50" description: Numeric value of the current balance, up to four decimal places, of the manual account as a number or string. Do not include any special characters aside from a decimal point. x-updatable: true currency: description: If set, the new three-letter lowercase currency code of the manual account balance. x-updatable: true allOf: - $ref: "#/components/schemas/currencyEnum" balance_as_of: type: string oneOf: - format: date-time - format: date description: "A new date for the `updated_at` property. May be set as a date, ie: YYYY-MM-DD, or date-time string in ISO 8601 extended format. This property is ignored if `balance` is not also set. If `balance` is set and this property is not set the current time is used." x-updatable: true status: type: string description: If set, the status of the manual account. If set to `closed`, the `closed_on_date` date will be set to the current date, unless it is also set. enum: - active - closed x-updatable: true closed_on: nullable: true oneOf: - type: string format: date - type: string format: date-time description: If set, the date this manual account was closed in YYYY-MM-DD format. If updating an account that is not already closed, `status` must also be set to `closed`. x-updatable: true external_id: type: string nullable: true minLength: 0 maxLength: 75 description: An optional user-defined ID for the manual account x-updatable: true custom_metadata: type: object nullable: true description: An optional JSON object that includes additional data related to this account. This must be a valid JSON object and, when stringified, must not exceed 4096 characters. additionalProperties: true x-updatable: true exclude_from_transactions: type: boolean description: If set, transactions may not be assigned to this manual account x-updatable: true to_base: type: number description: System defined balance converted to the user's primary currency. Ignored if set. Use `balance` to update the balance in the account x-updatable: false created_at: type: string format: date-time description: System defined date/time the account was created in ISO 8601 extended format. Ignored if set. x-updatable: false updated_at: type: string format: date-time description: System defined date/time the account was created in ISO 8601 extended format. Ignored if set. x-updatable: false created_by_name: type: string description: System defined name of the user who created the account. Ignored if set x-updatable: false # The object containing information about a Plaid account plaidAccountObject: type: object title: plaid account object additionalProperties: false description: An object containing information about an account synced via Plaid properties: id: type: integer format: int32 description: The unique identifier of this account plaid_item_id: type: string nullable: true minLength: 0 maxLength: 255 description: The unique identifier of the Plaid connection that this account belongs to. Accounts with the same plaid_item_id usually belong to the same institution. date_linked: type: string format: date description: Date account was first linked in ISO 8601 format linked_by_name: type: string nullable: false description: The name of the user who linked the account name: type: string description: Name of the account. This field is set by Plaid and cannot be altered. display_name: type: string nullable: true description: Optional display name for the account set by the user. If not set, it will return a concatenated string of institution and account name. type: type: string description: Primary type of the account, such as `credit`, `depository`, etc. This field is set by Plaid and cannot be altered. subtype: type: string description: Optional account subtype. This field is set by Plaid and cannot be altered. mask: type: string description: Mask (last 3 to 4 digits of account) of account. This field is set by Plaid and cannot be altered. institution_name: type: string description: Name of institution holding the account. This field is set by Plaid and cannot be altered. status: type: string description: "Denotes the current status of the account within Lunch Money. Must be one of
- active: Account is actively syncing transactions and/or balance
- inactive: Account marked inactive from user. Transaction imports and balance updates will not occur for this account.
- closed: Account is marked as closed
- deactivated: Account is marked deactivated during setup. The user must click `Add/Remove Accounts From This Bank` and manually re-select this account to activate it.'
- not found: Account was once linked but can no longer be found with Plaid.
- not supported: Account is not supported by Plaid.
- relink: Account (and others with the same connection) need to be relinked with Plaid.
- syncing: Account is awaiting the first import of transactions.
- revoked: Account connection has been revoked by Plaid and syncing is no longer possible. A new connection needs to be set up again.
- error: Account (and others with the same connection) is in error with Plaid and requires intervention to re-activate it.
" enum: - active - inactive - closed - deactivated - not found - not supported - relink - syncing - revoked - error allow_transaction_modifications: type: boolean description: If `false`, transactions imported for this synced account can have their properties (such as amount and account) be modified by the user. This option is managed in the web app. limit: type: number nullable: true description: Optional credit limit of the account. This field is set by Plaid and cannot be altered balance: type: string description: Current balance of the account in numeric format to 4 decimal places. This field is set by Plaid and cannot be altered. currency: type: string minLength: 3 maxLength: 3 description: Three-letter lowercase currency code of the account balance to_base: type: number description: The account balance converted to the user's primary currency balance_last_update: type: string format: date-time nullable: true description: Date balance was last updated in ISO 8601 extended format. This field is set by Plaid and cannot be altered. import_start_date: type: string format: date nullable: true description: Date of earliest date allowed for importing transactions. Transactions earlier than this date are not imported. last_import: type: string format: date-time nullable: true description: Timestamp in ISO 8601 extended format of the last time Lunch Money imported new data from Plaid for this account. last_fetch: type: string format: date-time nullable: true description: Timestamp in ISO 8601 extended format of the last successful request from Lunch Money for updated data or timestamps from Plaid in ISO 8601 extended format (not necessarily date of last successful import) plaid_last_successful_update: type: string format: date-time nullable: true description: Timestamp in ISO 8601 extended format of the last time Plaid successfully connected with institution for new transaction updates, regardless of whether any new data was available in the update. required: - id - plaid_item_id - date_linked - linked_by_name - name - display_name - type - subtype - mask - institution_name - status - allow_transaction_modifications - limit - balance - currency - to_base - balance_last_update - import_start_date - last_import - last_fetch - plaid_last_successful_update # The object containing information about a recurring item recurringObject: type: object title: recurring item object properties: id: type: integer format: int32 description: The unique identifier of this recurring item description: type: string nullable: true description: An optional description of this recurring item. status: type: string description: The status of this recurring item. `suggested` recurring items are generated by Lunch Money, but only `reviewed` recurring items will be applied to matching transactions. enum: - suggested - reviewed transaction_criteria: type: object description: The set of properties used to identify matching transactions. properties: start_date: type: string format: date nullable: true description: The beginning of the date range for matching transactions. If `null`, any transactions before end_date may be considered. end_date: type: string format: date nullable: true description: The end of the date range for matching transactions. If `null`, any transactions after start_date may be considered. granularity: type: string description: The unit of time used to define the cadence of the recurring item. enum: - day - week - month - year quantity: type: integer description: The number of granularity units between each recurrence. anchor_date: type: string format: date nullable: false description: The date used in conjunction with the `quantity` and `granularity` properties to calculate expected occurrences of recurring transactions. payee: type: string nullable: true description: If set, represents the original transaction payee name that triggered this recurring item's creation. amount: type: string pattern: ^-?\d+(\.\d{1,4})?$ description: The expected amount for a transaction that will match this recurring item. For recurring items that have a flexible amount this is the average of the specified min and max amounts. to_base: type: number description: The amount converted to the user's primary currency currency: type: string nullable: false description: Three-letter lowercase currency code of the recurring item. plaid_account_id: type: integer format: int64 nullable: true description: The Plaid account ID associated with the recurring item, if any. manual_account_id: type: integer format: int64 nullable: true description: The manual account ID associated with the recurring item, if any. required: - start_date - end_date - granularity - quantity - anchor_date - payee - amount - to_base - currency - plaid_account_id - manual_account_id overrides: type: object description: The values that will be applied to matching transactions. properties: payee: type: string nullable: false description: If present, the payee name that will be displayed for any matching transactions. notes: type: string nullable: false description: If present, the notes that will be displayed for any matching transactions. category_id: type: integer nullable: false description: If present, the ID of the category that matching transactions will be assigned to. matches: type: object nullable: true description: Details on expected, found and missing transactions for the specified range. This will be `null` for recurring items with a `status` of `suggested`. properties: request_start_date: type: string format: date description: The beginning of the date range that this request used to find matching transactions. request_end_date: type: string format: date description: The beginning of the date range that this request used to find matching transactions. expected_occurrence_dates: type: array items: type: string format: date description: A list of dates within the specified range where a recurring transactions is expected. found_transactions: type: array description: A list with the dates and IDs of matching transactions. items: type: object properties: date: type: string format: date description: The date for a matching transaction within the specified range. transaction_id: type: integer description: The ID of a matching transaction within the specified range. missing_transaction_dates: type: array items: type: string format: date description: A list of dates within the range of where a recurring transaction was expected but none was found. created_by: type: integer nullable: false description: The ID of the user who created the recurring item. created_at: type: string format: date-time nullable: false description: Date/time the recurring item was created in ISO 8601 extended format. updated_at: type: string format: date-time nullable: false description: Date/time the recurring item was updated in ISO 8601 extended format. source: type: string description: > This can be one of four values: - `manual`: User created this recurring item manually from the Recurring Items page - `transaction`: User created this by converting a transaction from the Transactions page - `system`: Recurring item was created by the system on transaction import - `null`: Some older recurring items may not have a source. enum: - manual - transaction - system required: - id - description - status - transaction_criteria - overrides - matches - created_by - created_at - updated_at - source # The object containing information about a tag tagObject: type: object title: tag object additionalProperties: false properties: id: type: integer format: int32 description: Unique identifier for the tag. name: type: string description: Name of the tag. description: type: string nullable: true description: Description of the tag. text_color: type: string nullable: true description: The text color of the tag. background_color: type: string nullable: true description: The background color of the tag. updated_at: type: string format: date-time nullable: false description: The date and time of when the tag was last updated (in the ISO 8601 extended format). created_at: type: string format: date-time nullable: false description: The date and time of when the tag was created (in the ISO 8601 extended format). archived: type: boolean description: If `true`, the tag will not show up when creating or updating transactions in the Lunch Money app. **Can it be assigned via the API** archived_at: type: string format: date-time nullable: true description: The date and time of when the tag was last archived or `null` if not archived required: - id - name - description - text_color - background_color - created_at - updated_at - archived - archived_at # The object that may be submitted to POST /tags createTagRequestObject: type: object additionalProperties: false x-internal: true properties: name: type: string nullable: false description: |- The name of the new tag. Must be between 1 and 100 characters. Must not match the name of any existing tags. minLength: 1 maxLength: 100 description: type: string nullable: true default: null description: The description of the tag. Must not exceed 200 characters. maxLength: 200 text_color: type: string nullable: true description: The text color of the tag. background_color: type: string nullable: true description: The background color of the tag. archived: type: boolean default: false description: If `true`, the tag is archived and not displayed in relevant areas of the Lunch Money app. required: - name # The object that may be submitted to PUT /tags/:id updateTagRequestObject: type: object x-internal: true additionalProperties: false properties: name: type: string nullable: false description: If set, the new name of the category. Must be between 1 and 100 characters. minLength: 1 maxLength: 100 x-updatable: true description: type: string nullable: true description: If set, the new description of the category. Must not exceed 200 characters. maxLength: 200 x-updatable: true text_color: type: string nullable: true description: The text color of the tag. x-updatable: true background_color: type: string nullable: true description: The background color of the tag. x-updatable: true archived: type: boolean description: If set, will indicate if this category is archived. x-updatable: true id: type: integer format: int32 description: System-defined unique identifier for the category. Ignored if set. x-updatable: false updated_at: type: string format: date-time nullable: false description: System-set time the tag was last updated. Ignored if set x-updatable: false created_at: type: string format: date-time nullable: false description: System-set time the tag was created. Ignored if set. x-updatable: false archived_at: type: string format: date-time nullable: true description: If set, updates the archived timestamp for the tag. Provide an ISO 8601 extended datetime or `null` to clear it. x-updatable: true # The object returned when a DELETE /tag/:id request # has an id for a tag that has dependencies deleteTagResponseWithDependencies: type: object x-internal: true additionalProperties: false properties: tag_name: type: string description: The name of the tag dependents: type: object properties: rules: type: integer description: The number of rules depending on the tag transactions: type: integer description: The number of transactions with the tag required: - rules - transactions required: - tag_name - dependents # The primary object that represents a transaction transactionObject: type: object title: transaction object additionalProperties: false properties: id: type: integer format: int64 description: System created unique identifier for transaction date: type: string format: date description: Date of transaction in ISO 8601 format amount: type: string description: Amount of the transaction in numeric format to 4 decimal places. Positive values indicate a debit transaction, negative values indicate a credit transaction. currency: description: Three-letter lowercase currency code of the transaction in ISO 4217 format. allOf: - $ref: "#/components/schemas/currencyEnum" to_base: type: number format: double description: The amount converted to the user's primary currency. If the multi-currency feature is not being used, to_base and amount will be the same. Positive values indicate a debit transaction, negative values indicate a credit transaction. recurring_id: type: integer format: int32 nullable: true description: The unique identifier of the associated recurring item that this transaction matched. payee: type: string description: | Name of payee set by the user, the financial institution, or by a matched recurring item. This will match the value displayed in payee field on the transactions page in the GUI. original_name: type: string nullable: true description: Original payee name from the source (financial institution, CSV, etc.). For Plaid transactions, this is the raw name before normalization. For manual/API transactions, this typically matches `payee`. May be null for older transactions. category_id: type: integer format: int32 nullable: true description: Unique identifier of associated category set by the user or by a matched recurring_item.
Category details can be obtained by passing the value of this property to the [Get A Single Category](../operations/getCategoryById) API plaid_account_id: type: integer format: int32 nullable: true description: The unique identifier of the plaid account associated with this transaction. This will always be null if this transaction is associated with a manual account or if this transaction has no associated account and appears as a "Cash Transaction" in the Lunch Money GUI. manual_account_id: type: integer format: int32 nullable: true description: The unique identifier of the manual account associated with this transaction. This will always be null if this transaction is associated with a synced account or if this transaction has no associated account and appears as a "Cash Transaction" in the Lunch Money GUI. external_id: type: string nullable: true description: A user-defined external ID for any transaction that was added via csv import, `POST /transactions` API call, or manually added via the Lunch Money GUI. No external ID exists for transactions associated with synced accounts, and they cannot be added. For transactions associated with manual accounts, the external ID must be unique as attempts to add a subsequent transaction with the same external_id and manual_account_id will be flagged as duplicates and fail. minLength: 0 maxLength: 75 tag_ids: type: array nullable: false description: A list of tag_ids for the tags associated with this transaction. If the transaction has no tags this will be an empty list.
Tag details can be obtained by passing the value of this attribute as the `ids` query parameter to the [List Tags](../operations/getTags) API items: type: integer format: int32 notes: type: string nullable: true description: | Any transaction notes set by the user or by a matched recurring item. This will match the value displayed in notes field on the transactions page in the GUI. status: type: string # description: > # Status of the transaction. Will be one of the following values: # x-enumDescriptions: # reviewed: User has reviewed the transaction, or it was automatically marked as reviewed due to reviewed recurring_item logic # unreviewed: User has not reviewed the transaction and it does not match any reviewed recurring_items. # delete_pending: The synced account deleted this transaction after it was updated by the user. Requires manual intervention. description: > Status of the transaction: - `reviewed`: User has reviewed the transaction, or it was automatically marked as reviewed due to reviewed recurring_item logic - `unreviewed`: User has not reviewed the transaction and it does not match any reviewed recurring_items. Note that any transactions where `is_pending` is true will be returned with a status of unreviewed. - `delete_pending`: The synced account deleted this transaction after it was updated by the user. Requires manual intervention. enum: - reviewed - unreviewed - delete_pending is_pending: type: boolean description: Denotes if the transaction is pending (not posted). Applies only to transactions in synced accounts and will always be false for transactions associated with manual accounts. created_at: type: string format: date-time description: The date and time of when the transaction was created (in the ISO 8601 extended format). updated_at: type: string format: date-time description: The date and time of when the transaction was last updated (in the ISO 8601 extended format). is_split_parent: type: boolean description: If `true`, this transaction has been split into two or more other transactions. By default, parent transactions are not returned in call to `GET /transactions` but they can be queried directly by their ID. split_parent_id: type: integer format: int64 nullable: true description: A transaction ID if this is a split transaction. Denotes the transaction ID of the original, or parent, transaction. Is null if this is not a split transaction is_group_parent: type: boolean description: "`true` if this transaction represents a group of transactions. If so, amount and currency represent the totalled amount of transactions bearing this transaction's id as their group_parent_id. Amount is calculated based on the user's primary currency." group_parent_id: type: integer format: int64 nullable: true description: Is set if this transaction is part of a group. Denotes the ID of the grouped transaction this is now included in. By default the transactions that were grouped are not returned in a call to `GET /transactions` but they can be queried directly by calling the `GET /transactions/group/{id}`, where the id passed is associated with a transaction where the `is_group_parent` attribute is true children: type: array nullable: false items: $ref: "#/components/schemas/childTransactionObject" description: Exists only for transactions which are the parent of a split transaction or for transaction groups. It will not exist in the response unless the `include_children` query parameter is set to `true`.
For parents of split transactions, it contains a list of the associated transactions that it was split into. For transaction groups, it contains the transactions that were grouped together. Examine the `is_split_parent` and `is_group_parent` properties to determine which of these it is. plaid_metadata: type: object nullable: true description: If requested, the transaction's plaid_metadata that came when this transaction was obtained. This will be a json object, but the schema is variable. This is only present when the `include_metadata` query parameter is set to true. custom_metadata: type: object nullable: true description: If requested, the transaction's custom_metadata that was included when the transaction was inserted via the API. This will be a json object, but the schema is variable. This is only present when the `include_metadata` query parameter is set to true. files: type: array nullable: false description: A list of objects that describe any attachments to the Transactions. This is only present when the `include_files` query parameter is set to true. items: $ref: "#/components/schemas/transactionAttachmentObject" source: type: string nullable: true description: > Source of the transaction: - `api`: Transaction was added by a call to the [POST /transactions](../operations/createTransaction) API - `csv`: Transaction was added via a CSV Import - `manual`: Transaction was created via the "Add to Cash" button on the Transactions page - `merge`: Transactions were originally in an account that was merged into another account - `plaid`: Transaction came from a Financial Institution synced via Plaid - `recurring`: Transaction was created from the Recurring page - `rule`: Transaction was created by a rule to split a transaction - `split`: Transaction was created by splitting another transaction - `user`: This is a legacy value and is replaced by either csv or manual enum: - api - csv - manual - merge - plaid - recurring - rule - split - user required: - id - date - amount - currency - to_base - recurring_id - payee - category_id - notes - status - is_pending - created_at - updated_at - split_parent_id - is_group_parent - group_parent_id - manual_account_id - plaid_account_id - tag_ids - source - external_id # The childTransactionObject is basically a transactionObject that has no # `children` attribute which should not be present on grouped or split # transactions. childTransactionObject: type: object x-internal: true additionalProperties: false properties: id: type: integer format: int64 description: System created unique identifier for transaction date: type: string format: date description: Date of transaction in ISO 8601 format amount: type: string description: Amount of the transaction in numeric format to 4 decimal places. Positive values indicate a debit transaction, negative values indicate a credit transaction. currency: description: Three-letter lowercase currency code of the transaction in ISO 4217 format allOf: - $ref: "#/components/schemas/currencyEnum" to_base: type: number format: double description: The amount converted to the user's primary currency. If the transaction currency is the same as the user's primary currency, to_base and amount will be the same. Positive values indicate a debit transaction, negative values indicate a credit transaction. recurring_id: type: integer format: int32 nullable: true description: The unique identifier of the associated recurring item that this transaction matched. payee: type: string description: | Name of payee set by the user, the financial institution, or by a matched recurring item. This will match the value displayed in payee field on the transactions page in the GUI. original_name: type: string nullable: true description: Original payee name from the source (financial institution, CSV, etc.). For Plaid transactions, this is the raw name before normalization. For manual/API transactions, this typically matches `payee`. May be null for older transactions. category_id: type: integer format: int32 nullable: true description: Unique identifier of associated category set by the user or by a matched recurring item.
Category details can be obtained by passing the value of this property to the [Get A Single Category](../operations/getCategoryById) API notes: type: string nullable: true description: | Any transaction notes set by the user or by a matched recurring item. This will match the value displayed in notes field on the transactions page in the GUI. status: type: string description: > Status of the transaction. Will be one of the following values: x-enumDescriptions: reviewed: User has reviewed the transaction, or it was automatically marked as reviewed due to reviewed recurring item logic unreviewed: User has not reviewed the transaction and it does not match any reviewed recurring_items. Note that any transactions where `is_pending` is true will be returned with a status of unreviewed. delete_pending: The synced account deleted this transaction after it was updated by the user. Requires manual intervention. # description: > # Status of the transaction: # - `reviewed`: User has reviewed the transaction, or it was # automatically marked as reviewed due to reviewed recurring_item # logic # - `unreviewed`: User has not reviewed the transaction and it does # not match any reviewed recurring_items. # - `delete_pending`: The synced account deleted this transaction # after it was updated by the user. Requires manual intervention. enum: - reviewed - unreviewed - delete_pending is_pending: type: boolean description: Denotes if the transaction is pending (not posted). Applies only to transactions in synced accounts and will always be false for transactions associated with manual accounts. created_at: type: string format: date-time description: The date and time of when the transaction was created (in the ISO 8601 extended format). updated_at: type: string format: date-time description: The date and time of when the transaction was last updated (in the ISO 8601 extended format). is_split_parent: type: boolean description: If true this transaction has been split into two or more other transactions. By default parent transactions are not returned in call to `GET /transactions` but they can be queried directly by their ID. split_parent_id: type: integer format: int64 nullable: true description: A transaction ID if this is a split transaction. Denotes the transaction ID of the original, or parent, transaction. Is null if this is not a split transaction is_group_parent: type: boolean description: True if this transaction represents a group of transactions. If so, amount and currency represent the totalled amount of transactions bearing this transaction's id as their group_parent_id. Amount is calculated based on the user's primary currency. group_parent_id: type: integer format: int64 nullable: true description: Is set if this transaction is part of a group. Denotes the ID of the grouped transaction this is now included in. By default the transactions that were grouped are not returned in a call to `GET /transactions` but they can be queried directly by calling the `GET /transactions/group/{id}`, where the id passed is associated with a transaction where the `is_group_parent` attribute is true manual_account_id: type: integer format: int32 nullable: true description: The unique identifier of the manual account associated with this transaction. This will always be null if this transaction is associated with a synced account or if this transaction has no associated account and appears as a "Cash Transaction" in the Lunch Money GUI. plaid_account_id: type: integer format: int32 nullable: true description: The unique identifier of the plaid account associated with this transaction. This will always be null if this transaction is associated with a manual account or if this transaction has no associated account and appears as a "Cash Transaction" in the Lunch Money GUI. tag_ids: type: array nullable: false description: A list of tag_ids for the tags associated with this transaction. If the transaction has no tags this will be an empty list.
Tag details can be obtained by passing the value of this attribute as the `ids` query parameter to the [List Tags](../operations/getTags) API items: type: integer format: int32 source: type: string nullable: true description: > Source of the transaction: - `api`: Transaction was added by a call to the [POST /transactions](../operations/createTransaction) API - `csv`: Transaction was added via a CSV Import - `manual`: Transaction was created via the "Add to Cash" button on the Transactions page - `merge`: Transactions were originally in an account that was merged into another account - `plaid`: Transaction came from a Financial Institution synced via Plaid - `recurring`: Transaction was created from the Recurring page - `rule`: Transaction was created by a rule to split a transaction - `split`: This is a transaction created by splitting another transaction - `user`: This is a legacy value and is replaced by either csv or manual enum: - api - csv - manual - merge - plaid - recurring - rule - split - user external_id: type: string nullable: true description: A user-defined external ID for any transaction that was added via csv import, `POST /transactions` API call, or manually added via the Lunch Money GUI. No external ID exists for transactions associated with synced accounts, and they cannot be added. For transactions associated with manual accounts, the external ID must be unique as attempts to add a subsequent transaction with the same external_id and manual_account_id will be flagged as duplicates and fail. minLength: 0 maxLength: 75 plaid_metadata: type: object nullable: true description: If requested, the transaction's plaid_metadata that came when this transaction was obtained. This will be a json object, but the schema is variable. This will only be present for transactions associated with a plaid account. custom_metadata: type: object nullable: true description: If requested, the transaction's custom_metadata that was included when the transaction was inserted via the API. This will be a json object, but the schema is variable. files: type: array nullable: false description: A list of objects that describe any attachments to the transaction items: $ref: "#/components/schemas/transactionAttachmentObject" required: - id - date - amount - currency - to_base - recurring_id - payee - category_id - notes - status - is_pending - created_at - updated_at - split_parent_id - is_group_parent - group_parent_id - manual_account_id - plaid_account_id - tag_ids - source - external_id # The request object for a POST /transactions request # It contains only user settable properties. insertTransactionObject: type: object x-internal: true additionalProperties: false properties: date: type: string format: date description: Date of transaction in ISO 8601 format amount: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ description: Numeric value of amount without currency symbol. i.e. $4.25 should be denoted as 4.25. May be a string or a number in double format. Positive values indicate a debit transaction, negative values indicate a credit transaction. currency: description: Three-letter lowercase currency code of the transaction in ISO 4217 format. Must match one of the [supported currencies](https://alpha.lunchmoney.dev/v2/currencies). If not set defaults to the user account's primary currency. allOf: - $ref: "#/components/schemas/currencyEnum" payee: type: string description: Name of payee for the transaction original_name: type: string nullable: true description: Original payee name. If not provided, defaults to `payee` value. category_id: type: integer format: int32 nullable: true description: The ID of the category associated with the transactions. If set, the category ID must exist for the user's account and it cannot be a category group. notes: type: string nullable: true description: | Any transaction notes set by the user or by a matched recurring item. This will match the value displayed in notes field on the transactions page in the GUI. manual_account_id: type: integer format: int32 nullable: true description: The Unique identifier for the associated manually managed account. If set, this must match an existing manual account id associated with the user's account. If not set, and `plaid_account_id` is also not set, no account is associated with the transaction and it will appear as a "Cash Transaction" in the Lunch Money GUI. It is an error if this, and `plaid_account_id` is also set on the same transaction. plaid_account_id: type: integer format: int32 nullable: true description: The Unique identifier for the associated plaid synced account. If set, this must match an existing plaid account id associated with the user's account. If not set, and `manual_account_id` is also not set, no account is associated with the transaction and it will appear as a "Cash Transaction" in the Lunch Money GUI. It is an error if this, and `manual_account_id` is also set on the same transaction. In addition the specified plaid account must have the "Allow Modifications To Transactions" property set (which is enabled by default), or the insert will fail. recurring_id: type: integer format: int32 nullable: true description: Unique identifier for associated recurring item. Recurring item must be associated with the same account. status: type: string description: If set must be either `reviewed` or `unreviewed`. If not set, defaults to `unreviewed`. enum: - reviewed - unreviewed tag_ids: type: array nullable: false description: A list of IDs for the tags associated with this transaction. Each ID must match an existing tag associated with the user's account. If not set, no tags will be associated with the created transaction. items: type: integer format: int32 external_id: type: string nullable: true description: A user-defined external ID for the transaction. If set, and `manual_account_id` is set, the creation of the new transaction will fail if a transaction with this id already exists for the specified manual account. minLength: 0 maxLength: 75 custom_metadata: type: object nullable: true description: An optional JSON object that includes additional data related to this transaction. This must be a valid JSON object and, when stringified, must not exceed 4096 characters. This data may be available in the future for processing by rules. additionalProperties: true required: - date - amount # The object that may be submitted to PUT /transactions/:id # System set properties such as id and created_at are tolerated but ignored updateTransactionObject: type: object x-internal: true additionalProperties: false properties: id: type: integer format: int64 description: System defined unique identifier of this transaction. Ignored if set. x-updatable: false date: type: string format: date description: Date of transaction in ISO 8601 format x-updatable: true amount: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ description: Numeric value of amount without currency symbol. i.e. $4.25 should be denoted as 4.25. May be a string or a number in double format. Positive values indicate a debit transaction, negative values indicate a credit transaction.
May not be updated on transactions that belong to a synced account with the "Allow Modifications to Transactions" property disabled. x-updatable: true currency: description: Three-letter lowercase currency code of the transaction in ISO 4217 format.
May not be updated on transactions that belong to a synced account with the "Allow Modifications to Transactions" property disabled. x-updatable: true allOf: - $ref: "#/components/schemas/currencyEnum" recurring_id: type: integer format: int32 nullable: true description: The unique identifier of the associated recurring item that this transaction matches. x-updatable: true payee: type: string description: | The new payee for the transaction. x-updatable: true original_name: type: string nullable: true description: Original payee name. Cannot be changed. Ignored if set. x-updatable: false category_id: type: integer format: int32 nullable: true description: Unique identifier of the category for this transaction. Set this to null to clear the transaction's category. x-updatable: true notes: type: string nullable: true description: > New notes for the transaction. Set this to an empty string to clear the existing notes. x-updatable: true manual_account_id: type: integer format: int32 nullable: true description: The unique identifier of the manual account associated with this transaction. Set this to null to disassociate the transaction with an account. If set `plaid_account_id` may not also be set to a non null value. Moving an existing transaction to to another account will not work if the transaction belongs to a synced account who's "Allow Modifications to Transactions" property is not set. x-updatable: true plaid_account_id: type: integer format: int32 nullable: true description: The unique identifier of the plaid account associated with this transaction. If set `manual_account_id` may not also be set to a non null value. Attempting to modify this on a transaction associated with a Plaid account will not work if the account's "Allow Modifications to Transactions" property is not set. Similarly, this cannot be set to an id associated with this type of locked Plaid account. x-updatable: true tag_ids: type: array nullable: false description: A list of tag_ids for the tags associated with this transaction. If set, this property will overwrite any existing tags. Use `additional_tag_ids` to add tags to the existing transaction's tags. Set this to an empty array to remove all tags from a transaction. If set `additional_tag_ids` may not be set. x-updatable: true items: type: integer format: int32 additional_tag_ids: type: array nullable: false description: A list of tag_ids for the tags associated with this transaction. If set, the tags listed in this property be added to any existing transaction tags. Use `tag_ids` to overwrite or clear transaction tags. If set `tag_ids` may not be set. x-updatable: true items: type: integer format: int32 external_id: type: string nullable: true description: A user-defined external ID for the transaction. The update will fail if the transaction does not also have a `manual_account_id` or if there is already an existing transaction with the same `manual_account_id`/`external_id` combination. minLength: 0 maxLength: 75 x-updatable: true custom_metadata: type: object nullable: true description: User defined JSON data that can be set or cleared via the API. x-updatable: true status: type: string description: > Status of the transaction, may be one of: - `reviewed`: User has reviewed the transaction, or it was automatically marked as reviewed due to reviewed recurring_item logic - `unreviewed`: User has not reviewed the transaction and it does not match any reviewed recurring_items. enum: - reviewed - unreviewed x-updatable: true to_base: type: number format: double description: System defined amount of this transaction in the user's primary currency. Ignored if set. Use `amount` to update the amount in the transaction. x-updatable: false is_pending: type: boolean description: System defined flag set for pending transactions. Ignored if set. x-updatable: false plaid_metadata: type: object nullable: true description: System set metadata from a Plaid account sync. Ignored if set. x-updatable: false created_at: type: string format: date-time description: System defined date and time of when the transaction was created. Ignored if set. x-updatable: false updated_at: type: string format: date-time description: System defined date and time of when the transaction was last updated. Ignored if set. x-updatable: false is_split_parent: type: boolean description: System defined boolean indicating if this transaction was split. To split or unsplit a transaction use the `/transactions/split` endpoint. Ignored if set. x-updatable: false children: type: array nullable: false items: $ref: "#/components/schemas/childTransactionObject" description: An array of child transactions that exists when a transaction has been split or if the transaction is a group. Split x-updatable: false and Grouped transactions may not be modified using this API. Ignored if set. split_parent_id: type: integer format: int64 nullable: true description: A transaction ID if this is a split transaction. Split transactions may not be modified this API. Use the `transactions/split` endpoint instead. Ignored if set. x-updatable: false is_group_parent: type: boolean description: System defined boolean indicating if this transaction represents a group of transactions. Grouped transactions may not be modified with this API. Use the `transactions/group` endpoint instead. Ignored if set. x-updatable: false group_parent_id: type: integer format: int64 nullable: true description: A transaction group ID if this transaction is part of a group. Grouped transactions may not be modified with this API. Use the `transactions/group` endpoint instead. Ignored if set. x-updatable: false source: type: string nullable: true description: | System defined original source of the transaction. Ignored if set. x-updatable: false enum: - api - csv - manual - merge - plaid - recurring - rule - split - user # The object that may be submitted to PUT /transactions/split splitTransactionObject: type: object additionalProperties: false x-internal: true description: The object representing a split transaction properties: amount: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ description: Individual amount of split. Currency will inherit from parent transaction. All amounts must sum up to parent transaction amount. payee: type: string minLength: 0 maxLength: 140 description: The payee for the child transaction. Will inherit the original payee from the parent if not defined. date: type: string format: date description: Must be in ISO 8601 format (YYYY-MM-DD). Will inherit from the parent if not defined. category_id: type: integer format: int32 description: Unique identifier for associated category_id. Category must already exist for the account. Will inherit category from the parent if not defined. tag_ids: type: array description: The IDs of any tags to apply to this split child transaction. Each ID must match an existing tag. items: type: integer format: int32 notes: type: string description: Will inherit notes from parent if not defined. required: - amount # The object returned when a new transaction duplicates one that # already exists skippedExistingExternalIdObject: type: object x-internal: true additionalProperties: false description: The object returned when a new transaction has an external_id that already exists properties: reason: type: string description: > The reason the transaction was skipped, may be one of: - `duplicate_external_id`: The transaction has the same `manual_account_id` and `external_id` as an existing transaction - `duplicate_payee_amount_date`: The `skip_duplicates` request body property was set to `true` and the transaction has the same `amount`, `payee`, and `date` as an existing transaction associated with the same account. enum: - duplicate_external_id - duplicate_payee_amount_date request_transactions_index: type: integer format: int64 description: The of the transaction in the request body's transactions array that was skipped. existing_transaction_id: type: integer format: int64 description: The id of the existing transactions that the requested transaction duplicates. request_transaction: type: object description: The requested transaction that was skipped. allOf: - $ref: "#/components/schemas/insertTransactionObject" # The object returned from a successful POST /transactions request insertTransactionsResponseObject: type: object x-internal: true additionalProperties: false description: The object returned from a successful POST /transactions request properties: transactions: description: An array of the inserted transactions. items: $ref: "#/components/schemas/transactionObject" type: array skipped_duplicates: description: An array of the requested transactions that were duplicates of existing transactions and were not inserted. items: $ref: "#/components/schemas/skippedExistingExternalIdObject" type: array required: - transactions - skipped_duplicates # The object containing information about a file attached to a transaction transactionAttachmentObject: type: object title: transaction attachment object additionalProperties: false # description: An object containing information about a file attached to a transaction properties: id: type: integer format: int32 description: The unique identifier of the attachment uploaded_by: type: integer format: int64 description: The id of the user who uploaded the attachment name: type: string description: The name of the file type: type: string description: The MIME type of the file size: type: integer description: The size of the file in kilobytes notes: type: string nullable: true description: Optional notes about the attachment created_at: type: string format: date-time description: The date and time when the attachment was created in ISO 8601 format # Object that describes a budget's amount, category and start_date budgetObject: type: object title: budget object additionalProperties: false description: "A budget object represents a budgeted amount for a specific category and budget period. Each budget entry is tied to a specific time period defined by its `start_date`. The budget object includes information about the budget amount, currency, period settings, and how future periods will be automatically calculated." properties: id: type: integer format: int64 description: System created unique identifier for the budget entry. category_id: type: integer format: int32 description: The ID of the category this budget applies to. amount: type: number format: double description: The budgeted amount for this period. currency: allOf: - $ref: "#/components/schemas/currencyEnum" description: The currency of the budgeted amount in ISO 4217 format. start_date: type: string format: date description: The start date of the budget period in ISO 8601 format (YYYY-MM-DD). This represents the beginning of the period for which this budget applies. next_start_date: type: string format: date readOnly: true description: The calculated start date of the next budget period based on the category's period settings (granularity, quantity, and anchor_date). This is useful for determining when the next budget period begins. notes: type: string nullable: true description: Optional notes associated with this budget period. auto_budget_type: type: string readOnly: true enum: - nothing - fixed - spend - budget description: "The budget preset type that determines how future periods will be automatically calculated. `nothing` means no automatic calculation (budgets must be set manually for each period). `fixed` uses a fixed amount for all future periods. `spend` uses the previous period's spending amount. `budget` uses the previous period's budgeted amount." auto_budget_amount: type: number format: double nullable: true readOnly: true description: "If `auto_budget_type` is `fixed`, this is the fixed amount that will be used for future periods." auto_budget_currency: allOf: - $ref: "#/components/schemas/currencyEnum" nullable: true readOnly: true description: "If `auto_budget_type` is `fixed`, this is the currency of the fixed amount." rollover_option: type: string nullable: true readOnly: true enum: - same category - available funds description: "The rollover setting for this category. `same category` means unspent funds roll over to the next period for this category. `available funds` means unspent funds are added to the available funds pool. `null` means rollover is disabled." granularity: type: string readOnly: true enum: - month - week - twice a month description: "The granularity of the budget period (e.g., monthly, weekly, twice a month). This is determined by the category's custom budget settings or the account's default budget period settings." quantity: type: integer format: int32 readOnly: true description: "The quantity of granularity units that make up each budget period. For example, if granularity is `week` and quantity is `2`, each budget period is 2 weeks." is_group: type: boolean readOnly: true description: "Whether the category is a category group. Category groups can have their own budgets that apply to all subcategories, or subcategories can have individual budgets." group_id: type: integer format: int32 nullable: true readOnly: true description: "If this budget is for a subcategory, this is the ID of the parent category group. `null` if this is not a subcategory." created_at: type: string format: date-time description: The date and time when this budget entry was created (in ISO 8601 extended format). updated_at: type: string format: date-time description: The date and time when this budget entry was last updated (in ISO 8601 extended format). required: - id - category_id - amount - currency - start_date - next_start_date - auto_budget_type - granularity - quantity - is_group - created_at - updated_at # Request body for PUT /budgets (upsert) upsertBudgetRequestObject: x-internal: true type: object additionalProperties: false properties: start_date: type: string format: date description: Start date of the budget period in ISO 8601 date format (YYYY-MM-DD). Must be a valid budget period start for the account. category_id: type: integer format: int32 description: Category ID for the budget amount: oneOf: - type: number format: double - type: string pattern: ^-?\d+(\.\d{1,4})?$ description: Budget amount. May be a string or a number in double format. currency: allOf: - $ref: "#/components/schemas/currencyEnum" description: Three-letter currency code. If omitted, the primary currency for the user's account is used. notes: type: string nullable: true description: Optional notes for the budget period minLength: 0 maxLength: 350 required: - start_date - category_id - amount # Response body for PUT /budgets (200) budgetUpsertResponseObject: x-internal: true type: object properties: category_id: type: integer format: int32 description: Category ID start_date: type: string format: date description: Start date of the budget period amount: type: string description: Budget amount in the stored currency (string for consistency with other amount fields in the API) currency: type: string description: Currency code for the budget to_base: type: number format: float description: Amount converted to the user's primary currency notes: type: string nullable: true description: Notes for the budget period # Response body for GET /budgets/settings (200) budgetSettingsResponseObject: x-internal: true type: object additionalProperties: false description: Budget period and display settings properties: budget_period_granularity: type: string enum: - day - week - month - year - twice a month description: Budget period granularity budget_period_quantity: type: number format: double description: The number of `granularity` units that make up a single budgeting period. budget_period_anchor_date: type: string format: date description: The date from which the budgeting period is calculated. All future (and past) periods are derived by applying `quantity` × `granularity` forward and backward from this date. budget_hide_no_activity: type: boolean default: false description: The display preference for hiding categories in budget view that have no activity and no budgeted value budget_use_last_day_of_month: type: boolean default: false description: The display preference for using the last day of the month as the period end for monthly periods budget_income_option: type: string enum: - max - budgeted - activity description: Determines which income value is used as the base when calculating available funds for a budgeting period budget_rollover_left_to_budget: type: boolean default: false description: Determines whether the remaining unallocated funds (“Left to Budget”) at the end of a budgeting period are carried forward to the next period required: - budget_hide_no_activity - budget_period_quantity - budget_period_granularity - budget_period_anchor_date - budget_use_last_day_of_month - budget_income_option - budget_rollover_left_to_budget # Summary endpoint response schemas summaryResponseObject: type: object title: summary object additionalProperties: false description: Budget summary for the requested range properties: aligned: type: boolean description: "`true` if start_date and end_date are aligned with the user's budget period setting; `false` otherwise.

When the response is not aligned, category `totals` will not include values for the `budgeted` and `available` properties, so aligned responses are usually preferred.

If unsure how to set an aligned date range, set a range of at least one month and set the `include_occurrences` parameter to `true`. Then examine the objects in the `occurrences` array for the first category to find start and end dates that will produce aligned responses. Setting `include_past_budget_dates` to `true` will add the three budget periods prior to the range in the `occurrences` array." categories: type: array items: $ref: "#/components/schemas/summaryCategoryObject" totals: $ref: "#/components/schemas/summaryTotalsObject" rollover_pool: nullable: true $ref: "#/components/schemas/summaryRolloverPoolObject" required: - aligned - categories summaryTotalsObject: x-internal: true type: object additionalProperties: false description: Total inflow and outflow for the given date range. This object is returned when the query parameter `include_totals` is set to `true`. properties: inflow: $ref: "#/components/schemas/summaryTotalsBreakdownObject" outflow: $ref: "#/components/schemas/summaryTotalsBreakdownObject" summaryTotalsBreakdownObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs properties: other_activity: description: Total amount, in the user's default currency, of non recurring activity for the given date range type: number recurring_activity: description: Total amount, in the user's default currency, of recurring activity that has occurred for the given date range type: number recurring_remaining: description: Total amount, in the user's default currency, of expected recurring activity that has not yet occurred type: number recurring_expected: description: Total amount, in the user's default currency, of expected recurring activity for the given date range type: number uncategorized: description: Total amount, in the user's default currency, of non recurring activity coming from un-categorized transactions type: number uncategorized_count: description: Number of un-categorized transactions for the given date range type: integer uncategorized_recurring: description: "Total amount, in the user's default currency, of recurring activity coming from un-categorized transactions." type: number summaryCategoryObject: x-internal: true type: object additionalProperties: false description: "List of each category's budget configuration and activity for the date range." properties: category_id: description: "ID of the category associated with the totals." type: integer totals: $ref: "#/components/schemas/summaryCategoryTotalsObject" occurrences: description: A list of objects describing the budget activity for each period within the range. This property is only present when `include_occurrences` is true.

For aligned ranges, there is one occurrence for each budget period in the range; for non-aligned, only periods fully contained in the range are included.

If `include_past_budget_dates` is also `true`, the three budget periods prior to the range are also included. type: array items: $ref: "#/components/schemas/summaryCategoryOccurrenceObject" rollover_pool: $ref: "#/components/schemas/summaryRolloverPoolObject" required: - category_id - totals summaryRolloverPoolAdjustmentObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs description: "The date and adjusted balance of the rollover pool at the time of the adjustment." properties: in_range: description: "true if this rollover pool adjustment is for a budget period that falls within the given date range." type: boolean date: description: "Date the adjustment was made." type: string format: date amount: description: "Amount of the rollover pool, in the budgets currency, at the time of the adjustment." type: string currency: description: "Currency of the rollover pool at the time of the adjustment." allOf: - $ref: "#/components/schemas/currencyEnum" to_base: description: "Amount of the rollover pool, in the user's default currency, at the time of the adjustment." type: number required: - in_range - date - amount - currency - to_base summaryCategoryTotalsObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs description: "Total activity for the given category within the given date range which is aligned with budget period setting." properties: other_activity: description: Total non recurring activity, in the user's default currency, for the category within the given date range.
The total activity for the category is the sum of this and the recurring_activity. type: number recurring_activity: description: Total recurring activity, in the user's default currency, for the category within the given date range.
The total activity for the category is the sum of this and the other_activity. type: number budgeted: description: "Total budgeted amount, in the user's default currency, for the category within the given date range or null if the category is not budgeted. This property will not be present in a non-aligned response." type: number nullable: true available: description: "Total amount of funds available, in the user's default currency, for the category within the given date range. This property will not be present in a non-aligned response." type: number nullable: true recurring_remaining: description: "Total expected recurring activity, in the user's default currency, that has not yet occurred for the category within the given date range." type: number recurring_expected: description: "Total expected recurring activity for the category within the given date range." type: number required: - other_activity - recurring_activity - recurring_remaining - recurring_expected summaryCategoryOccurrenceObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs description: "" properties: in_range: description: "`true` if this occurrence is within the given date range, `false` if it was included because the `include_past_budget_periods` parameter was set to `true`." type: boolean start_date: description: The start date of the budget period type: string format: date end_date: description: The end date of the budget period type: string format: date other_activity: description: Total non recurring activity, in the user's default currency, for the budget period. The total activity for this category in the period is the sum of this and the recurring_activity. type: number recurring_activity: description: Total recurring activity, in the user's default currency, for the budget period. The total activity for this category in the budget period is the sum of this and the other_activity. type: number budgeted: description: "Total budgeted amount, in the user's primary currency, for the period, or `null` if no budget was set." type: number nullable: true budgeted_amount: description: Total budgeted amount, in the budgeted currency, for the category within the period, or `null` if no budget was set. type: string nullable: true budgeted_currency: description: Currency of the budgeted amount nullable: true allOf: - $ref: "#/components/schemas/currencyEnum" notes: description: "Any notes set for the budget period." type: string nullable: true required: - in_range - start_date - end_date - other_activity - recurring_activity - budgeted - budgeted_amount - budgeted_currency - notes summaryRecurringTransactionObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs description: "A single transaction associated with a recurring item. I don't think we will expose this in the summary since it's gettable by querying the recurring_id" properties: date: type: string format: date category_id: type: integer payee: type: string to_base: type: number amount: type: string currency: allOf: - $ref: "#/components/schemas/currencyEnum" required: - date - category_id - payee - to_base - amount - currency summaryRolloverPoolObject: type: object additionalProperties: false x-internal: true # Don't display in schemas section of docs description: "Summary of the current rollover pool balance and all previous adjustments.
Only present if the `include_rollover_pool` query parameter is set to `true`." properties: budgeted_to_base: description: "Amount of funds, in the user's default currency, currently available to rollover." type: number all_adjustments: description: List of previous adjustments to the rollover pool type: array items: $ref: "#/components/schemas/summaryRolloverPoolAdjustmentObject" required: - budgeted_to_base - all_adjustments # The schema for an object returned when an error occurs errorResponseObject: type: object title: error response object description: The object returned will any 4XX error response. Each response is guaranteed to have a `message` and at least one `error` object. properties: message: type: string description: "High level error type, for example 'Not Found' or 'Request Validation Failure'" errors: description: An list of objects that describe the errors encountered while processing the request.
If multiple errors were encountered, the list will contain multiple objects.
Each `error` object is guaranteed to have an `errMsg`, but it may also contain other error specific properties. type: array items: type: object properties: errMsg: type: string description: A message to help the developer determine the problem with the request. required: - errMsg additionalProperties: true required: - message - errors # Error response when start_date is not a valid budget period start (PUT /budgets 400) budgetInvalidPeriodErrorObject: x-internal: true type: object additionalProperties: false description: Returned when the requested start_date is not a valid budget period start for the account. properties: message: type: string description: Overall error message (e.g. Invalid Request) requested_start_date: type: string format: date description: The start_date value that was rejected previous_valid_start_date: type: string format: date nullable: true description: The previous valid budget period start date before the requested date next_valid_start_date: type: string format: date nullable: true description: The next valid budget period start date after the requested date errMsg: type: string description: Human-readable error message required: - message - requested_start_date - errMsg # Enums shared by multiple schemas # Define the allowed types for a manual account accountTypeEnum: type: string title: manual account type enum enum: - cash - credit - cryptocurrency - employee compensation - investment - loan - other liability - other asset - real estate - vehicle # Define the allowed types for the 3 letter currency codes # CSpell: disable # TODO see if we can avoid having the long doc string show up in the # docs for the models like userObject and transactionObject that reference # this. Ideally if users want to see the details we can offer a link instead. currencyEnum: type: string title: currency enum # Comment out this documentation until I can figure out how to override it # in the docs that include this schema. # description: | # Supported Currency codes: # - `aed`: United Arab Emirates Dirham # - `afn`: Afghan Afghani # - `all`: Albanian Lek # - `amd`: Armenian Dram # - `ang`: Netherlands Antillean Guilder # - `aoa`: Angolan Kwanza # - `ars`: Argentine Peso # - `aud`: Australian Dollar # - `awg`: Aruban Florin # - `azn`: Azerbaijani Manat # - `bam`: Bosnia-Herzegovina Convertible Mark # - `bbd`: Barbadian Dollar # - `bdt`: Bangladeshi Taka # - `bgn`: Bulgarian Lev # - `bhd`: Bahraini Dinar # - `bif`: Burundian Franc # - `bmd`: Bermudian Dollar # - `bnd`: Brunei Dollar # - `bob`: Bolivian Boliviano # - `brl`: Brazilian Real # - `bsd`: Bahamian Dollar # - `btc`: Bitcoin # - `btn`: Bhutanese Ngultrum # - `bwp`: Botswanan Pula # - `byn`: Belarusian Ruble # - `bzd`: Belize Dollar # - `cad`: Canadian Dollar # - `cdf`: Congolese Franc # - `chf`: Swiss Franc # - `clf`: Chilean Unit of Account (UF) # - `clp`: Chilean Peso # - `cny`: Chinese Yuan # - `cop`: Colombian Peso # - `crc`: Costa Rican Colón # - `cuc`: Cuban Convertible Peso # - `cup`: Cuban Peso # - `cve`: Cape Verdean Escudo # - `czk`: Czech Republic Koruna # - `djf`: Djiboutian Franc # - `dkk`: Danish Krone # - `dop`: Dominican Peso # - `dzd`: Algerian Dinar # - `egp`: Egyptian Pound # - `ern`: Eritrean Nakfa # - `etb`: Ethiopian Birr # - `eth`: Ethereum # - `eur`: Euro # - `fjd`: Fijian Dollar # - `fkp`: Falkland Islands Pound # - `gbp`: British Pound Sterling # - `gel`: Georgian Lari # - `ggp`: Guernsey Pound # - `ghs`: Ghanaian Cedi # - `gip`: Gibraltar Pound # - `gmd`: Gambian Dalasi # - `gnf`: Guinean Franc # - `gtq`: Guatemalan Quetzal # - `gyd`: Guyanaese Dollar # - `hkd`: Hong Kong Dollar # - `hnl`: Honduran Lempira # - `hrk`: Croatian Kuna # - `htg`: Haitian Gourde # - `huf`: Hungarian Forint # - `idr`: Indonesian Rupiah # - `ils`: Israeli New Sheqel # - `imp`: Isle of Man Pound # - `inr`: Indian Rupee # - `iqd`: Iraqi Dinar # - `irr`: Iranian Rial # - `isk`: Icelandic Króna # - `jep`: Jersey Pound # - `jmd`: Jamaican Dollar # - `jod`: Jordanian Dinar # - `jpy`: Japanese Yen # - `kes`: Kenyan Shilling # - `kgs`: Kyrgystani Som # - `khr`: Cambodian Riel # - `kmf`: Comorian Franc # - `kpw`: North Korean Won # - `krw`: South Korean Won # - `kwd`: Kuwaiti Dinar # - `kyd`: Cayman Islands Dollar # - `kzt`: Kazakhstani Tenge # - `lak`: Laotian Kip # - `lbp`: Lebanese Pound # - `lkr`: Sri Lankan Rupee # - `lrd`: Liberian Dollar # - `lsl`: Lesotho Loti # - `ltl`: Lithuanian Litas # - `lvl`: Latvian Lats # - `lyd`: Libyan Dinar # - `mad`: Moroccan Dirham # - `mdl`: Moldovan Leu # - `mga`: Malagasy Ariary # - `mkd`: Macedonian Denar # - `mmk`: Myanma Kyat # - `mnt`: Mongolian Tugrik # - `mop`: Macanese Pataca # - `mro`: Mauritanian Ouguiya # - `mur`: Mauritian Rupee # - `mvr`: Maldivian Rufiyaa # - `mwk`: Malawian Kwacha # - `mxn`: Mexican Peso # - `myr`: Malaysian Ringgit # - `mzn`: Mozambican Metical # - `nad`: Namibian Dollar # - `ngn`: Nigerian Naira # - `nio`: Nicaraguan Córdoba # - `nok`: Norwegian Krone # - `npr`: Nepalese Rupee # - `nzd`: New Zealand Dollar # - `omr`: Omani Rial # - `pab`: Panamanian Balboa # - `pen`: Peruvian Nuevo Sol # - `pgk`: Papua New Guinean Kina # - `php`: Philippine Peso # - `pkr`: Pakistani Rupee # - `pln`: Polish Zloty # - `pyg`: Paraguayan Guarani # - `qar`: Qatari Rial # - `ron`: Romanian Leu # - `rsd`: Serbian Dinar # - `rub`: Russian Ruble # - `rwf`: Rwandan Franc # - `sar`: Saudi Riyal # - `sbd`: Solomon Islands Dollar # - `scr`: Seychellois Rupee # - `sdg`: Sudanese Pound # - `sek`: Swedish Krona # - `sgd`: Singapore Dollar # - `shp`: Saint Helena Pound # - `sll`: Sierra Leonean Leone # - `sos`: Somali Shilling # - `srd`: Surinamese Dollar # - `std`: São Tomé and Príncipe Dobra # - `svc`: Salvadoran Colón # - `syp`: Syrian Pound # - `szl`: Swazi Lilangeni # - `thb`: Thai Baht # - `tjs`: Tajikistani Somoni # - `tmt`: Turkmenistani Manat # - `tnd`: Tunisian Dinar # - `top`: Tongan Paʻanga # - `try`: Turkish Lira # - `ttd`: Trinidad and Tobago Dollar # - `twd`: New Taiwan Dollar # - `tzs`: Tanzanian Shilling # - `uah`: Ukrainian Hryvnia # - `ugx`: Ugandan Shilling # - `usd`: United States Dollar # - `uyu`: Uruguayan Peso # - `uzs`: Uzbekistan Som # - `vef`: Venezuelan Bolívar # - `ves`: Venezuelan Bolívar Sotiemas # - `vnd`: Vietnamese Dong # - `vuv`: Vanuatu Vatu # - `wst`: Samoan Tala # - `xaf`: CFA Franc BEAC # - `xag`: Silver # - `xau`: Gold # - `xcd`: East Caribbean Dollar # - `xof`: CFA Franc BCEAO # - `xpf`: CFP Franc # - `yer`: Yemeni Rial # - `zar`: South African Rand # - `zmw`: Zambian Kwacha # - `zwl`: Zimbabwean Dollar enum: - aed - afn - all - amd - ang - aoa - ars - aud - awg - azn - bam - bbd - bdt - bgn - bhd - bif - bmd - bnd - bob - brl - bsd - btc - btn - bwp - byn - bzd - cad - cdf - chf - clf - clp - cny - cop - crc - cuc - cup - cve - czk - djf - dkk - dop - dzd - egp - ern - etb - eth - eur - fjd - fkp - gbp - gel - ggp - ghs - gip - gmd - gnf - gtq - gyd - hkd - hnl - hrk - htg - huf - idr - ils - imp - inr - iqd - irr - isk - jep - jmd - jod - jpy - kes - kgs - khr - kmf - kpw - krw - kwd - kyd - kzt - lak - lbp - lkr - lrd - lsl - ltl - lvl - lyd - mad - mdl - mga - mkd - mmk - mnt - mop - mro - mur - mvr - mwk - mxn - myr - mzn - nad - ngn - nio - nok - npr - nzd - omr - pab - pen - pgk - php - pkr - pln - pyg - qar - ron - rsd - rub - rwf - sar - sbd - scr - sdg - sek - sgd - shp - sll - sos - srd - std - svc - syp - szl - thb - tjs - tmt - tnd - top - try - ttd - twd - tzs - uah - ugx - usd - uyu - uzs - vef - ves - vnd - vuv - wst - xaf - xag - xau - xcd - xof - xpf - yer - zar - zmw - zwl # CSpell: enable # These responses are defined primarily to provide examples in the docs responses: unauthorizedToken: description: Unauthorized. This error occurs when an invalid API token is passed to the request. content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Unauthorized errors: - errMsg: Access token does not exist. rateLimited: description: Too Many Requests. Retry your request after the number of seconds specified in the retry-after header. content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Too Many Requests errors: - errMsg: Too many requests, please try again later. serverError: description: Internal Server Error. Contact support. content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Internal Server Error errors: - errMsg: Currently in maintenance mode. Please try again in a few minutes. securitySchemes: bearerSecurity: type: http # TODO Make this shorter? # description: The Lunch Money API uses API keys to authenticate requests. To use # the v1 API you can view and manage your API keys on the [developers page # in the Lunch Money app](https://my.lunchmoney.app/developers).

To # interact with the Static Mock Server simply enter an API key of 11 # characters or more.

To interact with the v2 service implemented on # top of the v1 API paste in a real API token associated with a Lunch # Money Budget. description: To interact with the Static Mock Server simply enter an API key of 11 characters or more. scheme: bearer bearerFormat: JWT cookieAuth: type: apiKey in: cookie name: _lm_access_token paths: /me: get: tags: - me summary: Get current user description: Get details about the user associated with the supplied authorization token. operationId: getMe parameters: [] responses: "200": description: The User Object associated with the authorized token. content: application/json: schema: $ref: "#/components/schemas/userObject" example: name: User 1 email: user-1@lunchmoney.dev id: 18328 account_id: 18221 budget_name: \U0001F3E0 Family budget primary_currency: usd api_key_label: Side project dev key "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /summary: get: tags: - summary summary: Get summary description: Retrieves a summary of the user's budget. Use this endpoint to access budget configuration details and performance for a specified date range.

Use the [/budgets](#tag/budgets) endpoint to manage budget objects. operationId: getBudgetSummary parameters: - in: query name: start_date description: Start of date range in ISO 8601 date format (YYYY-MM-DD). required: true schema: type: string format: date examples: "aligned monthly": summary: "Start date for monthly budget period" description: "First day of month for aligned budget periods" value: "2025-07-01" "not aligned": summary: "Start date for non-aligned period" description: "Date that doesn't align with budget periods" value: "2025-07-02" - in: query name: end_date description: "End of date range in ISO 8601 date format (YYYY-MM-DD)." required: true schema: type: string format: date examples: "aligned monthly": summary: "End date for monthly budget period" description: "Last day of month for aligned budget periods" value: "2025-08-31" "not aligned": summary: "End date for non-aligned period" description: "Date that doesn't align with budget periods" value: "2025-08-27" - in: query name: include_exclude_from_budgets description: Enable to include categories that have the 'Exclude from Budgets' flag set in the returned `categories` array. required: false schema: type: boolean default: false - in: query name: include_occurrences description: Enable to include an `occurrences` array for each category in an aligned response. Each array will include an object for each budget period that falls within the specified date range which includes details on the activity for the budget period. required: false schema: type: boolean default: false - in: query name: include_past_budget_dates description: "Enable to include the three budget occurrences prior to the start date in the `occurrences` array for each category in an aligned response. This property is ignored if `include_occurrences` is not also set to `true`." required: false schema: type: boolean default: false - in: query name: include_totals description: "Enable to include a top-level `totals` section that summarizes the inflow and outflow across all transactions for the specified date range." required: false schema: type: boolean default: false - in: query name: include_rollover_pool description: "Enable to include a `rollover_pool` section that summarizes the current rollover pool balance and all previous adjustments." required: false schema: type: boolean default: false responses: "200": description: "Summary of the user's budget for the specified date range." content: application/json: schema: $ref: "#/components/schemas/summaryResponseObject" examples: "aligned monthly": summary: "Monthly budget summary aligned with budget periods" description: "Example response for a date range that aligns with monthly budget periods (1st to last day of month) with occurrences included" value: aligned: true categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 500 available: 343.36 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 156.64 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Adjusted for seasonal spending" - category_id: 315628 totals: other_activity: 424.8 recurring_activity: 0 budgeted: 200 available: -224.8 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 424.8 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Based on previous month's activity" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Emergency fund contribution" - category_id: 86 totals: other_activity: 25.69 recurring_activity: 0 budgeted: 200 available: 174.31 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 25.69 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Holiday spending budget" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Summer vacation savings" "not aligned": summary: "Budget summary for non-aligned date range" description: "Example response for a date range that does not align with monthly budget periods (July 2 to August 27)" value: aligned: false categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 400 available: 243.36 recurring_remaining: 0 recurring_expected: 0 - category_id: 315628 totals: other_activity: 424.8 recurring_activity: 0 budgeted: null available: null recurring_remaining: 0 recurring_expected: 0 - category_id: 78 totals: other_activity: 0 recurring_activity: 0 budgeted: null available: null recurring_remaining: 0 recurring_expected: 0 - category_id: 83 totals: other_activity: 0 recurring_activity: 0 budgeted: null available: null recurring_remaining: 1700 recurring_expected: 1700 - category_id: 88 totals: other_activity: 0 recurring_activity: 2501.68 budgeted: null available: null recurring_remaining: 0 recurring_expected: 2501.68 - category_id: 86 totals: other_activity: 25.69 recurring_activity: 0 budgeted: 200 available: 174.31 recurring_remaining: 0 recurring_expected: 0 - category_id: 84 totals: other_activity: 401.12 recurring_activity: 4.13 budgeted: 150 available: -255.25 recurring_remaining: -4.13 recurring_expected: 0 "summarized totals": summary: "Monthly budget summary with totals included" description: "Example response for aligned monthly budget periods with totals section showing overall inflow and outflow" value: aligned: true categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 400 available: 243.36 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 156.64 recurring_activity: 0 budgeted: 400 budgeted_amount: "400.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" - category_id: 315628 totals: other_activity: 424.8 recurring_activity: 0 budgeted: 200 available: -224.8 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 424.8 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Based on previous month's activity" - category_id: 315629 totals: other_activity: 0 recurring_activity: 0 budgeted: 150 available: 150 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 0 recurring_activity: 0 budgeted: 150 budgeted_amount: "150.0000" budgeted_currency: "usd" notes: "Emergency fund contribution" totals: inflow: other_activity: -125.50 recurring_activity: -89.99 uncategorized: 0 uncategorized_count: 0 uncategorized_recurring: 0 outflow: other_activity: 581.44 recurring_activity: 0 uncategorized: 45.20 uncategorized_count: 3 uncategorized_recurring: 0 "with occurrences": summary: "Monthly budget summary with occurrences included" description: "Example response for aligned monthly budget periods with occurrences showing individual budget period details for each category" value: aligned: true categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 500 available: 343.36 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 156.64 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Adjusted for seasonal spending" - category_id: 315628 totals: other_activity: 424.8 recurring_activity: 0 budgeted: 200 available: -224.8 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 424.8 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Based on previous month's activity" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Emergency fund contribution" - category_id: 86 totals: other_activity: 25.69 recurring_activity: 0 budgeted: 200 available: 174.31 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 25.69 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Holiday spending budget" - in_range: true start_date: "2025-08-01" end_date: "2025-08-31" other_activity: 0 recurring_activity: 0 budgeted: 200 budgeted_amount: "200.0000" budgeted_currency: "usd" notes: "Summer vacation savings" "with past occurrences": summary: "Monthly budget summary with past occurrences included" description: "Example response for aligned monthly budget periods with include_past_budget_dates=true, showing 3 past occurrences with in_range: false" value: aligned: true categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 500 available: 343.36 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: false start_date: "2025-04-01" end_date: "2025-04-30" other_activity: 120.50 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" - in_range: false start_date: "2025-05-01" end_date: "2025-05-31" other_activity: 180.25 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: null - in_range: false start_date: "2025-06-01" end_date: "2025-06-30" other_activity: 200.00 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Adjusted for seasonal spending" - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 156.64 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" "with rollover pool": summary: "Monthly budget summary with rollover pool included" description: "Example response for aligned monthly budget periods with include_rollover_pool=true, showing rollover pool data for categories with budgets" value: aligned: true categories: - category_id: 315177 totals: other_activity: 156.64 recurring_activity: 0 budgeted: 500 available: 343.36 recurring_remaining: 0 recurring_expected: 0 occurrences: - in_range: true start_date: "2025-07-01" end_date: "2025-07-31" other_activity: 156.64 recurring_activity: 0 budgeted: 500 budgeted_amount: "500.0000" budgeted_currency: "usd" notes: "Monthly budget allocation" rollover_pool: budgeted_to_base: 179.50 all_adjustments: - in_range: false date: "2025-06-30" amount: "179.5000" currency: "usd" to_base: 179.50 - in_range: false date: "2025-05-31" amount: "120.2500" currency: "usd" to_base: 120.25 - in_range: false date: "2025-04-30" amount: "80.0000" currency: "usd" to_base: 80.00 "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /categories: get: tags: - categories summary: Get all categories description: Retrieve a list of all categories associated with the user's account. operationId: getAllCategories parameters: - name: format in: query description: If `nested`, returns top-level categories (either category groups or categories not part of a category group) in alphabetical order. Grouped categories are nested within the category group under the property `children`. A `flattened`, response is similar but it includes grouped categories at the top level.

Categories are sorted by their `order`. When `order` is null, they are listed in alphabetical order below other categories with an `order`. required: false schema: type: string default: nested enum: - nested - flattened - name: is_group in: query description: If `false`, only categories not part of a category group are returned.
If `true`, only category groups are returned.
When set, the `format` parameter is ignored. required: false schema: type: boolean responses: "200": description: A list of Category Objects content: application/json: schema: type: object properties: categories: type: array items: $ref: "#/components/schemas/categoryObject" examples: nested response: value: categories: - id: 86 name: Automobile description: Auto related categories is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: true order: 2 collapsed: false archived: false group_id: null archived_at: null children: - id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 1 collapsed: false archived: false group_id: 86 archived_at: null - id: 315175 name: Maintenance description: Car maintenance and repairs is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 2 collapsed: false archived: false group_id: 86 archived_at: null - id: 83 name: Rent description: Monthly Rent is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.225Z" created_at: "2025-01-28T09:49:03.225Z" is_group: false order: 0 collapsed: false archived: false group_id: null archived_at: null - id: 88 name: W2 Income description: null is_income: true exclude_from_budget: false exclude_from_totals: true updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 3 collapsed: false archived: false group_id: null archived_at: null flattened response: value: categories: - id: 86 name: Automobile description: Auto related categories is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: true order: 1 collapsed: false archived: false group_id: null archived_at: null children: - id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 1 collapsed: false archived: false group_id: 86 archived_at: null - id: 315175 name: Maintenance description: Car maintenance and repairs is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 2 collapsed: false archived: false group_id: 86 archived_at: null - id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 1 collapsed: false archived: false group_id: 86 archived_at: null - id: 315175 name: Maintenance description: Car maintenance and repairs is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 2 collapsed: false archived: false group_id: 86 archived_at: null - id: 83 name: Rent description: Monthly Rent is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.225Z" created_at: "2025-01-28T09:49:03.225Z" is_group: false order: 2 collapsed: false archived: false group_id: null archived_at: null - id: 88 name: W2 Income description: null is_income: true exclude_from_budget: false exclude_from_totals: true updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: false order: 3 collapsed: false archived: false group_id: null archived_at: null "400": description: Invalid request parameters content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be equal to one of the allowed values instancePath: /query/format schemaPath: "#/properties/query/properties/format/enum" keyword: enum params: allowedValues: - flattened - nested "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" post: tags: - categories summary: Create a new category or category group description: Creates a new category with the given name.
If the `is_group` attribute is set to true, a category group is created. In this case, the `children` attribute may be set to an array of existing category IDs to add to the newly-created category group. operationId: createCategory requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/createCategoryRequestObject" examples: category: value: name: API Created Category description: Test description of created category is_income: false exclude_from_budget: true exclude_from_totals: false is_group: false category group: value: name: API Created Category Group description: Test description of Category Group is_income: false exclude_from_budget: false exclude_from_totals: false is_group: true children: - 83 responses: "201": description: Category or Category Group Object with the successfully created category or category group. content: application/json: schema: $ref: "#/components/schemas/categoryObject" examples: category: value: id: 90 name: API Created Category description: Test description of created category is_income: false exclude_from_budget: true exclude_from_totals: false updated_at: "2025-05-26T19:56:52.699Z" created_at: "2025-05-26T19:56:52.699Z" is_group: false group_id: null archived: false archived_at: null order: null collapsed: false category group: value: id: 91 name: API Created Category Group description: Test description of Category Group is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-05-27T19:59:45.053Z" created_at: "2025-05-27T19:59:45.053Z" is_group: true group_id: null archived: false archived_at: null order: null collapsed: false children: - id: 83 name: Rent description: Monthly Rent is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.225Z" created_at: "2025-01-28T09:49:03.225Z" is_group: false order: 1 collapsed: false archived: false group_id: null archived_at: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Invalid Request Body errors: - errMsg: Cannot specify a 'group_id' in request body if 'is_group' is also true "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /categories/{id}: get: tags: - categories summary: Get a single category description: Retrieve details of a specific category or category group by its ID. operationId: getCategoryById parameters: - name: id in: path description: ID of the category to retrieve required: true schema: type: integer format: int32 examples: category: summary: Example of a category's id value: 315174 category group: summary: Example of a category group's id value: 86 id not found: summary: Example of an id that doesn't exist value: 543210 responses: "201": description: Category Object with the requested category or category group. content: application/json: schema: $ref: "#/components/schemas/categoryObject" examples: category: value: id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" group_id: 86 is_group: false archived: false archived_at: null order: 1 collapsed: false category group: value: id: 86 name: Automobile description: Auto related categories is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" is_group: true order: 2 collapsed: false archived: false group_id: null archived_at: null children: - id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" group_id: 86 is_group: false archived: false archived_at: null order: 1 collapsed: false - id: 315175 name: Maintenance description: Car maintenance and repairs is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" group_id: 86 is_group: false archived: false archived_at: null order: 2 collapsed: false "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be a valid integer instancePath: /query/ids/0 schemaPath: "#/properties/query/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no category with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" put: tags: - categories summary: Update an existing category or category group description: >- Modifies the properties of an existing category or category group.

You may submit the response from a `GET /categories/{id}` as the request body; however, only certain properties can be updated using this API. The following properties are accepted in the request body but their values will be ignored: `id`, `is_group`, `updated_at`, `created_at`, and `order`.

It is also possible to provide only the properties to be updated in the request body, as long as the request includes at least one of the properties that is not listed above. For example, a request body that contains only a `name` property is valid.

It is not possible to use this API to convert a category to a category group, or a vice versa, so while submitting a request body with the `is_group` property is tolerated, it will result in an error response if the value is changed.

It is possible to modify the children of an existing category group with this API by setting the `children` attribute. If this is set, it will replace the existing children with the newly specified children. If the intention is to add or remove a single category, it is more straightforward to update the child category by specifying the new `group_id` attribute. If the goal is to add multiple new children or remove multiple existing children, it is recommended to first call the `GET /categories/:id` endpoint to get the existing children and then modify the list as desired.

operationId: updateCategory parameters: - name: id in: path description: ID of the category to update required: true schema: type: integer format: int32 examples: category: summary: Example of a category's id value: 83 category group: summary: Example of a category group's id value: 86 child category: summary: Example of a category belonging to a group value: 315164 not found: summary: Example of a category id that does not exist value: 543210 requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/updateCategoryRequestObject" examples: Update some category properties: value: name: Updated Category Name description: Updated description of the category Update same properties with full object: value: id: 83 name: Updated Category Name description: Updated description of the category is_income: false exclude_from_budget: true exclude_from_totals: false updated_at: "2020-01-28T09:49:03.225Z" created_at: "2020-01-28T09:49:03.225Z" is_group: false group_id: null archived: false archived_at: null order: 0 Invalid attempt to convert to category group: value: id: 83 name: Old Category is now a group! is_group: true Remove category from a group: value: id: 86 name: Automobile description: API Removed a sub category children: - 315174 responses: "200": description: Category or Category Group updated successfully content: application/json: schema: $ref: "#/components/schemas/categoryObject" examples: category: value: id: 83 name: Updated Category Name description: Updated description of the category is_income: false exclude_from_budget: false exclude_from_totals: true updated_at: "2025-05-26T20:41:18.406Z" created_at: "2025-01-28T09:49:03.225Z" is_group: false order: 0 collapsed: false archived: false archived_at: null group_id: null category group: value: id: 86 name: Automobile description: API Removed a sub category is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-06-22T19:54:30.921Z" created_at: "2025-01-28T09:49:03.238Z" is_group: true order: 2 collapsed: false archived: false group_id: null archived_at: null children: - id: 315174 name: Fuel description: Fuel and gas expenses is_income: false exclude_from_budget: false exclude_from_totals: false updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" group_id: 86 is_group: false archived: false archived_at: null order: 1 collapsed: false "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Invalid Request Body errors: - errMsg: Cannot modify the 'group_id' property of an existing category or category group "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no category with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - categories summary: Delete a category or category group description: Attempts to delete the single category or category group specified on the path. By default, this will only work if there are no dependencies, such as existing budgets for the category, categorized transactions, children categories for a category group, categorized recurring items, etc. If there are dependents, this endpoint will return an object that describes the amount and type of existing dependencies. operationId: deleteCategory parameters: - in: path name: id description: ID of the category to delete required: true schema: type: integer format: int32 examples: delete category: summary: Simple category delete value: 83 delete category group: summary: Attempt to delete category with dependencies value: 84 id not found: summary: Example of an id that doesn't exist value: 543210 - in: query name: force description: Set to `true` to force deletion even if there are dependencies required: false schema: type: boolean default: false responses: "204": description: No Content "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no category with the id: 543210." "422": description: Unprocessable Entity content: application/json: schema: $ref: "#/components/schemas/deleteCategoryResponseWithDependencies" examples: delete category with dependencies: summary: Response to an attempt to delete category with dependencies value: category_name: Category to be Deleted dependents: budget: 0 category_rules: 1 transactions: 10 children: 0 recurring: 0 plaid_cats: 0 delete category group: summary: Response to attempt to delete a category group with children value: category_name: Category Group to be Deleted dependents: budget: 0 category_rules: 0 transactions: 0 children: 3 recurring: 0 plaid_cats: 0 "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /manual_accounts: get: tags: - manual_accounts summary: Get all manual accounts description: Retrieve a list of all manually-managed accounts associated with the user's account. operationId: getAllManualAccounts responses: "200": description: A list of manual accounts content: application/json: schema: type: object properties: manual_accounts: type: array items: $ref: "#/components/schemas/manualAccountObject" example: manual_accounts: - id: 119807 name: Individual Brokerage institution_name: Fidelity display_name: null type: investment subtype: brokerage balance: "41211.8000" currency: usd to_base: 41211.8 balance_as_of: "2025-06-25T17:00:04.000Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2025-06-25T17:00:04.414Z" updated_at: "2025-06-26T19:03:38.312Z" - id: 119909 name: Euro Travel Card institution_name: WeBank display_name: null type: credit subtype: credit card balance: "1004.8000" currency: usd to_base: 1004.8 balance_as_of: "2023-06-25T17:00:04.000Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2025-06-25T17:00:04.414Z" updated_at: "2025-06-26T19:03:38.312Z" "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must NOT have additional properties instancePath: /query schemaPath: "#/properties/query/additionalProperties" keyword: additionalProperties params: additionalProperty: foo "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" post: tags: - manual_accounts summary: Create a manual account description: Create a new manually-managed account. operationId: createManualAccount requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/createManualAccountRequestObject" examples: minimum request body: summary: Minimum required fields for creating a manual account value: name: API created Account type: cash balance: "100" full example: summary: Full example with all fields value: name: API created loan type: vehicle subtype: loan display_name: Car loan balance: "9999.99" balance_as_of: "2024-10-12" closed_on: null currency: usd institution_name: Bank of America exclude_from_transactions: false display_name not unique: summary: Explicit display_name not unique value: name: API created card type: credit display_name: WeBank Euro Travel Card balance: "1004.8000" implicit display_name not unique: summary: Derived display_name not unique value: name: Individual Brokerage type: investment institution_name: Fidelity balance: "41211.8000" responses: "201": description: Successfully created manual account content: application/json: schema: $ref: "#/components/schemas/manualAccountObject" examples: minimum request response: value: id: 119999 name: API created Account institution_name: null display_name: null type: cash subtype: null balance: "100" currency: usd to_base: 100 balance_as_of: "2024-10-06T18:55:08.599Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2024-10-06T18:55:08.599Z" updated_at: "2024-10-06T18:55:08.599Z" complete request response: value: id: 119999 name: API created loan institution_name: Bank of America display_name: Car loan type: vehicle subtype: loan balance: "9999.99" currency: usd to_base: 9999.99 balance_as_of: "2024-10-06T18:55:08.599Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2024-10-06T18:57:12.029Z" updated_at: "2024-10-06T18:57:12.029Z" "400": description: Invalid request body content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: missing required properties: value: message: Request Validation Failure errors: - errMsg: "Missing required property 'name' in request body." - errMsg: "Missing required property 'type' in request body." - errMsg: "Missing required property 'balance' in request body." explicit display_name not unique: value: message: Request Validation Failure errors: - errMsg: "A manual account with the same display_name: 'WeBank Travel Card' already exists." existing_manual_account_id: 219909 requested_display_name: "WeBank Travel Card" existing_display_name: "WeBank Travel Card" existing_name: "Euro Travel Card" requested_name: "API created card" implicit display_name not unique: value: message: Request Validation Failure errors: - errMsg: "A manual account with the same implicit display_name derived from name: 'Individual Brokerage' and institution_name: 'Fidelity' already exists." existing_manual_account_id: 219807 requested_name: Individual Brokerage existing_name: Individual Brokerage requested_institution_name: Fidelity existing_institution_name: Fidelity "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /manual_accounts/{id}: get: tags: - manual_accounts summary: Get a single manual account description: Retrieve the details of the manual account with the specified ID. operationId: getManualAccountById parameters: - name: id in: path description: ID of the manual account to retrieve required: true schema: type: integer format: int32 examples: basic manual account: summary: Basic manual account by id request value: 119807 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "200": description: Manual Account Object with the requested account content: application/json: schema: $ref: "#/components/schemas/manualAccountObject" example: id: 119807 name: Individual Brokerage institution_name: Fidelity display_name: null type: investment subtype: brokerage balance: "41211.8000" currency: usd to_base: 41211.8 balance_as_of: "2025-06-25T17:00:04.000Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2025-06-25T17:00:04.414Z" updated_at: "2025-06-26T19:03:38.312Z" "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: invalid account id type: value: message: Invalid Path Parameters errors: - errMsg: "Invalid value type for path parameter: 'id'. Expected 'number', received 'string'." "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: There is no manual account with the id:'9999999999999'` "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" put: tags: - manual_accounts summary: Update an existing manual account description: >- Modifies the properties of an existing manual account.

You may submit the response from a `GET /manual_accounts/{id}` as the request body, however only certain properties can be updated using this API. The following system set properties are accepted in the request body but their values will be ignored: `id`, `to_base`, `created_at`, and `updated_at`.

It is also possible to provide only the properties to be updated in the request body, as long as the request includes at least one of the properties that is not listed above. For example a request body that contains only a `name` property is valid.

operationId: updateManualAccount parameters: - name: id in: path description: ID of the manual account to update required: true schema: type: integer format: int32 examples: category: summary: Example of a manual account's id value: 119807 not found: summary: Example of a manual account ID that does not exist value: 999999999 requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/updateManualAccountRequestObject" examples: minimum request body: summary: type change value: type: credit close account: summary: close and exclude value: closed_on: "2024-10-15" exclude_from_transactions: true use get request: summary: Only display name has changed value: id: 119909 name: Euro Travel Card type: credit subtype: credit card display_name: New Display Name balance: "1004.8000" balance_as_of: "2023-06-25T17:00:04.000Z" closed_on: null currency: usd institution_name: WeBank exclude_from_transactions: false created_at: "2025-06-25T17:00:04.414Z" updated_at: "2025-06-26T19:03:38.312Z" responses: "200": description: Manual Account updated successfully content: application/json: schema: $ref: "#/components/schemas/manualAccountObject" examples: type changed to credit: value: id: 119807 name: Individual Brokerage institution_name: Fidelity display_name: null type: investment subtype: brokerage balance: "41211.8000" currency: usd to_base: 41211.8 balance_as_of: "2025-06-25T17:00:04.000Z" status: active closed_on: null external_id: null exclude_from_transactions: false created_by_name: User 1 created_at: "2025-06-25T17:00:04.414Z" updated_at: "2025-06-26T19:03:38.312Z" closed account: value: id: 119807 name: Individual Brokerage institution_name: Fidelity display_name: null type: investment subtype: brokerage balance: "41211.8000" currency: usd to_base: 41211.8 balance_as_of: "2025-06-25T17:00:04.000Z" status: closed closed_on: "2024-10-06" external_id: null exclude_from_transactions: true created_by_name: User 1 created_at: "2025-06-25T17:00:04.414Z" updated_at: "2024-10-06T19:03:09.506Z" "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: missing required properties: value: message: Invalid Request Body errors: - errMsg: "A request to update a manual account must include at least one of the following properties: name, type, subtype, display_name, balance, balance_as_of, closed_on, currency, institution_name, exclude_from_transactions" duplicate display_name: value: message: Request Validation Failure errors: - errMsg: "A manual account with the same display_name: 'WeBank Travel Card' already exists." existing_manual_account_id: 219909 requested_display_name: "WeBank Travel Card" existing_display_name: "WeBank Travel Card" existing_name: "Euro Travel Card" requested_name: "API created card" "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no manual account with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - manual_accounts summary: Delete a manual account description: Deletes the single manual account with the ID specified on the path. If any transactions exist with the `manual_account_id` property set to this account's ID they will appear with a warning when displayed in the web view. operationId: deleteManualAccount parameters: - in: path name: id description: ID of the manual account to delete required: true schema: type: integer format: int32 examples: delete manual account: summary: Account ID to delete value: 119807 id not found: summary: Example of an id that doesn't exist value: 543210 - in: query name: delete_items description: When set to true will also delete any transactions, rules, and recurring items associated with this account. Use this option with caution, it is irreversible! required: false schema: type: boolean default: false - in: query name: delete_balance_history description: When set to true will delete any balance history associated with this account. required: false schema: type: boolean default: false responses: "204": description: No Content "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no manual account with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /plaid_accounts: get: tags: - plaid_accounts summary: Get all accounts synced via Plaid description: Retrieve a list of all synced accounts associated with the user's account. operationId: getAllPlaidAccounts responses: "200": description: A list of accounts synced via Plaid content: application/json: schema: type: object properties: plaid_accounts: type: array items: $ref: "#/components/schemas/plaidAccountObject" example: plaid_accounts: - id: 119804 plaid_item_id: "aB2cD3eF4gH5iJ6kL7mN8oP9qR0sT1uV2wX3yZ4" date_linked: "2020-01-28" linked_by_name: User 1 name: 401k display_name: "" type: brokerage subtype: 401k mask: "7468" institution_name: Vanguard status: inactive allow_transaction_modifications: false limit: null balance: "12345.6700" currency: usd to_base: 12345.67 balance_last_update: "2025-01-27T01:38:11.862Z" import_start_date: "2023-01-01" last_import: "2025-01-24T12:57:09.190Z" last_fetch: "2025-01-28T01:38:11.862Z" plaid_last_successful_update: "2025-01-27T01:38:11.862Z" - id: 119805 plaid_item_id: "xY9zW8vU7tS6rQ5pO4nM3lK2jI1hG0fE9dC8bA7" date_linked: "2020-01-28" linked_by_name: User 1 name: Freedom display_name: Penny's Visa type: credit subtype: credit card mask: "1973" institution_name: Chase status: active allow_transaction_modifications: true limit: 15000 balance: "0.0000" currency: usd to_base: 0 balance_last_update: "2025-01-27T01:38:07.460Z" import_start_date: "2023-01-01" last_import: "2025-01-24T12:57:03.250Z" last_fetch: "2025-01-28T01:38:11.862Z" plaid_last_successful_update: "2025-01-27T01:38:11.862Z" - id: 119807 plaid_item_id: "mK8nL9oP0qR1sT2uV3wX4yZ5aB6cD7eF8gH9iJ0" date_linked: "2020-01-28" linked_by_name: User 1 name: Checking display_name: Penny's Checking type: cash subtype: checking mask: "2046" institution_name: Western Bank status: active allow_transaction_modifications: true limit: null balance: "5498.2800" currency: usd to_base: 5498.28 balance_last_update: "2025-01-27T01:38:07.460Z" import_start_date: "2023-01-01" last_import: "2025-01-24T12:57:03.250Z" last_fetch: "2025-01-28T01:38:11.862Z" plaid_last_successful_update: "2025-01-27T01:38:11.862Z" "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must NOT have additional properties instancePath: /query schemaPath: "#/properties/query/additionalProperties" keyword: additionalProperties params: additionalProperty: foo "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /plaid_accounts/{id}: get: tags: - plaid_accounts summary: Get a single account that is synced via Plaid description: Retrieve the details of the plaid account with the specified ID. operationId: getPlaidAccountById parameters: - name: id in: path description: ID of the plaid account to retrieve required: true schema: type: integer format: int32 examples: basic manual account: summary: Basic plaid account by id request value: 119805 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "200": description: Plaid Account Object with the requested account. content: application/json: schema: $ref: "#/components/schemas/plaidAccountObject" example: id: 119805 plaid_item_id: "xY9zW8vU7tS6rQ5pO4nM3lK2jI1hG0fE9dC8bA7" date_linked: "2020-01-28" linked_by_name: User 1 name: Freedom display_name: Penny's Visa type: credit subtype: credit card mask: "1973" institution_name: Chase status: active allow_transaction_modifications: true limit: 15000 balance: "0.0000" currency: usd to_base: 0 balance_last_update: "2025-01-27T01:38:07.460Z" import_start_date: "2023-01-01" last_import: "2025-01-24T12:57:03.250Z" last_fetch: "2025-01-28T01:38:11.862Z" plaid_last_successful_update: "2025-01-27T01:38:11.862Z" "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be integer instancePath: /path/id schemaPath: "#/properties/path/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no plaid account with the id: 9999999999999" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /plaid_accounts/fetch: post: tags: - plaid_accounts summary: Trigger Fetch from Plaid description: >- Use this endpoint to trigger a fetch for latest data from Plaid.

Eligible accounts are those who last_fetch value is over 1 minute ago. (Although the limit is every minute, please use this endpoint sparingly!) Successive calls to this endpoint under a minute after the first will return a 425 TOO EARLY response.

Successful calls will return a 202 ACCEPTED response. Note that fetching from Plaid is a background job. This endpoint simply queues up the job. You may track the `plaid_last_successful_update`, `last_fetch` and `last_import` properties to verify the results of the fetch. The `last fetch` property is updated when Plaid accepts a request to fetch data. The `plaid_last_successful_update`is updated when it successfully contacts the associated financial institution. The `last_import` field is updated only when new transactions have been imported. operationId: triggerPlaidAccountFetch parameters: - name: start_date in: query schema: type: string format: date description: Denotes the beginning of the time period to fetch transactions for. If omitted, the most recent transactions will be returned.
Required if end_date exists.
- name: end_date in: query schema: type: string format: date description: "Denotes the end of the time period you'd like to get transactions for. Required if start_date exists. " - name: id in: query description: Specific ID of a plaid account to fetch. If not set the endpoint will trigger a fetch for all eligible accounts. schema: type: integer format: int32 examples: basic manual account: summary: Basic manual account by id request value: 119807 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "202": description: A 202 ACCEPTED status is returned if Plaid acknowledged the fetch request. This indicates that it is possible to subsequently query the `GET /plaid_accounts` endpoint to determine if the request was successful (`plaid_last_successful_update` is more recent than `last_fetch), or if new transactions were synced (`last_import` is more recent than `last_fetch`).
"400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: missing end_date: value: message: Invalid Request Parameters errors: - errMsg: "Both 'start_date' and 'end_date' must be specified." invalid id type: value: message: Request Validation Failure errors: - errMsg: must be integer instancePath: /path/id schemaPath: "#/properties/path/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "425": description: Too Early content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Too Early errors: - errMsg: "Please wait at least 60 seconds between fetch requests." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions: get: tags: - transactions (bulk) summary: Get all transactions description: Retrieve a list of all transactions associated with a user's account.
If called with no parameters, this endpoint will return the most recent transactions up to `limit` number of transactions. operationId: getAllTransactions parameters: - name: start_date in: query schema: type: string format: date description: Denotes the beginning of the time period to fetch transactions for. If omitted, the most recent transactions will be returned. See `limit`. Required if end_date exists.
- name: end_date in: query schema: type: string format: date description: "Denotes the end of the time period you'd like to get transactions for. Required if start_date exists. " - name: created_since in: query schema: oneOf: - type: string format: date - type: string format: date-time description: Filter transactions to those created after the specified timestamp. Accepts either a date (YYYY-MM-DD) or ISO 8601 datetime string. Date-only values are interpreted as midnight UTC (00:00:00Z). - name: updated_since in: query schema: oneOf: - type: string format: date - type: string format: date-time description: Filter transactions to those updated after the specified timestamp. Accepts either a date (YYYY-MM-DD) or ISO 8601 datetime string. Date-only values are interpreted as midnight UTC (00:00:00Z). - name: manual_account_id in: query schema: type: integer format: int32 description: Filter transactions to those associated with specified manual account ID or set this to 0 to omit any transactions from manual accounts. Setting both this and `plaid_account_id` to 0 will return transactions with no account. These are listed as "Cash Transactions" in the Lunch Money GUI.
Note that transaction groups are not associated with any account. If you want the response to include transactions from transaction groups, set the `include_group_children` query parameter to `true` when filtering by manual accounts. examples: euro travel card: value: 219909 no manual accounts: value: 0 - name: plaid_account_id in: query schema: type: integer format: int32 description: Filter transactions to those associated with specified plaid account ID or set this to 0 to omit any transactions from plaid accounts. Setting both this and `manual_account_id` to 0 will return transactions with no account. These are listed as "Cash Transactions" in the Lunch Money GUI.
Note that transaction groups are not associated with any account. If you want the response to include transactions from transaction groups, set the `include_group_children` query parameter to `true` when filtering by plaid accounts. examples: brokerage account: value: 119807 no plaid accounts: value: 0 - name: recurring_id in: query schema: type: integer format: int32 description: > Filter transactions to those associated with specified Recurring Item ID examples: paychecks: value: 994069 rent: value: 994079 - name: category_id in: query schema: type: integer format: int32 description: Filter transactions to those associated with the specified category ID. Will also match category groups. Set this to 0 to return only un-categorized transactions examples: rent: value: 83 food category group: value: 84 - name: tag_id in: query schema: type: integer format: int32 description: Filter transactions to those that have a tag with the specified Tag ID - name: is_group_parent in: query schema: type: boolean description: Filter by group (returns only transaction groups if `true`) - name: status in: query schema: type: string enum: - reviewed - unreviewed - delete_pending description: "Filter transactions to those with the specified status:
- `reviewed`: Only user reviewed transactions or those that were automatically marked as reviewed due to reviewed recurring_item logic
- `unreviewed`: Only transactions that need to be reviewed
- `delete_pending`: Only transactions that require manual intervention because the plaid account deleted this transaction after it was updated by the user." examples: needs review: value: unreviewed needs deletion: value: delete_pending - name: is_pending in: query schema: type: boolean description: > Filter transactions by pending status. Set to `true` to return only pending transactions, or `false` to return only non-pending transactions. When this parameter is set, it takes precedence over `include_pending`. Note: Pending transactions always have a status of `unreviewed`, so when setting this parameter to `true`, either omit the `status` parameter or set it to `unreviewed`. examples: only pending: value: true exclude pending: value: false - name: include_pending in: query schema: type: boolean default: false description: > By default, pending transactions are excluded from results. Set to `true` to include imported transactions with a pending status in the results. This query param is ignored if the `is_pending` query param is also set. - name: include_metadata in: query schema: type: boolean default: false description: By default, custom and plaid metadata are not included in the response. Set to true if you'd like the returned transactions objects to include any metadata associated with the transactions. - name: include_split_parents in: query schema: type: boolean default: false description: By default, transactions that were split into multiple transactions are not included in the response. Set to true if you'd like the returned transactions objects to include any transactions that were split into multiple transactions. Use with caution as this data is normally not exposed after the split transactions are created. - name: include_group_children in: query schema: type: boolean default: false description: By default, individual transactions that joined into a transaction group are not included in the response. Set to true if you'd like the returned transactions objects to include any transactions that joined into a transaction group. - name: include_children in: query schema: type: boolean default: false description: By default, the `children` property is not included in the response. Set to true if you'd like the children property to be populated with the transactions that make up a transaction group, or, if the `include_split_parents` query param is also set, the transactions that were split from a parent transaction. - name: include_files in: query schema: type: boolean default: false description: By default, the `files` property is not included in the response. Set to true if you'd like the responses to include a list of of objects that describe any files attached to the transactions. - name: limit in: query schema: type: integer minimum: 1 maximum: 2000 default: 1000 description: Sets the maximum number of transactions to return. If more match the filter criteria, the response will include a `has_more` attribute set to `true`. See [Pagination](https://alpha.lunchmoney.dev/v2/pagination) - name: offset in: query schema: type: integer description: Sets the offset for the records returned. This is typically set automatically in the header. See [Pagination](https://alpha.lunchmoney.dev/v2/pagination) responses: "200": description: Returns an array of transactions.

The `has_more` property is set to `true` if more transactions are available. See [Pagination](https://alpha.lunchmoney.dev/v2/pagination) content: application/json: schema: properties: transactions: items: $ref: "#/components/schemas/transactionObject" type: array has_more: type: boolean description: Set to true if more transactions are available error: type: string required: - transactions - has_more examples: default response: summary: Default response value: transactions: - id: 2112150655 date: "2024-07-28" amount: "1250.8400" currency: usd to_base: 1250.84 recurring_id: 994069 payee: Paycheck original_name: DIRECT DEPOSIT PAYROLL category_id: 88 notes: null status: reviewed is_pending: false created_at: "2024-07-28T17:00:06.192Z" updated_at: "2024-07-28T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119806 tag_ids: - 94317 source: plaid external_id: null - id: 2112150655 date: "2024-07-24" amount: "21.9800" currency: usd to_base: 21.98 recurring_id: null payee: Noodle House original_name: NOODLE HOUSE RESTAURANT #5678 category_id: null notes: null status: unreviewed is_pending: false created_at: "2024-07-24T17:00:06.192Z" updated_at: "2024-07-24T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: - 94317 source: plaid external_id: null - id: 2112150653 date: "2024-07-22" amount: "-847.2200" currency: usd to_base: -847.22 recurring_id: null payee: Credit Card Payment original_name: CHASE CREDIT CARD PAYMENT category_id: 82 is_pending: false status: reviewed notes: null created_at: "2024-07-22T17:00:06.192Z" updated_at: "2024-07-22T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119804 tag_ids: [] source: plaid external_id: null - id: 2112150651 date: "2024-07-22" amount: "250.0000" currency: usd to_base: 250 recurring_id: null payee: Fidelity original_name: Fidelity category_id: 82 notes: Transfer from Checking to Fidelity status: reviewed is_pending: false created_at: "2024-07-22T17:00:06.192Z" updated_at: "2024-07-22T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: 119807 plaid_account_id: null tag_ids: [] source: csv external_id: null has_more: false recurring paychecks: summary: recurring paychecks value: transactions: - id: 2112150655 date: "2024-07-28" amount: "1250.8400" currency: usd to_base: 1250.84 recurring_id: 994069 payee: Paycheck original_name: DIRECT DEPOSIT PAYROLL category_id: 88 notes: null status: reviewed is_pending: false created_at: "2024-07-28T17:00:06.192Z" updated_at: "2024-07-28T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119806 tag_ids: - 94317 source: plaid external_id: null - id: 2112150653 date: "2024-07-14" amount: "1250.8400" currency: usd to_base: 1250.84 recurring_id: 994069 payee: Paycheck original_name: DIRECT DEPOSIT PAYROLL category_id: 88 notes: null status: reviewed is_pending: false created_at: "2024-07-14T17:00:06.192Z" updated_at: "2024-07-14T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: true group_parent_id: null manual_account_id: null plaid_account_id: 119806 tag_ids: - 94317 source: plaid external_id: null has_more: false limit 2 - paginated response: summary: Limit 2 paginated response value: transactions: - id: 2112150655 date: "2024-07-28" amount: "1250.8400" currency: usd to_base: 1250.84 recurring_id: 994069 payee: Paycheck original_name: DIRECT DEPOSIT PAYROLL category_id: 88 notes: null status: reviewed is_pending: false created_at: "2024-07-28T17:00:06.192Z" updated_at: "2024-07-28T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119806 tag_ids: - 94317 source: plaid external_id: null - id: 2112150654 date: "2024-07-24" amount: "21.9800" currency: usd to_base: 21.98 recurring_id: null payee: Noodle House original_name: NOODLE HOUSE RESTAURANT #5678 category_id: null notes: null status: unreviewed is_pending: false created_at: "2024-07-24T17:00:06.192Z" updated_at: "2024-07-24T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: - 94317 source: plaid external_id: null has_more: true "400": description: Invalid request parameters content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be integer instancePath: /query/category_id schemaPath: "#/properties/query/properties/category_id/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" post: tags: - transactions (bulk) summary: Insert one or more transactions. description: >- Use this endpoint to add transactions to a budget.

The request body for this endpoint must include a list of transactions with at least one transaction and not more than 500 transactions to insert.

The successful request to this endpoint will return a response body which will include two arrays:
- `transactions`: A list of transactions that were successfully inserted.
- `skipped_duplicates`: A list of transactions that were duplicates of existing transactions and were not inserted. operationId: createNewTransactions requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: transactions: type: array minItems: 1 maxItems: 500 description: List of transactions to insert. items: $ref: "#/components/schemas/insertTransactionObject" apply_rules: type: boolean default: false description: If `true`, any rules associated with the account specified by the `manual_account_id` property for each transaction will be applied. skip_duplicates: type: boolean default: false description: If `true`, the system will flag new transactions that have the same `date`, `payee`, `amount`, and account_id (plaid or manual), as an existing transaction, as a duplicate.

Note that deduplication based on `external_id` will always occur regardless of how this property is set. skip_balance_update: type: boolean default: false description: If `true`, and new transactions include a `manual_account_id`, the balances of these accounts will not be updated, when the transactions are inserted. required: - transactions examples: categorized cash transaction: value: transactions: - date: "2024-12-01" amount: 42.89 payee: Food Town category_id: 315163 status: reviewed bare minimum new transaction: value: transactions: - date: "2024-11-01" amount: 99.99 two new cash transactions: value: transactions: - date: "2024-11-01" amount: 15.00 payee: Lunch with James notes: Cash Transaction category_id: 315163 - date: "2024-11-01" amount: "-9.99" payee: me notes: Interest from Investment Account Cash status: unreviewed with external_id and custom_metadata: value: transactions: - date: "2024-12-01" amount: "19.99" payee: Test Payee 3 manual_account_id: 219807 external_id: A658214 notes: API Test created Transaction custom_metadata: note: API Test Added Custom MetaData testNumber: 42 testBool: false testArray: - 1 - foo - false - 42.42 testObject: foo: bar duplicate external_id: value: transactions: - date: "2024-12-01" amount: "19.99" payee: Test Payee 3 manual_account_id: 219807 external_id: A658214 notes: API Test created Transaction with new external_id custom_metadata: note: API Test Added Custom MetaData testNumber: 42 testBool: false testArray: - 1 - foo - false - 42.42 testObject: foo: bar - date: "2025-06-20" amount: "250.0000" payee: Fidelity manual_account_id: 219807 external_id: "12345" notes: API Test created Transaction with duplicate external_id multiple duplicates: value: skip_duplicates: true transactions: - date: "2025-06-24" amount: "21.9800" payee: "Noodle House" notes: "Duplicate date, payee and amount. Note date may need to be changed in \"Try It\" mode." plaid_account_id: 119805 - date: "2025-04-20" amount: "250.0000" payee: "Fidelity" category_id: 82 notes: "Duplicate external ID" external_id: "12345" manual_account_id: 219807 - date: "2024-12-01" amount: "19.99" payee: "Test Payee 3" notes: "API Test created Transaction" manual_account_id: 219807 external_id: "A658214" responses: "201": description: Created content: application/json: schema: $ref: "#/components/schemas/insertTransactionsResponseObject" examples: categorized cash transaction: value: transactions: - id: 123456789 date: "2024-12-01" amount: "42.89" currency: usd to_base: 42.89 recurring_id: null payee: Food Town category_id: 315163 notes: null status: reviewed is_pending: false created_at: "2024-12-18T04:05:58.072Z" updated_at: "2024-12-18T04:05:58.072Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [] source: api external_id: null custom_metadata: null plaid_metadata: null skipped_duplicates: [] bare minimum request: value: transactions: - id: 123456789 date: "2024-11-01" amount: "99.99" currency: usd to_base: 99.99 recurring_id: null payee: '[No Payee]' category_id: null notes: null status: unreviewed is_pending: false created_at: "2024-11-20T16:09:11.544Z" updated_at: "2024-11-20T16:09:11.544Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [] source: api external_id: null custom_metadata: null plaid_metadata: null skipped_duplicates: [] two new cash transactions: value: transactions: - id: 123456789 date: "2024-11-01" amount: "15.00" currency: usd to_base: 15 recurring_id: null payee: Lunch with James category_id: null notes: Cash Transaction status: unreviewed is_pending: false created_at: "2024-11-20T16:10:23.395Z" updated_at: "2024-11-20T16:10:23.395Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [] source: api external_id: null custom_metadata: null plaid_metadata: null - id: 123456790 date: "2024-11-01" amount: "-9.99" currency: usd to_base: -9.99 recurring_id: null payee: me category_id: null notes: Interest from Investment Account Cash status: unreviewed is_pending: false created_at: "2024-11-20T16:10:23.395Z" updated_at: "2024-11-20T16:10:23.395Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [] source: api external_id: null custom_metadata: null plaid_metadata: null skipped_duplicates: [] with external_id and custom_metadata: value: transactions: - id: 123456789 date: "2024-12-01" amount: "19.99" currency: usd to_base: 19.99 recurring_id: null payee: Test Payee 3 category_id: null notes: API Test created Transaction status: unreviewed is_pending: false created_at: "2024-11-20T16:15:19.475Z" updated_at: "2024-11-20T16:15:19.475Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: 219807 plaid_account_id: null tag_ids: [] source: api external_id: A658214 custom_metadata: note: API Test Added Custom MetaData testNumber: 42 testBool: false testArray: - 1 - foo - false - 42.42 testObject: foo: bar skipped_duplicates: [] duplicate external id skipped: value: transactions: - id: 123456789 date: "2024-12-01" amount: "19.99" currency: usd to_base: 19.99 recurring_id: null payee: Test Payee 3 category_id: null notes: API Test created Transaction with new external_id status: unreviewed is_pending: false created_at: "2025-07-18T14:15:23.159Z" updated_at: "2025-07-18T14:15:23.159Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: 219807 plaid_account_id: null tag_ids: [] source: api external_id: A658214 custom_metadata: note: API Test Added Custom MetaData testNumber: 42 testBool: false testArray: - 1 - foo - false - 42.42 testObject: foo: bar skipped_duplicates: - reason: duplicate_external_id request_transactions_index: 1 existing_transaction_id: 2112150651 request_transaction: date: "2025-06-20" amount: "250.0000" payee: Fidelity manual_account_id: 219807 external_id: "12345" notes: API Test created Transaction with duplicate external_id multiple skipped duplicates: value: transactions: - id: 123456789 date: "2024-12-01" amount: "19.99" currency: usd to_base: 19.99 recurring_id: null payee: Test Payee 3 category_id: null notes: API Test created Transaction status: unreviewed is_pending: false created_at: "2025-07-18T14:05:29.253Z" updated_at: "2025-07-18T14:05:29.253Z" split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: 219807 plaid_account_id: null tag_ids: [] source: api external_id: A658214 skipped_duplicates: - reason: duplicate_payee_amount_date request_transactions_index: 0 existing_transaction_id: 2112150654 request_transaction: date: "2025-06-24" amount: "21.9800" payee: Noodle House notes: Duplicate date, payee and amount. Note date may need to be changed in "Try It" mode. plaid_account_id: 119805 - reason: duplicate_external_id request_transactions_index: 1 existing_transaction_id: 2112150651 request_transaction: date: "2025-04-20" amount: "250.0000" payee: Fidelity category_id: 82 notes: Duplicate external ID external_id: "12345" manual_account_id: 219807 "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: invalid ids in new transactions: value: message: Request Validation Failure errors: - errMsg: "transactions[0] manual account ID does not exist: 9999999" transaction_index: 0 error: Invalid Manual Account ID invalid_property: manual_account_id manual_account_id: 9999999 - errMsg: "transactions[1] manual account ID does not exist: 9999999" transaction_index: 1 error: Invalid Manual Account ID invalid_property: manual_account_id manual_account_id: 9999999 - errMsg: "transactions[2] recurring ID does not exist: 88888888" transaction_index: 2 error: Invalid Recurring ID invalid_property: recurring_id recurring_id: 88888888 duplicate external_ids within request: value: message: Request Validation Failure errors: - errMsg: Duplicate External IDs found in the request body error: Duplicate External ID transaction_property: external_id external_id: "12345" transactions_indices: - 0 - 1 - errMsg: Duplicate External IDs found in the request body error: Duplicate External ID transaction_property: external_id external_id: "54321" transactions_indices: - 2 - 3 "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" put: tags: - transactions (bulk) summary: Update multiple transactions description: >- Modifies the properties of multiple existing transactions in a single request.

You may submit complete transaction objects from the response returned by a `GET /transactions` in the request body for each transaction, however only certain properties can be updated using this API. The following system set properties are accepted in the request body, but their values will be ignored: `id`, `to_base`, `is_pending`, `created_at`, `updated_at`, `source`, and `plaid_metadata`.

Transactions that have been previously split or grouped may not be modified by this endpoint. Therefore the `is_split_parent`, `split_parent_id`, `is_group_parent`, `group_parent_id`, and `children` properties are also ignored when provided in the request body.

Each transaction in the array **must** include an `id` property to identify which transaction to update, along with at least one other property to be updated. For example, a transaction object that contains only an `id` and `category_id` property is valid.

The request can include between 1 and 500 transactions to update in a single call. operationId: updateTransactions requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: transactions: type: array minItems: 1 maxItems: 500 description: List of transactions to update. Each transaction must have an `id` property and at least one other property to update. items: allOf: - type: object required: [id] properties: id: type: integer format: int64 description: The ID of the transaction to update - $ref: "#/components/schemas/updateTransactionObject" required: - transactions examples: categorize multiple transactions: value: transactions: - id: 2112150654 category_id: 315162 notes: "Treat restaurants the same as groceries" - id: 2112150649 category_id: 315162 notes: "Treat restaurants the same as groceries" - id: 2112140372 category_id: 315162 notes: "Treat restaurants the same as groceries" update with full objects: value: transactions: - id: 2112150688 date: "2025-07-17" amount: "4.1300" currency: "usd" to_base: 4.13 recurring_id: 994081 payee: "Holey Donuts" category_id: 315164 notes: "Coffee - cash" status: "reviewed" is_pending: false created_at: "2025-07-17T17:00:06.192Z" updated_at: "2025-07-17T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: - 94317 source: "csv" external_id: null - id: 2112150649 category_id: 315162 notes: "Treat restaurants the same as groceries" update with errors: value: transactions: - id: 9999999 notes: "Invalid transaction ID" - id: 2112150688 category_id: 999999999 manual_account_id: 999999999 notes: "Invalid category and manual account IDs" - id: 2112150649 plaid_account_id: 999999999 tag_ids: [888888888, 999999999] notes: "Invalid tag and plaid account IDs" - id: 2112150649 additional_tag_ids: [888888888, 999999999] notes: "Invalid additional_tag_ids" - id: 2212150657 notes: "Transaction belongs to locked plaid account" payee: "New Payee" amount: "100.0000" currency: "jpy" responses: "200": description: Transactions successfully updated content: application/json: schema: properties: transactions: items: $ref: "#/components/schemas/transactionObject" type: array required: - transactions examples: bulk update transactions: value: transactions: - id: 2112150654 date: "2025-06-24" amount: "21.9800" currency: "usd" to_base: 21.98 recurring_id: null payee: "Noodle House" category_id: 315162 notes: "Treat restaurants the same as groceries" status: "reviewed" is_pending: false created_at: "2025-06-24T17:00:06.192Z" updated_at: "2025-06-24T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: - 94317 source: "plaid" external_id: null custom_metadata: null - id: 2112150649 date: "2025-06-18" amount: "4.1300" currency: "usd" to_base: 4.13 recurring_id: 994081 payee: "Holey Donuts" category_id: 315162 notes: "Treat restaurants the same as groceries" status: "reviewed" is_pending: false created_at: "2025-06-18T17:00:06.192Z" updated_at: "2025-06-18T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: - 94317 source: "csv" external_id: null custom_metadata: null - id: 2112140372 date: "2025-06-12" amount: "50.00" currency: "usd" to_base: 50 recurring_id: null payee: "Starbucks" category_id: 315162 notes: "Treat restaurants the same as groceries" status: "reviewed" is_pending: false created_at: "2025-06-12T17:00:06.192Z" updated_at: "2025-06-12T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119807 tag_ids: [] source: "plaid" external_id: null custom_metadata: null update with full objects: value: transactions: - id: 2112150688 date: "2025-07-17" amount: "4.1300" currency: "usd" to_base: 4.13 recurring_id: 994081 payee: "Holey Donuts" category_id: 315164 notes: "Coffee - cash" status: "reviewed" is_pending: false created_at: "2025-07-17T17:00:06.192Z" updated_at: "2025-07-17T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: - 94317 source: "csv" external_id: null custom_metadata: null - id: 2112150649 date: "2025-06-18" amount: "4.1300" currency: "usd" to_base: 4.13 recurring_id: 994081 payee: "Holey Donuts" category_id: 315162 notes: "Treat restaurants the same as groceries" status: "reviewed" is_pending: false created_at: "2025-06-18T17:00:06.192Z" updated_at: "2025-06-18T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: - 94317 source: "csv" external_id: null custom_metadata: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: invalid ids in id list: value: message: Request Validation Failure errors: - errMsg: "transactions[0] manual account ID does not exist: 999999999" transaction_index: 0 error: Invalid Manual Account ID invalid_property: manual_account_id manual_account_id: 999999999 - errMsg: "transactions[1] manual account ID does not exist: 999999999" transaction_index: 1 error: Invalid Manual Account ID invalid_property: manual_account_id manual_account_id: 999999999 - errMsg: "transactions[2] recurring ID does not exist: 888888888" transaction_index: 2 error: Invalid Recurring ID invalid_property: recurring_id recurring_id: 888888888 update with errors: value: message: Request Validation Failure errors: - errMsg: "There is no transaction with the id: 9999999" error: Invalid Transaction ID invalid_property: id transaction_id: 9999999 transaction_index: 0 - errMsg: "transactions[1] category ID does not exist: 999999999" transaction_index: 1 error: Invalid Category ID invalid_property: category_id category_id: 999999999 - errMsg: "transactions[1] manual account ID does not exist: 999999999" transaction_index: 1 error: Invalid Manual Account ID invalid_property: manual_account_id manual_account_id: 999999999 - errMsg: "transactions[2] plaid account ID does not exist: 999999999" transaction_index: 2 error: Invalid Plaid Account ID invalid_property: plaid_account_id plaid_account_id: 999999999 - errMsg: "transactions[2] tag_ids[0] ID does not exist: 888888888" transaction_index: 2 error: Invalid Tag ID invalid_property: tag_ids tag_id: 888888888 tag_ids_index: 0 - errMsg: "transactions[2] tag_ids[1] ID does not exist: 999999999" transaction_index: 2 error: Invalid Tag ID invalid_property: tag_ids tag_id: 999999999 tag_ids_index: 1 - errMsg: "transactions[3] additional_tag_ids[0] ID does not exist: 888888888" transaction_index: 3 error: Invalid Tag ID invalid_property: additional_tag_ids tag_id: 888888888 additional_tag_ids_index: 0 - errMsg: "transactions[3] additional_tag_ids[1] ID does not exist: 999999999" transaction_index: 3 error: Invalid Tag ID invalid_property: additional_tag_ids tag_id: 999999999 additional_tag_ids_index: 1 - errMsg: "Cannot change the currency for a transaction that belongs to a Plaid Account which is not configured to allow modifications to transactions. Plaid Account ID: 119804" error: Transaction belongs to a locked Plaid account id: 2212150657 transaction_index: 4 locked_property: currency - errMsg: "Cannot change the amount for a transaction that belongs to a Plaid Account which is not configured to allow modifications to transactions. Plaid Account ID: 119804" error: Transaction belongs to a locked Plaid account id: 2212150657 transaction_index: 4 locked_property: amount duplicate external_ids within request: value: message: Request Validation Failure errors: - errMsg: Duplicate External IDs found in the request body error: Duplicate External ID transaction_property: external_id external_id: "12345" transactions_indices: - 0 - 1 - errMsg: Duplicate External IDs found in the request body error: Duplicate External ID transaction_property: external_id external_id: "54321" transactions_indices: - 2 - 3 invalid ids: value: message: Request Validation Failure errors: - errMsg: "There is no transaction with the id: 1" error: Invalid Transaction ID invalid_property: id transaction_id: 1 transaction_index: 0 - errMsg: "There is no transaction with the id: 2" error: Invalid Transaction ID invalid_property: id transaction_id: 2 transaction_index: 1 "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - transactions (bulk) summary: Bulk delete existing transactions description: >- Deletes the transaction with the IDs specified in the request body.

If any of the specified transactions are a split transaction or a split parent, or if any are a grouped transactions or part of a transaction group, the request will fail with a suggestion on how to unsplit or ungroup the transaction(s) prior to deletion. This will also fail if any of the specified transaction IDs do not exist.

Otherwise, the specified transactions are deleted.

Use with caution. This action is not reversible! operationId: deleteTransactions requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: ids: type: array description: Array of existing Transaction IDs to delete minItems: 1 maxItems: 500 items: type: integer format: int64 required: - ids examples: delete three transactions: value: ids: - 2112150653 - 2112150654 - 2112150655 duplicate ids: value: ids: - 2112150653 - 2112150653 - 2112150654 - 2112150654 invalid ids: value: ids: - 2112150653 - 9999999999 - 2112150654 responses: "204": description: No Content "400": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Invalid Request Body errors: - errMsg: "Duplicate transaction ID found: 2112150653" transaction_id: 2112150653 ids_index: 0 invalid_property: ids - errMsg: "Duplicate transaction ID found: 2112150653" transaction_id: 2112150653 ids_index: 1 invalid_property: ids - errMsg: "Duplicate transaction ID found: 2112150654" transaction_id: 2112150654 ids_index: 2 invalid_property: ids - errMsg: "Duplicate transaction ID found: 2112150654" transaction_id: 2112150654 ids_index: 3 invalid_property: ids "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: "There is no transaction with the id: 8888888888" ids_index: 0 id: 8888888888 - errMsg: "There is no transaction with the id: 9999999999" ids_index: 1 id: 9999999999 "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions/{id}: get: tags: - transactions summary: Get a single transaction description: > Retrieves the details of a specific transaction by its ID, including the following properties which are not returned by default in the response to a `GET /transactions` request:
- `plaid_metadata` will either be `null` or contain the metadata for transactions associated with an account that is synced via plaid. - `custom_metadata` will either be `null` or contain any custom_metadata added to transactions that were inserted or updated via the API. - `files` will be a list of objects that describe any attachments to the transaction. If `is_group_parent` is true in the returned transaction, the object will also include the `children` property which will contain a list of the original transactions that make up the transaction group.
If `is_split_parent` is true in the returned transaction, the object will also include the `children` property which will contain a list of the split transactions. operationId: getTransactionById parameters: - name: id in: path description: ID of the transaction to retrieve required: true schema: type: integer format: int64 examples: basic transaction: summary: Basic transaction by id request value: 2112150654 transaction with plaid metadata: summary: Transaction with plaid metadata value: 2112150655 transaction group: summary: Transaction group value: 2112140959 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "200": description: Transaction Object with the requested transaction. content: application/json: schema: $ref: "#/components/schemas/transactionObject" examples: basic transaction: value: id: 2112150654 date: "2024-07-24" amount: "21.9800" currency: usd to_base: 21.98 recurring_id: null payee: Noodle House original_name: NOODLE HOUSE RESTAURANT #5678 category_id: null notes: null status: unreviewed is_pending: false created_at: "2024-07-24T17:00:06.192Z" updated_at: "2024-07-24T17:00:06.192Z" split_parent_id: null children: [] is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: [] source: csv external_id: null transaction with plaid metadata: value: id: 2112150655 date: "2025-05-28" amount: "1250.8400" currency: usd to_base: 1250.84 recurring_id: 994069 payee: Paycheck original_name: DIRECT DEPOSIT PAYROLL category_id: null notes: null status: pending is_pending: true created_at: "2025-05-28T17:00:06.192Z" updated_at: "2025-05-28T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119806 tag_ids: - 94317 source: plaid external_id: null custom_metadata: null plaid_metadata: note: This is an artificially constructed example of metadata account_id: 9DYYMLBoaxIqRkAOKaVDuaPZrmE5qJhVxyZyv account_owner: null amount: "1250.8400" authorized_datetime: "2025-05-28T17:00:06.192Z" counterparties: - confidence_level: LOW entity_id: null logo_url: null name: Employers Inc. transaction group: value: id: 2112140959 date: "2025-05-17" amount: "25.6900" currency: usd to_base: 25.69 recurring_id: null payee: Valero original_name: Valero category_id: 315174 notes: Net Gas for roadtrip status: reviewed is_pending: false created_at: "2025-05-17T17:00:06.192Z" updated_at: "2025-05-17T17:00:06.733Z" split_parent_id: null is_group_parent: true group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: - 94318 - 94317 source: csv external_id: null children: - id: 2112150647 date: "2025-05-17" amount: "25.000" currency: usd to_base: 25 recurring_id: null payee: Me original_name: Me category_id: 315174 notes: Gas repay from Tim for roadtrip status: reviewed is_pending: false created_at: "2025-05-17T17:00:06.192Z" updated_at: "2025-05-17T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 2112140959 manual_account_id: null plaid_account_id: null tag_ids: - 94318 - 94317 source: csv external_id: null - id: 2112150859 date: "2025-05-16" amount: "25.000" currency: usd to_base: 25 recurring_id: null payee: Me category_id: 315174 notes: Gas repay from Liz for roadtrip status: reviewed is_pending: false created_at: "2025-05-16T17:00:06.192Z" updated_at: "2025-05-16T17:00:06.192Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 2112140959 manual_account_id: null plaid_account_id: null tag_ids: - 94318 - 94317 source: csv external_id: null - id: 2112150659 date: "2025-05-15" amount: "75.6900" currency: usd to_base: 75.69 recurring_id: null payee: Valero category_id: 315174 notes: Gas on roadtrip with Tim and Liz status: reviewed is_pending: false created_at: "2025-05-15T17:00:06.192Z" updated_at: "2025-05-15T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 2112140959 manual_account_id: null plaid_account_id: 119805 tag_ids: - 94318 - 94317 source: plaid external_id: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be integer instancePath: /path/id schemaPath: "#/properties/path/properties/id/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no transaction with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" put: tags: - transactions summary: Update an existing transaction description: >- Modifies the properties of an existing transaction.

You may submit the response from a `GET /transactions/{id}` as the request body, however only certain properties can be updated using this API. The following system set properties are accepted in the request body but their values will be ignored: `id`, `to_base`, `is_pending`, `created_at`, `updated_at`, `source`, and `plaid_metadata`.

Transactions that have been previously split or grouped may not be modified by this endpoint. Therefore the `is_split_parent`, `split_parent_id`, `is_group_parent`, `group_parent_id`, and `children` properties are also ignored when provided in the request body.

It is also possible to provide only the properties to be updated in the request body, as long as the request includes at least one of the properties that is not listed above. For example a request body that contains only an `category_id` attribute is valid. operationId: updateTransaction parameters: - name: id in: path description: ID of the transaction to update required: true schema: type: integer format: int64 examples: basic transaction: summary: Basic transaction by id request value: 2112140361 id not found: summary: Example of an id that doesn't exist value: 9999999999999 - name: update_balance in: query description: Set this to `false` to skip updating the transaction's associated account balance. Default behavior is to update balances. required: false schema: type: boolean requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/updateTransactionObject" examples: update categories simple: value: category_id: 315162 update transaction category with previous get response: value: id: 2112140361 date: "2024-12-09" amount: "300.00" currency: usd to_base: 300 recurring_id: null payee: Best Buy category_id: 315162 notes: Electronics status: reviewed is_pending: false created_at: "2024-12-09T17:00:06.192Z" updated_at: "2024-12-09T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119810 tag_ids: [] source: plaid external_id: null responses: "201": description: Transaction successfully updated content: application/json: schema: $ref: "#/components/schemas/transactionObject" examples: transaction with updated category: value: id: 2112140361 date: "2024-12-09" amount: "300.00" currency: usd to_base: 300 recurring_id: null payee: Best Buy category_id: 315162 notes: Electronics status: reviewed is_pending: false created_at: "2024-12-09T17:00:06.192Z" updated_at: "2024-12-09T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119810 tag_ids: [] source: plaid external_id: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be integer instancePath: /path/id schemaPath: "#/properties/path/properties/id/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no transaction with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - transactions summary: Delete a transaction description: >- Deletes the transaction with the ID specified on the path.

If the specified transaction is a split transaction or a split parent, or if it is a grouped transactions or part of a transaction group, the request will fail with a suggestion on how to unsplit or ungroup the transaction(s) prior to deletion. Otherwise, the specified transaction is deleted.

Use with caution. This action is not reversible! operationId: deleteTransactionById parameters: - in: path name: id description: ID of the transaction to delete required: true schema: type: integer format: int64 examples: delete transaction: summary: Simple transaction delete value: 2112140361 delete split transaction: value: 2112140459 delete transaction group: value: 2112140959 id not found: summary: Example of an id that doesn't exist value: 543210 responses: "204": description: No Content "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no transaction with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions/group: post: tags: - transactions (group) summary: Create a transaction group description: > Specify a set of existing transaction IDs to group together as a single grouped transaction. The new transaction will have an amount equal to the sum of the grouped transaction amounts. If the grouped transactions have different currencies, the new group transaction will be set in the user's default currency.

After a transaction has been grouped, the original transactions are no longer shown on the transactions page or returned by a `GET /transactions` request. The newly created grouped transaction is returned instead. To see the details of the original transactions that were used to create a transaction group, use the `GET /transactions/{id}` endpoint and pass the ID of the grouped transaction. The grouped transactions will be included in the `children` property of the transaction returned in the response operationId: groupTransactions requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: ids: type: array minItems: 2 maxItems: 500 description: List of existing transaction IDs to group. Split and recurring transactions may not be grouped. Transactions that are already grouped must be ungrouped before being regrouped. items: type: integer format: int64 date: type: string format: date description: Date for the new grouped transaction in ISO 8601 format. payee: type: string description: | The payee for the new grouped transaction. minLength: 0 maxLength: 140 category_id: type: integer format: int64 nullable: true description: The ID of an existing category to assign to the grouped transaction. If not set and all the grouped transactions have the same category, the grouped transaction will inherit the category, otherwise the new transaction will have no category. notes: type: string nullable: true description: | Notes for the grouped transaction. status: type: string description: If set must be either `reviewed` or `unreviewed`. If not set, defaults to `reviewed`. enum: - reviewed - unreviewed tag_ids: type: array description: A list of IDs for the tags associated with the grouped transaction. Each ID must match an existing tag associated with the user's account. If not set, no tags will be associated with the created transaction. items: type: integer format: int64 required: - ids - date - payee examples: group inherits category: value: ids: - 2112140365 - 2112140361 payee: Home Entertainment Transactions date: "2024-12-10" responses: "201": description: The new grouped parent transaction with populated children attribute content: application/json: schema: $ref: "#/components/schemas/transactionObject" examples: group inherits category: value: id: 123456789 date: "2024-12-10" amount: "375.0000" currency: usd to_base: 375 recurring_id: null payee: Home Entertainment Transactions category_id: 315628 notes: null status: reviewed is_pending: false created_at: "2024-12-18T14:45:03.366Z" updated_at: "2024-12-18T14:45:03.366Z" split_parent_id: null is_group_parent: true group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [] source: api external_id: null custom_metadata: null children: - id: 2112140365 date: "2024-11-10" amount: "75.00" currency: usd to_base: 75 recurring_id: null payee: Target category_id: 315628 notes: Household items status: reviewed is_pending: false created_at: "2024-11-10T17:00:06.192Z" updated_at: "2024-11-10T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 123456789 manual_account_id: null plaid_account_id: 119809 tag_ids: [] source: plaid external_id: null - id: 2112140361 date: "2024-11-09" amount: "300.00" currency: usd to_base: 300 recurring_id: null payee: Best Buy category_id: 315628 notes: Electronics status: reviewed is_pending: false created_at: "2024-11-09T17:00:06.192Z" updated_at: "2024-11-09T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 123456789 manual_account_id: null plaid_account_id: 119810 tag_ids: [] source: plaid external_id: null group with all reviewed children: summary: When all children have status 'reviewed', the grouped transaction also has status 'reviewed' value: id: 123456789 date: "2024-12-25" amount: "0.0000" currency: usd to_base: 0 recurring_id: null payee: Grouped Transaction Payee category_id: 82 notes: API Created Test Transaction Group status: reviewed is_pending: false created_at: "2025-11-13T21:39:27.609Z" updated_at: "2025-11-13T21:39:27.609Z" split_parent_id: null is_group_parent: true group_parent_id: null manual_account_id: null plaid_account_id: null tag_ids: [94318] source: api external_id: null custom_metadata: null children: - id: 2112150653 date: "2025-10-22" amount: "-847.2200" currency: usd to_base: -847.22 recurring_id: null payee: Credit Card Payment category_id: 82 notes: null status: reviewed is_pending: false created_at: "2025-10-22T17:00:06.192Z" updated_at: "2025-10-22T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 123456789 manual_account_id: null plaid_account_id: 119804 tag_ids: [] source: plaid external_id: null custom_metadata: null - id: 2112150652 date: "2025-10-21" amount: "847.2200" currency: usd to_base: 847.22 recurring_id: null payee: Transfer to Credit Card category_id: 82 notes: "Lenny's Amex Bill" status: reviewed is_pending: false created_at: "2025-10-21T17:00:06.192Z" updated_at: "2025-10-21T17:00:06.733Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: 123456789 manual_account_id: null plaid_account_id: 119806 tag_ids: [] source: plaid external_id: null custom_metadata: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: missing ids: value: message: Request Validation Failure errors: - errMsg: "There is no transaction with the id: 89999999" ids_index: 0 id: 89999999 - errMsg: "There is no transaction with the id: 99999999" ids_index: 1 id: 99999999 duplicate ids: value: message: Request Validation Failure errors: - errMsg: "Duplicate transaction ID found: 2112150653" ids_index: 1 transaction_id: 2112150653 invalid_property: ids split transactions: value: message: Request Validation Failure errors: - errMsg: "Transaction with id 2112150653 is a split transaction and cannot be added to a transaction group." ids_index: 0 id: 2112150653 - errMsg: "Transaction with id 2112150654 is a split transaction and cannot be added to a transaction group." ids_index: 1 id: 2112150654 grouped transactions: value: message: Request Validation Failure errors: - errMsg: "Transaction with id 2112140959 is a transaction group and cannot be added to another transaction group." ids_index: 0 id: 2112140959 - errMsg: "Transaction with id 2112150647 is in a transaction group already and cannot be added to another transaction group." ids_index: 1 id: 2112150647 group_parent_id: 2112140959 recurring transactions: value: message: Request Validation Failure errors: - errMsg: "Transaction 2112150655 is a recurring transaction and cannot be added to a transaction group." ids_index: 0 id: 2112150655 "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions/group/{id}: delete: tags: - transactions (group) summary: Delete a transaction group description: >- Deletes the transaction group with the ID specified on the path.
The transactions within the group are not removed and will subsequently be treated as "normal" ungrouped transactions. operationId: ungroupTransactions parameters: - in: path name: id description: ID of the transaction group to delete required: true schema: type: integer format: int64 examples: delete transaction group: summary: Simple transaction group delete value: 2112140959 delete non group transaction: summary: ID is not a transaction group value: 2112150649 id not found: summary: Example of an id that doesn't exist value: 543210 responses: "204": description: No Content "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no transaction with the id: 543210" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions/split/{id}: post: tags: - transactions (split) summary: Split a transaction description: >- Splits an existing transaction into a set of smaller child transactions.

After a transaction has been split, the original transaction is no longer shown on the transactions page or returned by a `GET /transactions` request. The newly created child transactions are returned instead. To see the details of the original parent transaction after it has been split, use the `GET /transactions/{id}` endpoint and pass the value of the `split_parent_id` of one of the children. operationId: splitTransaction parameters: - name: id in: path description: ID of the transaction to spit required: true schema: type: integer format: int64 examples: spit transaction: summary: Basic transaction by id request value: 2112150650 already split transaction: summary: Attempt to split a transaction that has already been split value: 2112140459 id not found: summary: Example of an id that doesn't exist value: 9999999999999 requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: child_transactions: type: array minItems: 2 maxItems: 500 description: List of child transactions to create. The sum of the `amounts` must match the split transaction amount. items: $ref: "#/components/schemas/splitTransactionObject" required: - child_transactions examples: split 88.45 Transaction: value: child_transactions: - amount: 44.23 payee: Food Town - Lenny - amount: 44.22 payee: Food Town - Penny invalid math on 88.45 Transaction: value: child_transactions: - amount: 1.5 payee: Food Town - Lenny - amount: 1.5 payee: Food Town - Penny responses: "201": description: The new split parent transaction with populated children attribute content: application/json: schema: $ref: "#/components/schemas/transactionObject" examples: split 88.45 Transaction: value: id: 2112150650 date: "2024-10-19" amount: "88.4500" currency: usd to_base: 88.45 recurring_id: null payee: Food Town category_id: 315162 notes: null status: reviewed is_pending: false created_at: "2024-10-19T17:00:06.192Z" updated_at: "2024-11-30T22:25:53.232Z" split_parent_id: null is_split_parent: true is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: [] source: plaid external_id: null children: - id: 2112150750 date: "2024-10-19" amount: "44.2300" currency: usd to_base: 44.23 recurring_id: null payee: Food Town - Lenny category_id: 315162 notes: null status: reviewed is_pending: false created_at: "2024-11-30T22:25:53.232Z" updated_at: "2024-11-30T22:25:53.232Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: [] source: plaid external_id: null - id: 2112150751 date: "2024-10-19" amount: "44.2200" currency: usd to_base: 44.22 recurring_id: null payee: Food Town - Penny category_id: 315162 notes: null status: reviewed is_pending: false created_at: "2024-11-30T22:25:53.232Z" updated_at: "2024-11-30T22:25:53.232Z" is_split_parent: false split_parent_id: null is_group_parent: false group_parent_id: null manual_account_id: null plaid_account_id: 119805 tag_ids: [] source: plaid external_id: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: bad math: value: message: Request Validation Failure errors: - errMsg: Sum of split transactions do not add up to the original transaction amount. split recurring: value: message: Request Validation Failure errors: - errMsg: You cannot split a recurring transaction. id: 2112150655 split group: value: message: Request Validation Failure errors: - errMsg: You cannot split a group transaction. Ungroup it before splitting. split split: value: message: Request Validation Failure errors: - errMsg: You cannot split an already split transaction. Unsplit it before splitting again. missing amount in child transaction: value: message: Invalid Request Body errors: - errMsg: "child_transactions[0] is missing required property 'amount' in request body." child_transactions_index: 0 error: Missing required property invalid_property: amount invalid category in child transaction: value: message: Request Validation Failure errors: - errMsg: "child_transactions[0] category ID does not exist: 899999999" child_transactions_index: 0 error: Invalid category ID invalid_property: category_id category_id: 899999999 category group in child transaction: value: message: Request Validation Failure errors: - errMsg: "child_transactions[0] category ID is a category group and cannot be assigned to a transaction: 86" child_transactions_index: 0 error: Invalid category ID invalid_property: category_id category_id: 86 category_group_name: Food "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - transactions (split) summary: Unsplit a previously split transactions description: >- Deletes the split children of a previously split transactions and restores the parent transactions to the normal unsplit state.

Use the value of the `split_parent_id`property of a split transaction to specify the parent ID. operationId: unsplitTransaction parameters: - in: path name: id description: ID of the previously split transaction to delete. required: true schema: type: integer format: int64 examples: unsplit a transaction: value: 2112140459 invalid parent id: value: 2112140361 id not found: value: 543210 responses: "204": description: No Content "400": description: Invalid request parameters content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no transaction with the id: 2112140458" id: 2112140458 "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /transactions/{transaction_id}/attachments: post: tags: - transactions (files) summary: Attach a file to a transaction operationId: attachFileToTransaction description: >- Attaches a file to a transaction. The file must be less than 10MB in size.

The file will be attached to the transaction and can be downloaded from the link returned by a `GET /transactions/attachments/{file_id}` request. parameters: - name: transaction_id in: path required: true schema: type: integer format: int64 description: The ID of the transaction to attach the file to examples: attach file to transaction: summary: Basic transaction by id request value: 2112150655 id not found: summary: Example of an id that doesn't exist value: 9999999999999 requestBody: required: true content: multipart/form-data: schema: type: object required: - file properties: file: type: string format: binary description: | The file to attach via multipart form encoding. File size may not exceed 10MB. notes: type: string description: Optional notes about the file example: file: ./test-attachment.png notes: "Test file attachment" responses: "201": description: File attached successfully content: application/json: schema: $ref: "#/components/schemas/transactionAttachmentObject" example: id: 1234567890 uploaded_by: 1 name: "receipt.png" type: "image/png" size: 4330 notes: null source: "api" created_at: "2025-06-11T22:33:20.294Z" "400": description: Invalid request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" examples: invalidFileType: value: message: "Invalid Request Body" errors: - errMsg: "File type application/zip not allowed. Allowed types are: image/jpeg, image/png, application/pdf, image/heic, image/heif" fileTooLarge: value: message: "Invalid Request Body" errors: - errMsg: "File size exceeds maximum allowed size of 10MB" invalidFileTypeString: value: message: "Invalid Request Body" errors: - errMsg: "Invalid value for property 'file'. Expected 'object', received 'string'" error: Invalid type invalid_property: file "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Transaction not found /transactions/attachments/{file_id}: get: summary: Get a url to download a file attachment description: Returns a signed url that can be used to download the file attachment. operationId: getTransactionAttachmentUrl tags: - transactions (files) parameters: - name: file_id in: path required: true schema: type: integer format: int32 description: The ID of the file attachment to download examples: existing file attachment id: summary: Basic file attachment by id request value: 1234567890 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "200": description: Successfully retrieved the file attachment content: application/json: schema: properties: url: type: string description: The signed url to download the file attachment expires_at: type: string format: date-time description: The date and time the signed url will expire required: - url - expires_at example: url: "https://files.lunchmoney.app/66938-41ebb56a066bf09898de.png?X-Header1=X-Value1&X-Header2=Test-Do-Not-Use" expires_at: "2025-07-14T12:00:00Z" "401": $ref: "#/components/responses/unauthorizedToken" "404": description: File attachment not found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: File attachment 1234567890 not found delete: summary: Delete a file attachment operationId: deleteTransactionAttachment description: >- Deletes a file attachment from a transaction. tags: - transactions (files) parameters: - name: file_id in: path required: true schema: type: integer format: int32 description: The ID of the file attachment to delete examples: existing file attachment id: summary: Basic file attachment by id request value: 1234567890 id not found: summary: Example of an id that doesn't exist value: 9999999999999 responses: "204": description: File attachment successfully deleted "401": $ref: "#/components/responses/unauthorizedToken" "404": description: File attachment not found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: File attachment 1234567890 not found /tags: get: tags: - tags summary: Get All Tags description: Retrieve a list of all tags associated with the user's account. operationId: getAllTags responses: "200": description: A list of tags content: application/json: schema: type: object properties: tags: type: array items: $ref: "#/components/schemas/tagObject" example: tags: - id: 94317 name: Penny's description: For transactions not related to Lenny updated_at: "2025-02-28T09:49:03.238Z" created_at: "2025-01-28T09:49:03.238Z" text_color: "333" background_color: "FFE7D4" archived: false archived_at: null - id: 94318 name: Road Trip description: "" updated_at: "2025-02-28T09:50:03.238Z" created_at: "2025-01-28T09:50:03.238Z" text_color: "333" background_color: "CFF4F3" archived: false archived_at: null - id: 94319 name: Date Night description: "" updated_at: "2025-02-28T09:59:03.238Z" created_at: "2025-01-28T10:02:03.238Z" text_color: "333" background_color: "D7F5CC" archived: false archived_at: null "400": description: Invalid request parameters content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be equal to one of the allowed values instancePath: /query/format schemaPath: "#/properties/query/properties/format/enum" keyword: enum params: allowedValues: - flattened - nested "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" post: tags: - tags summary: Create a new tag description: Creates a new tag with the given name operationId: createTag requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/createTagRequestObject" examples: name only: value: name: API Created Tag with no description with description: value: name: API Created Tag description: Description of tag created via API responses: "201": description: Tag Object with the successfully created tag content: application/json: schema: $ref: "#/components/schemas/tagObject" examples: name only: value: id: 94350 name: API Created Tag with no description description: null created_at: "2024-07-28T01:01:38.716Z" updated_at: "2024-07-28T01:01:38.716Z" text_color: null background_color: null archived: false archived_at: null with description: value: id: 94351 name: API Created Tag description: Description of tag created via API text_color: null background_color: null created_at: "2024-07-28T01:01:38.716Z" updated_at: "2024-07-28T01:01:38.716Z" archived: false archived_at: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Invalid Request Body errors: - errMsg: Tag with name 'New Tag' already exists "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /tags/{id}: get: tags: - tags summary: Get a single tag description: Retrieve the details of a specific tag with the specified ID. operationId: getTagById parameters: - name: id in: path description: ID of the tag to retrieve required: true schema: type: integer format: int32 examples: tag: summary: Example of a tags's id value: 94319 not found: summary: Example of a tag id that does not exist value: 543210 responses: "200": description: Tag Object with the requested Tag ID content: application/json: schema: $ref: "#/components/schemas/tagObject" example: id: 94319 name: Date Night description: "" updated_at: "2025-02-28T09:59:03.238Z" created_at: "2025-01-28T10:02:03.238Z" text_color: null background_color: null archived: false archived_at: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be a valid integer instancePath: /query/ids/0 schemaPath: "#/properties/query/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: There is no tag with the id:'543210' "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" put: tags: - tags summary: Update an existing tag description: >- Updates an existing tag.

You may submit the response from a `GET /tags/{id}` as the request body, however only certain properties can be updated using this API. The following system set properties are accepted in the request body but their values will be ignored: `id`, `updated_at`, and `created_at`.

It is also possible to provide only the properties to be updated in the request body, as long as the request includes at least one of the properties that is not listed above. For example a request body that contains only a `name` attribute is valid. operationId: updateTag parameters: - name: id in: path description: ID of the tag to update required: true schema: type: integer format: int32 examples: tag: summary: Example of a tags's id value: 94319 not found: summary: Example of a tag id that does not exist value: 543210 requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/updateTagRequestObject" examples: Update tag name: value: name: Updated Tag Name Update with full object: value: id: 94319 name: Updated Tag Name description: API Updated Description text_color: "333" background_color: "FFE7D4" updated_at: "2025-02-28T09:59:03.238Z" created_at: "2025-01-28T10:02:03.238Z" archived: false archived_at: null responses: "200": description: Category or Category Group updated successfully content: application/json: schema: $ref: "#/components/schemas/tagObject" examples: new name: value: id: 94319 name: Updated Tag Name description: null text_color: null background_color: null updated_at: "2025-02-28T09:59:03.238Z" created_at: "2025-01-28T10:02:03.238Z" archived: false archived_at: null new name and description: value: id: 94319 name: Updated Tag Name description: API Updated Description text_color: "333" background_color: "FFE7D4" updated_at: "2025-02-28T09:59:03.238Z" created_at: "2025-01-28T10:02:03.238Z" archived: false archived_at: null "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: "A request to update a tag must include at least one of the following properties: name, description, archived." "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no tag with the id: 543210." "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - tags summary: Delete a tag description: >- Deletes the tag with the ID specified on the path.
If transaction or rules exist with the tag a dependents object is returned and the tag is not deleted. This behavior can be overridden by setting the `force` param to `true`. operationId: deleteTag parameters: - in: path name: id description: ID of the tag to delete required: true schema: type: integer format: int32 examples: delete tag: summary: Simple tag delete value: 94319 delete tag with dependents: summary: Tag request with dependents value: 94317 id not found: summary: Example of an id that doesn't exist value: 543210 - in: query name: force description: Set to true to force deletion even if there are dependencies required: false schema: type: boolean default: false responses: "204": description: No Content "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: "There is no tag with the id: 543210." "422": description: Unprocessable Entity content: application/json: schema: $ref: "#/components/schemas/deleteTagResponseWithDependencies" example: tag_name: Tag to be Deleted dependents: rules: 1 transactions: 10 "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /recurring_items: get: tags: - recurring_items summary: Get all recurring items description: Get info about the recurring items for a specified time frame operationId: getAllRecurring parameters: - name: start_date in: query schema: type: string format: date description: Denotes the beginning of the range used to populate the `matching` object in the recurring items. If omitted, the current month will be used as the range.
Required if end_date exists. - name: end_date in: query schema: type: string format: date description: "Denotes the end of the range used to populate the `matching` object in the recurring items. Required if start_date exists. " - name: include_suggested in: query schema: type: boolean description: When set to true will include recurring items that have been suggested by the system, but have not been reviewed and are not actively updating transactions. responses: "200": description: A list of recurring items content: application/json: schema: type: object properties: recurring_items: type: array items: $ref: "#/components/schemas/recurringObject" example: recurring_items: recurring_items: - id: 994069 description: Income status: reviewed transaction_criteria: start_date: "2024-09-01" end_date: "2024-10-31" anchor_date: "2024-09-14" granularity: month quantity: 1 payee: Penny Lane amount: "1250.8400" to_base: 1250.84 currency: usd plaid_account_id: 119806 manual_account_id: null overrides: payee: Paycheck category_id: 88 matches: request_start_date: "2024-10-01" request_end_date: "2024-10-31" expected_occurrence_dates: - "2024-10-14" - "2024-10-28" found_transactions: - date: "2024-10-14" transaction_id: 2212150658 missing_transaction_dates: - "2024-10-28" created_by: 18328 created_at: "2024-07-28T01:01:38.716Z" updated_at: "2024-07-28T01:01:38.716Z" source: manual - id: 994079 description: Monthly rent payable to Mrs Smith status: reviewed transaction_criteria: start_date: "2024-09-01" end_date: "2024-10-31" anchor_date: "2024-09-01" granularity: month quantity: 1 payee: '[No Payee]' amount: "850.0000" to_base: 850 currency: usd plaid_account_id: 119806 manual_account_id: null overrides: payee: Rent notes: Monthly rent payable to Mrs Smith category_id: 83 matches: request_start_date: "2024-10-01" request_end_date: "2024-10-31" expected_occurrence_dates: - "2024-10-01" found_transactions: - date: "2024-10-01" transaction_id: 2212150656 missing_transaction_dates: [] created_by: 18328 created_at: "2025-06-28T01:01:38.195Z" updated_at: "2025-06-28T01:01:38.195Z" source: manual "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be a valid integer instancePath: /query/ids/0 schemaPath: "#/properties/query/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: There is no tag with the id:'543210' "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /recurring_items/{id}: get: tags: - recurring_items summary: Get a single recurring item description: Retrieve the details of a specific recurring item with the specified ID. operationId: getRecurringById parameters: - name: id in: path description: ID of the recurring item to retrieve required: true schema: type: integer format: int32 examples: tag: summary: Example of a recurring ID value: 994069 not found: summary: Example of a recurring ID that does not exist value: 543210 - name: start_date in: query schema: type: string format: date description: Denotes the beginning of the range used to populate the `matching` object in the recurring items. If omitted, the current month will be used as the range.
Required if end_date exists. - name: end_date in: query schema: type: string format: date description: "Denotes the end of the range used to populate the `matching` object in the recurring items. Required if start_date exists. " responses: "200": description: Tag Object with the requested Tag ID content: application/json: schema: $ref: "#/components/schemas/recurringObject" example: id: 994069 description: Income status: reviewed transaction_criteria: start_date: "2024-09-01" end_date: "2024-10-31" anchor_date: "2024-09-14" granularity: month quantity: 1 payee: Penny Lane amount: "1250.8400" to_base: 1250.84 currency: usd plaid_account_id: 119806 manual_account_id: null overrides: payee: Paycheck category_id: 88 matches: request_start_date: "2024-10-01" request_end_date: "2024-10-31" expected_occurrence_dates: - "2024-10-14" - "2024-10-28" found_transactions: - date: "2024-10-14" transaction_id: 2212150658 missing_transaction_dates: - "2024-10-28" created_by: 18328 created_at: "2024-07-28T01:01:38.716Z" updated_at: "2024-07-28T01:01:38.716Z" source: manual "400": description: Bad Request content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Request Validation Failure errors: - errMsg: must be a valid integer instancePath: /query/ids/0 schemaPath: "#/properties/query/properties/ids/items/type" keyword: type params: type: integer "401": $ref: "#/components/responses/unauthorizedToken" "404": description: Not Found content: application/json: schema: $ref: "#/components/schemas/errorResponseObject" example: message: Not Found errors: - errMsg: There is no tag with the id:'543210' "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /budgets/settings: get: tags: - budgets summary: Get budget settings description: Returns the budget-related settings for the user's account. operationId: getBudgetSettings responses: "200": description: Budget settings for the account content: application/json: schema: $ref: "#/components/schemas/budgetSettingsResponseObject" "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" /budgets: put: tags: - budgets summary: Upsert budget description: |- Create or update a budget for a category and period.

If a budget already exists for the specified `start_date` and `category_id`, the `amount` (and optional `currency` and `notes`) are updated; otherwise a new budget entry is created.

Note that `start_date` **must** be a valid budget period start for the account (based on the account's budget period settings). If an invalid `start_date` is provided, the request will fail with an error that indicates what the previous and next valid start dates are.

Use the [budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view the account's budget settings.
To view existing budgets details use the [summary](#tag/summary) endpoint. operationId: upsertBudget requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/upsertBudgetRequestObject" example: start_date: "2025-01-01" category_id: 315177 amount: 500 currency: "usd" notes: "Monthly groceries" responses: "200": description: Budget upserted successfully content: application/json: schema: $ref: "#/components/schemas/budgetUpsertResponseObject" example: category_id: 315177 start_date: "2025-01-01" amount: 500 currency: "usd" to_base: 500.0 notes: "Monthly groceries" "400": description: Bad Request (invalid period start, invalid category, or validation failure) content: application/json: schema: oneOf: - $ref: "#/components/schemas/budgetInvalidPeriodErrorObject" - $ref: "#/components/schemas/errorResponseObject" examples: invalid period: summary: Start date not a valid budget period start value: message: Invalid Request errors: - errMsg: "The requested start date is not a valid budget period start for this account." requested_start_date: "2025-01-15" previous_valid_start_date: "2025-01-01" next_valid_start_date: "2025-02-01" validation error: summary: Bad Category ID value: message: Invalid Request Body errors: - errMsg: "Category ID does not exist" "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" delete: tags: - budgets summary: Delete budget description: Removes the budget for the given category and period. If there already is no budget set for that period, the request still succeeds (idempotent).

Note that `start_date` **must** be a valid budget period start for the account (based on the account's budget period settings). If an invalid `start_date` is provided, the request will fail with an error that indicates what the previous and next valid start dates are.

Use the [budgets/settings](#tag/budgets/GET/budgets/settings) endpoint to view the account's budget settings.
To view existing budgets details use the [summary](#tag/summary) endpoint. operationId: deleteBudget parameters: - in: query name: category_id required: true description: Category ID of the budget to delete schema: type: integer format: int32 - in: query name: start_date required: true description: Start date of the budget period in ISO 8601 date format (YYYY-MM-DD) schema: type: string format: date responses: "204": description: Budget deleted (or no budget existed for the given category and period) "400": description: Bad Request (invalid period start, invalid category, or validation failure) content: application/json: schema: oneOf: - $ref: "#/components/schemas/budgetInvalidPeriodErrorObject" - $ref: "#/components/schemas/errorResponseObject" examples: invalid period: summary: Bad Category ID value: message: Invalid Request errors: - errMsg: "The requested start date is not a valid budget period start for this account." requested_start_date: "2025-01-15" previous_valid_start_date: "2025-01-01" next_valid_start_date: "2025-02-01" validation error: summary: Invalid request body value: message: Invalid Request Body errors: - errMsg: "Category ID does not exist" "401": $ref: "#/components/responses/unauthorizedToken" "429": $ref: "#/components/responses/rateLimited" "500": $ref: "#/components/responses/serverError" security: - bearerSecurity: [] - cookieAuth: []