Reconcile GSTR-2B against the Purchase Register into an ITC Report
Skill: Convert a GSTR-2B JSON and purchase register into an ITC reconciliation report
Region: India Category: GST — Input Tax Credit reconciliation (GSTR-2B vs books) Does: Takes the downloaded GSTR-2B JSON and the buyer's purchase register and produces an invoice-level ITC reconciliation report (JSON) — match status, mismatches, ineligible ITC under section 17(5), a vendor follow-up list, and the eligible ITC figures for GSTR-3B table 4. Standard: GSTN GSTR-2B (auto-drafted ITC statement) reconciled to books; output feeds GSTR-3B Table 4.
GSTR-2B is a static monthly statement (generated on the 14th). ITC is generally available only for invoices appearing in GSTR-2B (Rule 36(4) / section 16(2)(aa)). The AI matches and classifies; the taxpayer confirms eligibility and follows up with vendors before claiming. Verify cut-off dates and the current Rule 16(4) time limit.
When this applies
- A registered buyer reconciles purchases booked in its accounts against the ITC reflected in GSTR-2B for a tax period, before filing GSTR-3B.
- Identifies invoices in books-not-in-2B (defer the claim), in-2B-not-in-books (book or query), and value/tax mismatches.
- Not for generating GSTR-1 (supplier outward) or the GSTR-9 annual return (see
gst/build-gstr9-json.md).
Reconciliation procedure
- Read both sources. Parse the GSTR-2B JSON (sections
b2b,cdnr, etc.) and the purchase register (CSV/JSON: supplier GSTIN, invoice no, date, taxable value, IGST/CGST/SGST/cess, eligibility). - Build match keys. Key = supplier GSTIN + invoice number (normalized) + invoice date. Tolerate minor invoice-number formatting differences but flag them.
- Classify each record.
matched,mismatch_value,in_2b_not_in_books,in_books_not_in_2b. For matched, compare taxable value and each tax head within a tolerance (e.g. ₹1). - Apply eligibility. Flag ineligible ITC under section 17(5) (blocked credits) and any other non-creditable items; split eligible vs ineligible.
- Aggregate to GSTR-3B Table 4 figures (4A(5) all other ITC, 4B reversals, 4D ineligible).
- Emit the JSON report and a vendor follow-up list; validate with the checklist.
Source → reconciliation field map
| From the source | → Report field |
|---|---|
| Supplier GSTIN | lines[].gstin |
| Invoice number | lines[].invoice_no |
| Invoice date | lines[].invoice_date |
| Taxable value (2B vs books) | lines[].taxable_2b, lines[].taxable_books |
| IGST/CGST/SGST/cess (2B vs books) | lines[].tax_2b, lines[].tax_books |
| Match outcome | lines[].status |
| 17(5) / non-creditable flag | lines[].eligibility |
| Eligible ITC total | summary.itc_eligible |
| Ineligible ITC total | summary.itc_ineligible |
| GSTR-3B Table 4 figures | gstr3b_table4 |
| Vendors with missing/mismatched invoices | vendor_followup[] |
Document structure
itc_reconciliation
├── gstin, period
├── lines[] (per-invoice: keys, 2B vs books amounts, status, eligibility)
├── summary
│ ├── matched_count / mismatch_count / only_2b / only_books
│ ├── itc_eligible (igst/cgst/sgst/cess)
│ └── itc_ineligible
├── gstr3b_table4 (4A5, 4B2, 4D1, 4D2)
└── vendor_followup[] (gstin, issue, invoices)
Code tables
Match status
| Status | Meaning |
|---|---|
matched |
Same key, amounts within tolerance |
mismatch_value |
Same key, taxable/tax differs |
in_2b_not_in_books |
In GSTR-2B, not booked (book it or query) |
in_books_not_in_2b |
Booked, not in 2B (defer ITC until it appears) |
Eligibility
| Flag | Meaning |
|---|---|
eligible |
Creditable ITC |
blocked_17_5 |
Blocked credit under section 17(5) (e.g. motor vehicles, food & beverage, personal use) |
ineligible_other |
Non-creditable (exempt supplies, personal, etc.) |
GSTR-3B Table 4 targets
| Field | Meaning |
|---|---|
4A5 |
All other ITC (eligible, from 2B) |
4B1 |
ITC reversed — Rule 38/42/43, 17(5) |
4B2 |
ITC reversed — others |
4D1 |
Ineligible ITC — section 17(5) |
4D2 |
Ineligible ITC — others |
Calculation rules
- Tolerance: |taxable_2b − taxable_books| ≤ ₹1 and each tax head ≤ ₹1 ⇒
matched; otherwisemismatch_value. - Eligible ITC = Σ tax heads of
matched/mismatchlines that areeligibleand present in 2B. - Ineligible ITC (17(5)) = Σ tax heads flagged
blocked_17_5(report in 4D1; if availed then reversed, also reflect in 4B). - GSTR-3B 4A5 = eligible IGST/CGST/SGST/cess available from 2B for the period.
- Recompute every total from the line set; flag mismatches with the books.
Worked example (end-to-end)
Input — GSTR-2B (excerpt) + purchase register
GSTR-2B b2b: 27ABCDE1234F1Z5 | INV-101 | 2026-05-10 | taxable 100000 | IGST 18000
Purchase register:
27ABCDE1234F1Z5 | INV-101 | 2026-05-10 | taxable 100000 | IGST 18000 | eligible
27ZZZZZ9999Z1Z9 | INV-77 | 2026-05-12 | taxable 50000 | IGST 9000 | eligible (not in 2B)
27MNOPQ4321K1Z2 | INV-55 | 2026-05-08 | taxable 20000 | CGST 1800 SGST 1800 | blocked_17_5 (staff catering)
After matching + classification (intermediate)
INV-101 → matched, eligible (IGST 18000 available)
INV-77 → in_books_not_in_2b (defer 9000) → vendor follow-up
INV-55 → matched, blocked_17_5 (CGST 1800 + SGST 1800 ineligible)
eligible ITC: IGST 18000 ; ineligible 17(5): 3600
Output — ITC reconciliation report
{
"gstin": "27AAAAA0000A1Z5",
"period": "052026",
"lines": [
{ "gstin": "27ABCDE1234F1Z5", "invoice_no": "INV-101", "invoice_date": "2026-05-10",
"taxable_2b": 100000, "taxable_books": 100000,
"tax_2b": { "igst": 18000, "cgst": 0, "sgst": 0, "cess": 0 },
"tax_books": { "igst": 18000, "cgst": 0, "sgst": 0, "cess": 0 },
"status": "matched", "eligibility": "eligible" },
{ "gstin": "27ZZZZZ9999Z1Z9", "invoice_no": "INV-77", "invoice_date": "2026-05-12",
"taxable_2b": 0, "taxable_books": 50000,
"tax_2b": { "igst": 0, "cgst": 0, "sgst": 0, "cess": 0 },
"tax_books": { "igst": 9000, "cgst": 0, "sgst": 0, "cess": 0 },
"status": "in_books_not_in_2b", "eligibility": "eligible" },
{ "gstin": "27MNOPQ4321K1Z2", "invoice_no": "INV-55", "invoice_date": "2026-05-08",
"taxable_2b": 20000, "taxable_books": 20000,
"tax_2b": { "igst": 0, "cgst": 1800, "sgst": 1800, "cess": 0 },
"tax_books": { "igst": 0, "cgst": 1800, "sgst": 1800, "cess": 0 },
"status": "matched", "eligibility": "blocked_17_5" }
],
"summary": {
"matched_count": 2, "mismatch_count": 0, "only_2b": 0, "only_books": 1,
"itc_eligible": { "igst": 18000, "cgst": 0, "sgst": 0, "cess": 0 },
"itc_ineligible": { "igst": 0, "cgst": 1800, "sgst": 1800, "cess": 0 }
},
"gstr3b_table4": {
"4A5": { "igst": 18000, "cgst": 0, "sgst": 0, "cess": 0 },
"4D1": { "igst": 0, "cgst": 1800, "sgst": 1800, "cess": 0 }
},
"vendor_followup": [
{ "gstin": "27ZZZZZ9999Z1Z9", "issue": "in_books_not_in_2b", "invoices": ["INV-77"] }
]
}
Normalisations shown: keys built as GSTIN+invoice+date; INV-77 deferred (not in 2B) and pushed to vendor follow-up; INV-55 catering flagged blocked_17_5 → 4D1; eligible 4A5 IGST recomputed as 18000.
Validation checklist
- Both sources parsed; match key = GSTIN + invoice no + date (formatting differences flagged)
- Every record classified (matched / mismatch_value / in_2b_not_in_books / in_books_not_in_2b)
- Section 17(5) blocked credits flagged and excluded from eligible ITC
- Eligible ITC counts only invoices present in GSTR-2B (Rule 36(4) / 16(2)(aa))
- GSTR-3B Table 4 figures (4A5, 4B, 4D1) reconcile to the summary
- Vendor follow-up list covers all in-books-not-in-2B and mismatches
- Totals recomputed from lines; ITC time-limit (Rule 16(4)) considered before claiming
Last updated: 2026-06-13 — verify current ITC eligibility rules (36(4), 16(2)(aa), 16(4)), section 17(5) list, and GSTR-3B Table 4 structure before use.