Create a budget
Plan income and spending per account and period, fill the amounts by hand or estimate them from past transactions, and compare plan with actuals in the Budget Report.
A budget is a plan: how much you expect each account to receive or spend in each period. Comparing it with what actually happened tells you where the money went. A budget has a number of periods (for example 12 months) that start on a date, and an amount for any account in any period.
Steps
- Create the budget with budget.create: a
name,numPeriods(1 to 60) and arecurrencesaying how long a period is and when the first starts. The first budget becomes the default one. - Set amounts with budget.setAmounts: a list of
{account, period, amount}. Periods count from 0. Amounts keep the account's natural sign: income is negative (a credit), expenses positive. One call is atomic, so a bad period leaves the budget unchanged. - Or estimate them with budget.estimate: it fills the periods of the accounts you name
from what happened in the past, either period by period from a
startDate, or as an average (useAverage). It overwrites those accounts' amounts, so use it on a budget you have not filled yet. - Add notes to cells with budget.setNotes.
- Read it back with budget.get, and list budgets with budget.list.
- Compare with actuals. Run the Budget Report with report.run: it shows, per account and period,
the budget, the actual and the difference (Budget Report). Other budget reports are listed
by report.list. Set the budget it uses in the
General/Budgetoption.
Example
A three-month budget for rent and salary, with rent estimated from two past months.
Example: with a new, empty book open as book.gnucash, at 2024-04-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":"Rent","type":"EXPENSE","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":"transaction.post","params":{"datePosted":"2024-01-05","description":"Rent","splits":[{"account":"Rent","value":"750.00"},{"account":"Checking","value":"-750.00"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":5,"method":"transaction.post","params":{"datePosted":"2024-02-05","description":"Rent","splits":[{"account":"Rent","value":"812.50"},{"account":"Checking","value":"-812.50"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": "…"
}
Request:
{"jsonrpc":"2.0","id":6,"method":"budget.create","params":{"name":"Spring","numPeriods":3,"recurrence":{"mult":1,"periodType":"month","start":"2024-04-01"}}}
Response:
{
"jsonrpc": "2.0",
"id": 6,
"result": {
"name": "Spring",
"numPeriods": 3,
"isDefault": true,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":7,"method":"budget.setAmounts","params":{"budget":"00ed000000000000000000000000000a","amounts":[{"account":"Salary","period":0,"amount":"-3000.00"},{"account":"Salary","period":1,"amount":"-3000.00"},{"account":"Salary","period":2,"amount":"-3000.00"}]}}
Response:
{
"jsonrpc": "2.0",
"id": 7,
"result": {
"set": 3,
"unset": 0,
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":8,"method":"budget.estimate","params":{"budget":"00ed000000000000000000000000000a","accounts":["Rent"],"startDate":"2024-01-01","significantDigits":2}}
Response:
{
"jsonrpc": "2.0",
"id": 8,
"result": {
"amounts": [
{
"accountName": "Rent",
"period": 0,
"amount": {
"num": "750",
"denom": "1"
},
"…": "…"
},
{
"period": 1,
"amount": {
"num": "813",
"denom": "1"
},
"…": "…"
},
{
"period": 2,
"amount": {
"num": "0",
"denom": "1"
},
"…": "…"
}
],
"…": "…"
}
}
Request:
{"jsonrpc":"2.0","id":9,"method":"report.run","params":{"report":"Budget Report"}}
Response:
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"title": "…",
"sections": "…",
"…": "…"
}
}
Command line
red-ale exec --book book.gnucash --script - <<'EOF'
account.create {"name":"Checking","type":"BANK","commodity":"USD"}
account.create {"name":"Rent","type":"EXPENSE","commodity":"USD"}
account.create {"name":"Salary","type":"INCOME","commodity":"USD"}
transaction.post {"datePosted":"2024-01-05","description":"Rent","splits":[{"account":"Rent","value":"750.00"},{"account":"Checking","value":"-750.00"}]}
transaction.post {"datePosted":"2024-02-05","description":"Rent","splits":[{"account":"Rent","value":"812.50"},{"account":"Checking","value":"-812.50"}]}
budget.create {"name":"Spring","numPeriods":3,"recurrence":{"mult":1,"periodType":"month","start":"2024-04-01"}}
budget.setAmounts {"budget":"00ed000000000000000000000000000a","amounts":[{"account":"Salary","period":0,"amount":"-3000.00"},{"account":"Salary","period":1,"amount":"-3000.00"},{"account":"Salary","period":2,"amount":"-3000.00"}]}
budget.estimate {"budget":"00ed000000000000000000000000000a","accounts":["Rent"],"startDate":"2024-01-01","significantDigits":2}
report.run {"report":"Budget Report"}
EOF
It prints:
[
"…",
"…",
"…",
"…",
"…",
{
"name": "Spring",
"numPeriods": 3,
"isDefault": true,
"…": "…"
},
{
"set": 3,
"unset": 0,
"…": "…"
},
{
"amounts": [
{
"accountName": "Rent",
"period": 0,
"amount": {
"num": "750",
"denom": "1"
},
"…": "…"
},
{
"period": 1,
"amount": {
"num": "813",
"denom": "1"
},
"…": "…"
},
{
"period": 2,
"amount": {
"num": "0",
"denom": "1"
},
"…": "…"
}
],
"…": "…"
},
{
"title": "…",
"sections": "…",
"…": "…"
}
]
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":"Rent","type":"EXPENSE","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":"transaction.post","arguments":{"datePosted":"2024-01-05","description":"Rent","splits":[{"account":"Rent","value":"750.00"},{"account":"Checking","value":"-750.00"}]}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"transaction.post","arguments":{"datePosted":"2024-02-05","description":"Rent","splits":[{"account":"Rent","value":"812.50"},{"account":"Checking","value":"-812.50"}]}}
Result:
{
"content": [
{
"type": "text",
"text": "\"…\""
}
]
}
Tool call:
{"name":"budget.create","arguments":{"name":"Spring","numPeriods":3,"recurrence":{"mult":1,"periodType":"month","start":"2024-04-01"}}}
Result:
{
"structuredContent": {
"name": "Spring",
"numPeriods": 3,
"isDefault": true,
"…": "…"
}
}
Tool call:
{"name":"budget.setAmounts","arguments":{"budget":"00ed000000000000000000000000000a","amounts":[{"account":"Salary","period":0,"amount":"-3000.00"},{"account":"Salary","period":1,"amount":"-3000.00"},{"account":"Salary","period":2,"amount":"-3000.00"}]}}
Result:
{
"structuredContent": {
"set": 3,
"unset": 0,
"…": "…"
}
}
Tool call:
{"name":"budget.estimate","arguments":{"budget":"00ed000000000000000000000000000a","accounts":["Rent"],"startDate":"2024-01-01","significantDigits":2}}
Result:
{
"structuredContent": {
"amounts": [
{
"accountName": "Rent",
"period": 0,
"amount": {
"num": "750",
"denom": "1"
},
"…": "…"
},
{
"period": 1,
"amount": {
"num": "813",
"denom": "1"
},
"…": "…"
},
{
"period": 2,
"amount": {
"num": "0",
"denom": "1"
},
"…": "…"
}
],
"…": "…"
}
}
Tool call:
{"name":"report.run","arguments":{"report":"Budget Report"}}
Result:
{
"structuredContent": {
"title": "…",
"sections": "…",
"…": "…"
}
}