Skip to content

Ledger model

The API is resource-oriented. Most integrations touch the same small set of objects repeatedly, so it helps to understand how they fit together before you start writing data.

ResourcePurpose
meAuthenticated subject metadata and account-level context
accountsWallets, bank accounts, cards, investments, loans, and other balance containers
transactionsExpenses, income, and transfers
categoriesSystem or custom labels used to classify transactions
payeesCounterparties or merchant-like entities attached to transactions

DuitMyself intentionally uses these amount rules:

  • Positive amounts are expenses.
  • Negative amounts are income.

This is the opposite of some accounting and banking APIs. Make this conversion explicit when syncing from another system.

Do not model a transfer as separate expense and income rows unless your source system truly stores it that way.

Use:

  • isTransfer: true
  • transferToAccountId
  • optional destination amount and exchange rate for cross-currency transfers
  • Categories can be system-owned or user-owned.
  • System categories are readable, but write routes are for custom categories.
  • Payees are reusable counterparties. Store them once, then attach them to many transactions.

Public IDs such as acct_..., txn_..., cat_..., and payee_... are stable API identifiers.

  • Use these IDs when calling read, patch, or delete routes.
  • Never rely on Convex internal document IDs.
  • If your source system already has its own identifiers, pair them with the API’s externalId-based upsert routes.