Bookkeeping AI agent

Tell it about income and expenses in plain words; ask questions like "how much did we spend on ads this month?"

AI agentMedium Saves ~10 hours/month AI AgentsBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Chat — you message the agent
  1. You write "paid 1,200 for Facebook ads yesterday" or ask a question.
  2. The agent confirms the details and adds the transaction to your ledger.
  3. For questions, it reads the ledger and does the maths.
  4. It can draft a monthly summary email to your accountant.

What it can do

Unlike a fixed flow, an agent decides which of its tools to use, in what order — and remembers the conversation.

  • Records income and expenses from plain sentences
  • Answers questions about totals by category and period
  • Prepares monthly summaries
  • Drafts emails to your accountant

System prompt

The instructions that shape the agent. It's already inside the n8n template — copy it into Make or Zapier, and adjust the YOUR_… parts.

System prompt
You are a bookkeeping assistant for YOUR_BUSINESS. Currency: YOUR_CURRENCY. Today is {{ $now.toFormat('d LLLL yyyy') }}.

Tools:
- "Read ledger": all transactions (date, type income/expense, amount, category, description).
- "Add transaction": adds one income or expense. Categories: YOUR_CATEGORIES (e.g. Ads, Software, Salaries, Rent, Supplies, Sales, Other).
- "Email accountant": drafts an email to our accountant (never sends).

You can: record transactions the user describes ("paid 1,200 for Facebook ads yesterday"), answer questions ("how much did we spend on ads this month?"), and prepare monthly summaries.

Rules:
- Always read the ledger before answering questions about numbers. Do the arithmetic carefully and show the total and the period.
- Confirm amount, date and category before adding a transaction.
- You are not a tax advisor — for tax questions, suggest asking the accountant.

Safety rules

Built into the prompt and the tools:

  • Confirms amount, date and category before saving
  • Always reads the ledger before answering number questions
  • Not a tax advisor — refers tax questions to your accountant

Uses your own AI key (Claude, OpenAI or another model). Cost depends on the model and conversation length — a small, fast model keeps most conversations to a fraction of a cent.

Diagram

Bookkeeping chatChat TriggerBookkeeping agentAI AgentClaude modelAnthropic Chat Mo…◷MemorySimple MemoryGRead ledgerGoogle Sheets ToolGAdd transactionGoogle Sheets ToolGEmail accounta…Gmail Tool
Trigger AI Agent tool

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.

Workflow JSON
Show code (244 lines)
{
  "name": "Bookkeeping AI agent (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Bookkeeping AI agent\nTell it about income and expenses in plain words; ask questions like \"how much did we spend on ads this month?\"\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "public": true,
        "mode": "hostedChat",
        "initialMessages": "Tell me about an income or expense, or ask a question like “How much did we spend on ads this month?”",
        "options": {
          "responseMode": "lastNode"
        }
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Bookkeeping chat",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        0
      ],
      "webhookId": "2de5c18f-62da-415c-a349-f01983763a93"
    },
    {
      "parameters": {
        "options": {
          "systemMessage": "=You are a bookkeeping assistant for YOUR_BUSINESS. Currency: YOUR_CURRENCY. Today is {{ $now.toFormat('d LLLL yyyy') }}.\n\nTools:\n- \"Read ledger\": all transactions (date, type income/expense, amount, category, description).\n- \"Add transaction\": adds one income or expense. Categories: YOUR_CATEGORIES (e.g. Ads, Software, Salaries, Rent, Supplies, Sales, Other).\n- \"Email accountant\": drafts an email to our accountant (never sends).\n\nYou can: record transactions the user describes (\"paid 1,200 for Facebook ads yesterday\"), answer questions (\"how much did we spend on ads this month?\"), and prepare monthly summaries.\n\nRules:\n- Always read the ledger before answering questions about numbers. Do the arithmetic carefully and show the total and the period.\n- Confirm amount, date and category before adding a transaction.\n- You are not a tax advisor — for tax questions, suggest asking the accountant."
        }
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Bookkeeping agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.9,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-sonnet-5",
          "mode": "list"
        },
        "options": {}
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Claude model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        -40,
        220
      ]
    },
    {
      "parameters": {
        "contextWindowLength": 10
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        130,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Returns all transactions: date, type (income/expense), amount, category, description.",
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Ledger",
          "mode": "name"
        },
        "options": {}
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Read ledger",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        300,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Adds one confirmed income or expense.",
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Ledger",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "date": "={{ $fromAI('date', \"Transaction date YYYY-MM-DD\", 'string') }}",
            "type": "={{ $fromAI('type', \"income or expense\", 'string') }}",
            "amount": "={{ $fromAI('amount', \"Amount as a number\", 'number') }}",
            "category": "={{ $fromAI('category', \"One of the allowed categories\", 'string') }}",
            "description": "={{ $fromAI('description', \"Short description\", 'string') }}"
          }
        },
        "options": {}
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Add transaction",
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.5,
      "position": [
        470,
        220
      ]
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Drafts an email to the accountant (never sends it).",
        "resource": "draft",
        "operation": "create",
        "subject": "={{ $fromAI('subject', \"Email subject\", 'string') }}",
        "message": "={{ $fromAI('body', \"Email body, e.g. a monthly summary\", 'string') }}",
        "options": {
          "sendTo": "accountant@yourcompany.com"
        }
      },
      "id": "2de5c18f-62da-415c-a349-f01983763a93",
      "name": "Email accountant",
      "type": "n8n-nodes-base.gmailTool",
      "typeVersion": 2.1,
      "position": [
        640,
        220
      ]
    }
  ],
  "connections": {
    "Bookkeeping chat": {
      "main": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Memory": {
      "ai_memory": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Read ledger": {
      "ai_tool": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Add transaction": {
      "ai_tool": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Email accountant": {
      "ai_tool": [
        [
          {
            "node": "Bookkeeping agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Use a fixed list of categories so monthly reports stay clean.

Related flows