Method

transaction.post

Post a balanced transaction; refused if unbalanced.

Records a transaction: a date, a description and two or more splits, each moving a value into or out of one account. The splits' values must sum to exactly zero, or the transaction is refused with unbalanced and the book is left as it was. Values are in the transaction's currency; a split in an account of another commodity also needs its amount in that commodity, which is how a purchase of shares or foreign currency records its price.

Without currency, the transaction's currency is the commodity of the first split's account. That matters when the first split is in a foreign-currency account: the values are then in that currency, and every split in an account of another commodity needs an amount. To record the transaction in your own currency, pass currency, or put an account in that currency first. If the first split's account holds no currency (shares, say), currency is required and the call is refused as invalid without it.

Positive values are debits, negative values credits: paying 750.00 of rent from a bank account is -750.00 on the bank account and 750.00 on the expense account.

Examples

Example: with a new, empty book open as book.gnucash.

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":"transaction.post","params":{"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "guid": "…",
    "currency": "CURRENCY::USD",
    "description": "Rent",
    "datePosted": "2024-07-01",
    "balanced": true,
    "splits": [
      {
        "account": "…",
        "accountName": "Rent",
        "value": {
          "num": "75000",
          "denom": "100"
        },
        "amount": {
          "num": "75000",
          "denom": "100"
        },
        "…": "…"
      },
      {
        "accountName": "Checking",
        "value": {
          "num": "-75000",
          "denom": "100"
        },
        "…": "…"
      }
    ],
    "…": "…"
  }
}

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"}
transaction.post {"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}
EOF

It prints:

[
  "…",
  "…",
  {
    "guid": "…",
    "currency": "CURRENCY::USD",
    "description": "Rent",
    "datePosted": "2024-07-01",
    "balanced": true,
    "splits": [
      {
        "account": "…",
        "accountName": "Rent",
        "value": {
          "num": "75000",
          "denom": "100"
        },
        "amount": {
          "num": "75000",
          "denom": "100"
        },
        "…": "…"
      },
      {
        "accountName": "Checking",
        "value": {
          "num": "-75000",
          "denom": "100"
        },
        "…": "…"
      }
    ],
    "…": "…"
  }
]

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":"transaction.post","arguments":{"datePosted":"2024-07-01","description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"750.00"}]}}

Result:

{
  "structuredContent": {
    "guid": "…",
    "currency": "CURRENCY::USD",
    "description": "Rent",
    "datePosted": "2024-07-01",
    "balanced": true,
    "splits": [
      {
        "account": "…",
        "accountName": "Rent",
        "value": {
          "num": "75000",
          "denom": "100"
        },
        "amount": {
          "num": "75000",
          "denom": "100"
        },
        "…": "…"
      },
      {
        "accountName": "Checking",
        "value": {
          "num": "-75000",
          "denom": "100"
        },
        "…": "…"
      }
    ],
    "…": "…"
  }
}

Splits that don't balance are refused, and nothing is recorded:

Example: with a new, empty book open as book.gnucash.

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":"transaction.post","params":{"description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"705.00"}]}}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": 2002,
    "message": "…",
    "data": {
      "imbalance": "-45.00",
      "currency": "USD",
      "help": "error/unbalanced"
    }
  }
}

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"}
transaction.post {"description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"705.00"}]}
EOF

It fails with exit status 2, printing on standard error:

{
  "error": {
    "code": 2002,
    "message": "…",
    "data": {
      "imbalance": "-45.00",
      "currency": "USD",
      "help": "error/unbalanced"
    }
  }
}

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":"transaction.post","arguments":{"description":"Rent","splits":[{"account":"Checking","value":"-750.00"},{"account":"Rent","value":"705.00"}]}}

Result:

{
  "isError": true,
  "structuredContent": {
    "error": {
      "code": 2002,
      "name": "unbalanced",
      "message": "…",
      "data": {
        "imbalance": "-45.00",
        "currency": "USD",
        "help": "error/unbalanced"
      }
    }
  }
}

Effect: write, on the Book.

Params

Params of transaction.post.

  • currency (CommodityId or null): The transaction currency. Defaults to the first split's account commodity, when that is a currency.
  • datePosted (Date or null): The posted date; today by default. Stored at its day-neutral time with a date-posted slot, as GnuCash does.
  • dateEntered (Timestamp or null): When it was entered; now by default.
  • num (string or null): Check or reference number.
  • description (string or null): Description.
  • notes (string or null): Notes; empty means none.
  • docLink (string or null): A document link: a URL, a file:// URI, or a path relative to the path head. Empty means none.
  • splits (array of SplitParams, required): The splits. Their values must sum to zero.
  • recordPrice (boolean): Record each priced split's value/amount in the price database, as GnuCash's register does (xaccTransRecordPrice with source user:split-register).

Result

A transaction, as returned by every transaction method.

  • guid (Guid, required): The transaction's GUID.
  • currency (CommodityId, required): The transaction currency, which values are in.
  • num (string or null): Check or reference number.
  • description (string or null): Description.
  • notes (string or null): Notes.
  • datePosted (Date or null): The posted date.
  • datePostedTime (Timestamp, required): The posted instant as stored (the posted date's day-neutral time for transactions GnuCash or red-ale enters).
  • dateEntered (Timestamp, required): When it was entered.
  • void (boolean, required): Void, by GnuCash 5.17's rule: the void timestamp is set.
  • voidReason (string or null): Why it was voided.
  • voidTime (Timestamp or null): When it was voided.
  • readOnly (string or null): Why it may not be changed, when read-only (voided, or generated by a business document).
  • reversedBy (Guid or null): The transaction that reverses this one.
  • closing (boolean, required): A book-closing transaction.
  • balanced (boolean, required): The split values sum to zero; with trading accounts on, trading values and each commodity's amounts too.
  • docLink (string or null): The document link (assoc_uri slot), as stored: a URL, a file:// URI, or a path relative to the path head.
  • splits (array of SplitInfo, required): Its splits, in stored order (debits first).