mibudge

mibudge API

REST API for the mibudge personal budgeting service.

Authentication

All endpoints require JWT authentication via Authorization: Bearer <token> header. Obtain tokens through the login flow; refresh via POST /api/token/refresh/ (httpOnly cookie).

Permissions

Money fields

Monetary values are represented as a decimal amount paired with an ISO 4217 currency code (e.g. amount + amount_currency). Currency defaults to the account’s currency if not specified.

Version: 1.0.0

Authentication

Endpoints

api

POST /api/token/

Operation: api_token_create

JWT obtain endpoint that stores the refresh token in an httpOnly cookie and returns only the access token in the response body.

This is the browser-SPA login flow: JS receives the short-lived access token (kept in memory); the refresh token is a Secure/HttpOnly/SameSite=Strict cookie that JS cannot read, and that the browser sends automatically to /api/token/refresh/.

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

POST /api/token/refresh/

Operation: api_token_refresh_create

JWT refresh endpoint that reads the refresh token from the httpOnly cookie rather than the request body.

On success, returns {“access”: “"} in JSON. When token rotation is enabled, also rotates the refresh cookie so the 14-day sliding window resets with each use.

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

allocations

GET /api/v1/allocations/

Operation: allocations_list

Return allocations belonging to the authenticated user’s transactions. Filterable by transaction, budget, and category. Orderable by created_at.

Parameters:

Response 200:

GET /api/v1/allocations/{id}/

Operation: allocations_retrieve

Return a single transaction allocation by UUID.

Parameters:

Response 200:

bank-accounts

GET /api/v1/bank-accounts/

Operation: bank_accounts_list

Return bank accounts owned by the authenticated user. Filterable by account_type. Orderable by name or created_at.

Parameters:

Response 200:

POST /api/v1/bank-accounts/

Operation: bank_accounts_create

Create a new bank account. The authenticated user is automatically added as an owner. An ‘Unallocated’ budget is auto-created by a post_save signal. Optionally set initial posted_balance, available_balance, and currency (all immutable after creation).

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 201:

GET /api/v1/bank-accounts/{id}/

Operation: bank_accounts_retrieve

Return a single bank account by UUID.

Parameters:

Response 200:

PUT /api/v1/bank-accounts/{id}/

Operation: bank_accounts_update

Full update of a bank account. Only ‘name’ is mutable after creation – bank, account_type, currency, and balances are rejected if changed.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

PATCH /api/v1/bank-accounts/{id}/

Operation: bank_accounts_partial_update

Partial update of a bank account. Only ‘name’ is mutable after creation.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

DELETE /api/v1/bank-accounts/{id}/

Operation: bank_accounts_destroy

Delete a bank account and all associated budgets, transactions, and allocations.

Parameters:

Response 204: No response body

GET /api/v1/bank-accounts/{id}/funding-summary/

Operation: bank_accounts_funding_summary_retrieve

Return the total amounts that will be automatically funded at the next event for each distinct funding schedule on this account. Only active, schedulable budgets are included – paused, archived, completed goals, and RECURRING budgets that delegate to a fill-up goal are excluded. Results are grouped by funding schedule (RRULE string) and sorted by next event date.

Parameters:

Response 200: Per-schedule funding totals.

POST /api/v1/bank-accounts/{id}/mark-imported/

Operation: bank_accounts_mark_imported_create

Record that a transaction import has been completed for this account. Sets last_imported_at to now and advances last_posted_through to the supplied date (never regresses an existing value). Body: {“last_posted_through”: “YYYY-MM-DD”}.

Parameters:

Request Body (application/json):

Response 200:

banks

GET /api/v1/banks/

Operation: banks_list

Return all banks in the system. Banks are shared reference data managed through the admin – any authenticated user can list and retrieve them.

Parameters:

Response 200:

GET /api/v1/banks/{id}/

Operation: banks_retrieve

Return a single bank by UUID.

Parameters:

Response 200:

budgets

GET /api/v1/budgets/

Operation: budgets_list

Return budgets belonging to the authenticated user’s accounts. Filterable by bank_account, budget_type, archived, and paused. Searchable by name. Orderable by name, created_at, or balance.

Parameters:

Response 200:

POST /api/v1/budgets/

Operation: budgets_create

Create a new budget under a bank account. Required: name, bank_account (UUID), budget_type, funding_type, and target_balance. The bank_account and budget_type are immutable after creation. Balance is managed by signals and is always read-only.

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 201:

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

GET /api/v1/budgets/{id}/

Operation: budgets_retrieve

Return a single budget by UUID.

Parameters:

Response 200:

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

PUT /api/v1/budgets/{id}/

Operation: budgets_update

Full update of a budget. bank_account and budget_type are immutable. The unallocated budget cannot be renamed.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

PATCH /api/v1/budgets/{id}/

Operation: budgets_partial_update

Partial update of a budget. bank_account and budget_type are immutable. The unallocated budget cannot be renamed.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

DELETE /api/v1/budgets/{id}/

Operation: budgets_destroy

Delete a budget. The unallocated budget cannot be deleted (403). A budget with existing transaction allocations cannot be deleted (400) – archive it instead.

Parameters:

Response 204: No response body

POST /api/v1/budgets/{id}/archive/

Operation: budgets_archive_create

Archive a budget. Any remaining balance is transferred to the account’s unallocated budget. If the budget has an associated fill-up goal, that budget is also archived and its balance moved to unallocated. The unallocated budget cannot be archived.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

currencies

GET /api/v1/currencies/

Operation: currencies_retrieve

Return all ISO 4217 currency codes supported by the system, sorted by code. Each entry includes the code, English name, and numeric ISO 4217 code. Requires authentication.

Response 200: List of supported currencies.

internal-transactions

GET /api/v1/internal-transactions/

Operation: internal_transactions_list

Return budget-to-budget transfers belonging to the authenticated user’s accounts. Filterable by bank_account, src_budget, dst_budget, and date range (date_from/date_to). Orderable by created_at.

Parameters:

Response 200:

POST /api/v1/internal-transactions/

Operation: internal_transactions_create

Transfer money between two budgets in the same bank account. Required: bank_account (UUID), amount, src_budget (UUID), and dst_budget (UUID). The authenticated user is recorded as the actor. Internal transactions are write-once – to reverse a transfer, create a new one with src and dst swapped.

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 201:

GET /api/v1/internal-transactions/{id}/

Operation: internal_transactions_retrieve

Return a single internal transaction by UUID.

Parameters:

Response 200:

transactions

GET /api/v1/transactions/

Operation: transactions_list

Return transactions belonging to the authenticated user’s accounts. Filterable by bank_account, pending status, transaction_type, and date range (date_from/date_to). Searchable by description, raw_description, and party. Orderable by transaction_date, amount, or created_at.

Parameters:

Response 200:

POST /api/v1/transactions/

Operation: transactions_create

Create a new bank transaction. Required: bank_account (UUID), amount, transaction_date, transaction_type, and raw_description. A default TransactionAllocation to the bank account’s unallocated budget is auto-created. After creation, only transaction_type, memo, and description are updatable.

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 201:

GET /api/v1/transactions/{id}/

Operation: transactions_retrieve

Return a single transaction by UUID.

Parameters:

Response 200:

PUT /api/v1/transactions/{id}/

Operation: transactions_update

Full update of a transaction. Only transaction_type, memo, and description are mutable after creation.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

PATCH /api/v1/transactions/{id}/

Operation: transactions_partial_update

Partial update of a transaction. Only transaction_type, memo, and description are mutable after creation.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

DELETE /api/v1/transactions/{id}/

Operation: transactions_destroy

Delete a transaction. Balance changes are reversed by the pre_delete signal. Associated allocations are cascade-deleted.

Parameters:

Response 204: No response body

POST /api/v1/transactions/{id}/splits/

Operation: transactions_splits_create

Declaratively set how a transaction’s amount is split across budgets. All referenced budgets must belong to the same bank account as the transaction. The backend reconciles existing allocations to match: creating, updating, or deleting as needed. Any unallocated remainder gets an allocation to the account’s unallocated budget. Returns all allocations for this transaction after reconciliation.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

users

GET /api/v1/users/

Operation: users_list

Return all users. Restricted to staff/admin users.

Parameters:

Response 200:

GET /api/v1/users/{username}/

Operation: users_retrieve

Return a single user by username. Restricted to staff/admin users.

Parameters:

Response 200:

PUT /api/v1/users/{username}/

Operation: users_update

Full update of a user profile. Restricted to staff/admin users.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

PATCH /api/v1/users/{username}/

Operation: users_partial_update

Partial update of a user profile. Restricted to staff/admin users.

Parameters:

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

GET /api/v1/users/me/

Operation: users_me_retrieve

GET returns the authenticated user’s own profile. PATCH allows updating the name field. Available to any authenticated user (not restricted to staff).

Response 200:

PATCH /api/v1/users/me/

Operation: users_me_partial_update

GET returns the authenticated user’s own profile. PATCH allows updating the name field. Available to any authenticated user (not restricted to staff).

Request Body (application/json):

Request Body (application/x-www-form-urlencoded):

Request Body (multipart/form-data):

Response 200:

Schemas

AccountTypeEnum

Bank

Read-only serializer for banks.

Banks are shared reference data managed only through the admin.

BankAccount

Serializer for bank accounts.

On create the caller supplies name, bank (UUID), account_type, account_number, and optionally currency and initial balances. The view routes creation through BankAccountService which adds the requesting user as owner and seeds the Unallocated budget.

After creation, name and account_number are updatable. Currency, account_type, bank, and balances are immutable once the account exists.

Group assignment is not yet supported via the API.

BankAccountRequest

Serializer for bank accounts.

On create the caller supplies name, bank (UUID), account_type, account_number, and optionally currency and initial balances. The view routes creation through BankAccountService which adds the requesting user as owner and seeds the Unallocated budget.

After creation, name and account_number are updatable. Currency, account_type, bank, and balances are immutable once the account exists.

Group assignment is not yet supported via the API.

BlankEnum

Budget

Serializer for budgets.

On create the caller supplies bank_account (UUID) and budget properties. After creation, bank_account and budget_type are immutable. Balance is managed by signals and is always read-only. The unallocated budget’s name cannot be changed.

Currency is inherited from the bank account via the pre_save signal and is not accepted from the client.

Args: obj: The Budget instance being serialized.

Returns: Dict with ‘date’, ‘amount’, ‘amount_currency’, ‘deferred’, or None.

BudgetRequest

Serializer for budgets.

On create the caller supplies bank_account (UUID) and budget properties. After creation, bank_account and budget_type are immutable. Balance is managed by signals and is always read-only. The unallocated budget’s name cannot be changed.

Currency is inherited from the bank account via the pre_save signal and is not accepted from the client.

BudgetTypeEnum

CategoryEnum

FundingTypeEnum

InternalTransaction

Serializer for internal transactions (budget-to-budget transfers).

Internal transactions are write-once: the API supports create and read but not update or delete. To reverse a transfer, create a new internal transaction with the src and dst budgets swapped.

On create the caller supplies bank_account, amount, src_budget, and dst_budget. The view sets the actor to the requesting user.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

InternalTransactionRequest

Serializer for internal transactions (budget-to-budget transfers).

Internal transactions are write-once: the API supports create and read but not update or delete. To reverse a transfer, create a new internal transaction with the src and dst budgets swapped.

On create the caller supplies bank_account, amount, src_budget, and dst_budget. The view sets the actor to the requesting user.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

PaginatedBankAccountList

PaginatedBankList

PaginatedBudgetList

PaginatedInternalTransactionList

PaginatedTransactionAllocationList

PaginatedTransactionList

PaginatedUserList

PatchedBankAccountRequest

Serializer for bank accounts.

On create the caller supplies name, bank (UUID), account_type, account_number, and optionally currency and initial balances. The view routes creation through BankAccountService which adds the requesting user as owner and seeds the Unallocated budget.

After creation, name and account_number are updatable. Currency, account_type, bank, and balances are immutable once the account exists.

Group assignment is not yet supported via the API.

PatchedBudgetRequest

Serializer for budgets.

On create the caller supplies bank_account (UUID) and budget properties. After creation, bank_account and budget_type are immutable. Balance is managed by signals and is always read-only. The unallocated budget’s name cannot be changed.

Currency is inherited from the bank account via the pre_save signal and is not accepted from the client.

PatchedTransactionRequest

Serializer for bank transactions.

On create the caller supplies bank_account, amount, transaction_date, transaction_type, raw_description, and optionally pending, memo, and description.

After creation only transaction_type, memo, and description are updatable. The view is responsible for creating the default TransactionAllocation to the unallocated budget on create.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

PatchedUserRequest

Serializer for user profiles.

The default_bank_account field is writable but constrained: the bank account must be owned by the user being updated. On output it returns the UUID string (or null).

TokenObtainPair

TokenObtainPairRequest

TokenRefresh

TokenRefreshRequest

Transaction

Serializer for bank transactions.

On create the caller supplies bank_account, amount, transaction_date, transaction_type, raw_description, and optionally pending, memo, and description.

After creation only transaction_type, memo, and description are updatable. The view is responsible for creating the default TransactionAllocation to the unallocated budget on create.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

TransactionAllocation

Serializer for transaction allocations.

An allocation maps a portion of a transaction’s amount to a budget. On create the caller supplies transaction, amount, and optionally budget (defaults to unallocated) and category. After creation, budget, category, and memo are updatable.

The serializer enforces two key constraints:

  1. Same-account restriction – the budget must belong to the same bank account as the transaction. Cross-account allocations are rejected with a 400 error.
  2. Sum constraint – the total allocated amount across all allocations for a transaction must not exceed the transaction amount.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

TransactionRequest

Serializer for bank transactions.

On create the caller supplies bank_account, amount, transaction_date, transaction_type, raw_description, and optionally pending, memo, and description.

After creation only transaction_type, memo, and description are updatable. The view is responsible for creating the default TransactionAllocation to the unallocated budget on create.

The amount_currency is read from raw request data by djmoney’s MoneyField.get_value() – no explicit currency field declaration is needed.

TransactionSplitsRequest

Serializer for the declarative splits endpoint.

Accepts a dict mapping budget UUIDs to amounts. The backend reconciles existing allocations to match the declared state. Any remainder goes to the unallocated budget.

All budgets must belong to the same bank account as the transaction. Cross-account budget references are rejected with a 400 error.

TransactionTypeEnum

User

Serializer for user profiles.

The default_bank_account field is writable but constrained: the bank account must be owned by the user being updated. On output it returns the UUID string (or null).

UserRequest

Serializer for user profiles.

The default_bank_account field is writable but constrained: the bank account must be owned by the user being updated. On output it returns the UUID string (or null).