Record deposits and withdrawals
Enter income, expenses and cash withdrawals as balanced transactions, then check the balance and list what you have entered.
Day-to-day bookkeeping is a sequence of transactions: your pay arrives in the bank, you buy groceries, you take cash out of a machine. In double-entry bookkeeping each one is a date, a description and two or more splits whose values sum to exactly zero. A value is in the transaction's currency; positive values are debits, negative values credits.
The sign rule
The account you name decides what a sign means. A positive value on a bank account is a deposit, a negative one a
withdrawal. On an income account the signs run the other way, because income is a credit: pay of 2,500.00 is
+2500.00 on the bank account and -2500.00 on the income account. An expense is + on the expense account and -
on the account you paid from.
Steps
- Make the accounts the transaction needs (see Set up accounts): a bank account, a cash account, an income account and an expense account.
- Record a deposit: transaction.post with
datePosted,descriptionand two splits, the bank account+and the income account-. - Record an expense: the expense account
+and the account that paid-. - Record a cash withdrawal: a transfer from the bank account to the cash account,
-and+. It is neither income nor expense, so no category is involved. - Check the balance with account.balance, and review the entries with transaction.list, optionally for one account and a date range.
If the splits do not sum to zero the call fails with unbalanced and nothing is recorded, so a typing slip never leaves a half-entered transaction.
Example
Example: with a new, empty book open as book.gnucash, at 2024-07-15T12:00:00Z.
JSON-RPC
Request:
{"jsonrpc":"2.0","id":1,"method":"account.create","params":{"name":"Checking","type":"BANK","commodity":"USD"}}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":2,"method":"account.create","params":{"name":"Wallet","type":"CASH","commodity":"USD"}}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":3,"method":"account.create","params":{"name":"Salary","type":"INCOME","commodity":"USD"}}
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":4,"method":"account.create","params":{"name":"Groceries","type":"EXPENSE","commodity":"USD"}}
Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":5,"method":"transaction.post","params":{"datePosted":"2024-07-01","description":"July pay","splits":[{"account":"Checking","value":"2500.00"},{"account":"Salary","value":"-2500.00"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"description": "July pay",
"balanced": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":6,"method":"transaction.post","params":{"datePosted":"2024-07-03","description":"ATM","splits":[{"account":"Wallet","value":"100.00"},{"account":"Checking","value":"-100.00"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"balanced": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":7,"method":"transaction.post","params":{"datePosted":"2024-07-05","description":"Market","splits":[{"account":"Groceries","value":"63.40"},{"account":"Wallet","value":"-63.40"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"balanced": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":8,"method":"account.balance","params":{"account":"Checking"}}
Response:
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"balances": {
"commodity": "CURRENCY::USD",
"balance": {
"num": "240000",
"denom": "100"
},
"…": "…"
},
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":9,"method":"account.balance","params":{"account":"Wallet"}}
Response:
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"balances": {
"balance": {
"num": "3660",
"denom": "100"
},
"…": "…"
},
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":10,"method":"transaction.list","params":{"account":"Wallet"}}
Response:
{
"jsonrpc": "2.0",
"id": 10,
"result": {
"transactions": [
{
"description": "ATM",
"…": "…"
},
{
"description": "Market",
"…": "…"
}
]
}
}
Command line
red-ale exec --book book.gnucash --script - <<'EOF'
account.create {"name":"Checking","type":"BANK","commodity":"USD"}
account.create {"name":"Wallet","type":"CASH","commodity":"USD"}
account.create {"name":"Salary","type":"INCOME","commodity":"USD"}
account.create {"name":"Groceries","type":"EXPENSE","commodity":"USD"}
transaction.post {"datePosted":"2024-07-01","description":"July pay","splits":[{"account":"Checking","value":"2500.00"},{"account":"Salary","value":"-2500.00"}]}
transaction.post {"datePosted":"2024-07-03","description":"ATM","splits":[{"account":"Wallet","value":"100.00"},{"account":"Checking","value":"-100.00"}]}
transaction.post {"datePosted":"2024-07-05","description":"Market","splits":[{"account":"Groceries","value":"63.40"},{"account":"Wallet","value":"-63.40"}]}
account.balance {"account":"Checking"}
account.balance {"account":"Wallet"}
transaction.list {"account":"Wallet"}
EOF
It prints:
[
"…",
"…",
"…",
"…",
{
"description": "July pay",
"balanced": true,
"…": "…"
},
{
"balanced": true,
"…": "…"
},
{
"balanced": true,
"…": "…"
},
{
"balances": {
"commodity": "CURRENCY::USD",
"balance": {
"num": "240000",
"denom": "100"
},
"…": "…"
},
"…": "…"
},
{
"balances": {
"balance": {
"num": "3660",
"denom": "100"
},
"…": "…"
},
"…": "…"
},
{
"transactions": [
{
"description": "ATM",
"…": "…"
},
{
"description": "Market",
"…": "…"
}
]
}
]
MCP tool call
Tool call:
{"name":"account.create","arguments":{"name":"Checking","type":"BANK","commodity":"USD"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"account.create","arguments":{"name":"Wallet","type":"CASH","commodity":"USD"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"account.create","arguments":{"name":"Salary","type":"INCOME","commodity":"USD"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"account.create","arguments":{"name":"Groceries","type":"EXPENSE","commodity":"USD"}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"transaction.post","arguments":{"datePosted":"2024-07-01","description":"July pay","splits":[{"account":"Checking","value":"2500.00"},{"account":"Salary","value":"-2500.00"}]}}
Result:
{
"structuredContent": {
"description": "July pay",
"balanced": true,
"…": "…"
}
}
Tool call:
{"name":"transaction.post","arguments":{"datePosted":"2024-07-03","description":"ATM","splits":[{"account":"Wallet","value":"100.00"},{"account":"Checking","value":"-100.00"}]}}
Result:
{
"structuredContent": {
"balanced": true,
"…": "…"
}
}
Tool call:
{"name":"transaction.post","arguments":{"datePosted":"2024-07-05","description":"Market","splits":[{"account":"Groceries","value":"63.40"},{"account":"Wallet","value":"-63.40"}]}}
Result:
{
"structuredContent": {
"balanced": true,
"…": "…"
}
}
Tool call:
{"name":"account.balance","arguments":{"account":"Checking"}}
Result:
{
"structuredContent": {
"balances": {
"commodity": "CURRENCY::USD",
"balance": {
"num": "240000",
"denom": "100"
},
"…": "…"
},
"…": "…"
}
}
Tool call:
{"name":"account.balance","arguments":{"account":"Wallet"}}
Result:
{
"structuredContent": {
"balances": {
"balance": {
"num": "3660",
"denom": "100"
},
"…": "…"
},
"…": "…"
}
}
Tool call:
{"name":"transaction.list","arguments":{"account":"Wallet"}}
Result:
{
"structuredContent": {
"transactions": [
{
"description": "ATM",
"…": "…"
},
{
"description": "Market",
"…": "…"
}
]
}
}