n8n for CA Firms: Auto-Pull GSTR-2B and Flag ITC Mismatches
A 200-client CA firm checks GSTR-2B against purchase registers by hand every month. Here is an n8n workflow that auto-pulls 2B, runs the ITC reconciliation logic, and emails a mismatch report per client.
Hrishikesh Baidya
May 29, 20259 min read
0%
A CA firm with 200 GST clients spends the first ten days of every month doing the same thing 200 times: download GSTR-2B, open the client's purchase register, and eyeball which input-tax credits match and which don't. It is the most automatable task in the entire practice. This post is an n8n workflow that pulls each client's GSTR-2B on a schedule, runs the ITC reconciliation logic, and emails a per-client mismatch report — so the team reviews exceptions instead of doing data-entry.
200
Clients in the Example
14th
Day GSTR-2B Is Generated
~16 nodes
In the n8n Flow
₹740/mo
Self-Hosted Infra (Hetzner)
## What does this n8n workflow actually do?
It runs on a monthly cron after GSTR-2B is generated, pulls each client's 2B data (via a GSP/ASP API or an uploaded JSON), compares every invoice against the client's purchase register, and classifies each line as matched, mismatched, missing-in-2B, or missing-in-books. It then emails the firm a clean exceptions report per client. The accountant only looks at the lines that need a human.
GSTR-2B is the static, auto-drafted input-tax-credit statement the GST portal generates monthly. Because it's static — it doesn't change after generation for that period — it's the right anchor for reconciliation, unlike the dynamic GSTR-2A.
## Why this matters now
Wrong input-tax credit claims are the single most expensive GST error a small business makes. Claim ITC that isn't in your 2B and the department can reverse it with interest; miss ITC that is in your 2B and you've handed money to the government for no reason. The reconciliation has to happen every month, for every client, and doing it by hand at 200-client scale guarantees something slips. We built a related GSTR-3B reminder flow before — see our n8n + WhatsApp GSTR-3B reminder cron for CA firms — but reminders only tell you a deadline is near. This flow does the actual matching.
Reconciliation is rules, not judgement. "Does GSTIN + invoice number + taxable value + tax amount match within tolerance?" is a yes/no a computer answers perfectly. Reserve the human for the genuinely ambiguous lines — the ten that matter, not the 990 that don't.
## The matching logic (the framework)
Every purchase invoice gets classified into one of four buckets. This is the whole reconciliation engine.
✅
Matched
GSTIN, invoice number, taxable value, and tax amount all agree within a small tolerance. Claim the ITC. No human needed.
⚠️
Mismatched
Same invoice found in both, but a value differs beyond tolerance — usually a tax amount or a fat-finger on taxable value. Flag for review.
📥
In 2B, not in books
The supplier filed it; you haven't booked it. Either a missed purchase entry or an invoice you didn't receive. Often recoverable ITC you'd otherwise lose.
📤
In books, not in 2B
You booked it; the supplier hasn't filed. Don't claim yet — claiming ITC absent from 2B is the risky one. Chase the supplier.
A practical matching note: never match on invoice number alone. Suppliers format invoice numbers inconsistently (leading zeros, prefixes, slashes). Match on the tuple of GSTIN plus a normalised invoice number plus taxable value, with a small rounding tolerance on tax of one or two rupees.
Out of 412 invoices, only 40 need a human. That's the entire value proposition: turn a 412-line manual check into a 40-line review.
One subtlety worth building in from day one: track the "in books, not in 2B" lines across months, not just within a month. A supplier who hasn't filed this month often files next month, and that invoice then appears in a later 2B. If your flow keeps a rolling list of unclaimed invoices and re-checks them against each new 2B, it catches the credit the month it becomes claimable — instead of the client either forgetting it or claiming it early and exposing themselves. This carry-forward register is the single feature that separates a toy reconciliation script from one a practice actually trusts. It is also the feature most hand-built spreadsheets skip, which is why credits quietly leak: an invoice that wasn't in 2B in May, filed by the supplier in June, gets lost in the gap between two separate monthly spreadsheets that never talk to each other.
## How do you build it in n8n? (the step-by-step)
This runs on self-hosted n8n (v1.62 at time of writing) on a ₹740/month Hetzner CX22 — the same setup we cost out in our n8n + Shopify + Tally GST sync guide.
1
Cron trigger on the 14th, monthly
GSTR-2B for a month is generated on the 14th of the following month. Set a Schedule Trigger to fire on the 14th (or 15th, for safety) at a quiet hour. Verification: a manual test execution fires and reaches the next node with the correct return period.
2
Loop over your client list
Read clients from a Google Sheet or Postgres table — GSTIN, name, contact, and a per-client tolerance. Use a Split In Batches node so one slow client doesn't block the rest. Verification: the loop iterates the exact count of active clients and logs each GSTIN.
3
Fetch GSTR-2B per client
Call your GSP/ASP provider's GSTR-2B endpoint with an HTTP Request node, authenticated per client. No GSP yet? Fall back to a watched folder where staff drop the 2B JSON downloaded from the portal. Verification: the response contains the B2B invoice array for the right period; assert the period field.
4
Pull the purchase register
Read the client's booked purchases for the same period from Tally (via an export), Zoho Books API, or a Sheet. Normalise both sides to one schema: GSTIN, invoice no, date, taxable value, IGST, CGST, SGST. Verification: both datasets land in the same column shape before matching.
5
Run the four-bucket match in a Code node
A Code node normalises invoice numbers (strip spaces, leading zeros, prefixes), builds a key of GSTIN + normalised-invoice, and classifies each line into matched / mismatched / in-2B-only / in-books-only with the tax tolerance. Verification: feed a fixture with one known case of each bucket and assert four correct labels.
6
Build the per-client report and email it
Render the four buckets into an HTML table or a CSV attachment, with totals and the rupee value of at-risk and recoverable ITC. Email it to the engagement partner with the Send Email node, subject line stamped with client name and period. Verification: the email arrives with correct totals and the CSV opens cleanly in Excel.
7
Log every run for the audit trail
Append a row to a "runs" sheet or table: client, period, counts per bucket, at-risk ITC, timestamp. This is your evidence that reconciliation happened, when, and what it found. Verification: every client processed has exactly one run row for the period.
Start with the JSON-upload fallback. Getting GSP API access takes paperwork. Ship v1 with staff dropping portal-downloaded 2B JSONs into a watched folder — you get 90% of the value in a day, and wire the API later without changing the matching logic.
## Your pre-launch checklist
Cron set for the 14th/15th, after 2B generation
Client master has GSTIN, contact, and per-client tolerance
2B source working (GSP API or watched-folder JSON)
Purchase register exports to a fixed schema
Invoice-number normalisation handles prefixes, slashes, leading zeros
Match key is GSTIN + normalised invoice + taxable value
Tax tolerance set (1–2 rupee rounding) and documented
Per-client report emails the right partner with totals
Run log appends one audit row per client per period
## When should a CA firm NOT automate this?
Automation fits firms with steady monthly volume and clients on real accounting software. Three situations where you slow down.
First, clients whose "books" are a WhatsApp folder of invoice photos — there's nothing structured to match against, so fix the bookkeeping before the reconciliation. Second, the first month for a new client, where you don't yet know their supplier quirks; run it manually once, learn the edge cases, then automate. Third, reverse-charge and import-of-services entries, which don't appear in 2B the same way — carve these out into a separate manual check rather than forcing them through the four-bucket logic and getting false flags.
Never auto-claim. This flow flags and reports — it does not file. A human partner decides what ITC to claim. The "in books, not in 2B" bucket especially needs judgement: claiming credit absent from 2B is exactly what triggers departmental reversals with interest.
## A real example: the 200-client firm
A mid-size CA firm in Indore, three partners and a dozen articled assistants, ran 2B reconciliation entirely by hand for around 200 GST clients. The first two weeks of every month were swallowed by it, and credits still slipped — a missed "in-2B-not-in-books" line here, a wrong claim there.
We built this exact n8n flow with the JSON-upload fallback first, then GSP API for the larger clients. The monthly reconciliation grunt-work dropped from a multi-day slog to a same-day review of exceptions, and the audit log gave the partners something they never had: provable evidence of when each client's ITC was checked and what it found. The firm's articled assistants now spend that fortnight on advisory work that actually bills. We see the same upstream-data payoff building finance tooling like Radiant Finance, where the whole product depends on clean reconciliation. As Hrishikesh, our CTO, puts it, the win isn't the automation — it's giving skilled people back the hours the machine should have had all along.
## Frequently asked questions
### What is GSTR-2B and how is it different from 2A?
GSTR-2B is a static, auto-drafted input-tax-credit statement the GST portal generates once a month, around the 14th of the following month. Unlike GSTR-2A, which keeps changing as suppliers file, 2B is frozen for the period — which makes it the correct, stable anchor for ITC reconciliation.
### Can n8n pull GSTR-2B automatically?
Yes, through a GSP or ASP provider's API using an HTTP Request node, authenticated per client. If you don't have GSP access yet, a watched-folder fallback works: staff download the 2B JSON from the portal and drop it in a folder n8n monitors, and the rest of the flow is identical.
### What does it cost to run?
Self-hosted n8n on a Hetzner CX22 runs about ₹740 a month for the infrastructure. GSP API access has its own per-GSTIN pricing depending on the provider. The build itself is a one-time engineering cost; the watched-folder version can be running in a day.
### How do you match invoices reliably?
Never on invoice number alone — suppliers format them inconsistently. Match on a key of GSTIN plus a normalised invoice number (strip spaces, prefixes, and leading zeros) plus taxable value, with a one-to-two-rupee tolerance on the tax amount to absorb rounding.
### Does this file the return or claim ITC for me?
No, and it deliberately shouldn't. The flow classifies and emails a report; a partner decides what to claim. The "in books, not in 2B" cases in particular need human judgement, because claiming credit that isn't in 2B is what invites reversals with interest.
### How long does it take to build?
A working v1 with the JSON-upload fallback can be built in a day or two. Adding GSP API integration, per-client tolerances, and a polished report layer typically takes about a week of engineering, after which it runs itself every month on the cron.
Want this GSTR-2B reconciliation built for your CA practice?
We build the n8n ITC-reconciliation flow — 2B pull, four-bucket matching, per-client report, and audit log — for Indian CA firms in about 7 working days. Typical project: ₹45k–₹90k, self-hosted on your infra. Suitable if your team loses the first fortnight of every month to manual matching. No slides — just your client list and our honest take.