Why Reconcile GSTR-2A vs 2B?
GSTR-2A is dynamic — it updates whenever a supplier files GSTR-1. GSTR-2B is your fixed monthly ITC statement, locked on the 14th. From FY 2022-23, ITC claims must be based on GSTR-2B. Any gap between what you claimed and what appears in 2B is a mismatch that triggers an ASMT-10 scrutiny notice. Manual reconciliation is error-prone beyond 200 invoices per month. Python eliminates the error and compresses hours of work into minutes.
Rule 36(4) — ITC Restriction
ITC on invoices not appearing in GSTR-2B is restricted under Rule 36(4). Claiming restricted credit without reconciliation evidence is the most common trigger for ASMT-10 notices and potential demand orders under Section 73/74.
What the Python Engine Does
Export data from the GST portal
Download GSTR-2A and GSTR-2B as JSON from the GST portal. Export your purchase register as CSV from Tally, SAP, or any ERP. No manual reformatting needed — the script handles both.
Ingest and normalise with Pandas
Pandas reads both JSON exports and the purchase register CSV. GSTIN formats are normalised, invoice numbers are stripped of whitespace and case differences, and dates are standardised — removing false mismatches from data-entry variation.
Match by GSTIN + invoice number with fuzzy logic
Every line in the purchase register is matched against GSTR-2B. Exact matches are cleared; near-matches (one character off in an invoice number) are caught by fuzzy matching. Each unmatched line is labelled with a reason code: Supplier Not Filed, Timing Difference, Amount Variance, or Ineligible ITC.
Output a colour-coded, audit-ready Excel
openpyxl generates a formatted workbook: a summary tab with total matched, unmatched, and mismatch amounts reconciling to the notice figure, and a line-by-line annexure tab ready to attach directly to the ASMT-11 reply — no further editing required.
Core Matching Pattern
# Normalise invoice numbers before matching df_books['inv_key'] = (df_books['invoice_no'] .str.upper().str.strip().str.replace(r'[\s\-/]', '', regex=True)) df_2b['inv_key'] = (df_2b['invoice_no'] .str.upper().str.strip().str.replace(r'[\s\-/]', '', regex=True)) # Merge on GSTIN + normalised invoice number merged = df_books.merge(df_2b, on=['gstin', 'inv_key'], how='left', suffixes=('_books', '_2b')) # Label mismatch reasons def classify(row): if pd.isna(row['taxable_value_2b']): return 'Supplier Not Filed' if abs(row['taxable_value_books'] - row['taxable_value_2b']) > 1: return 'Amount Variance' return 'Matched' merged['reason'] = merged.apply(classify, axis=1)
The full script adds fuzzy matching for near-misses, GSTR-2A cross-referencing for timing differences, and openpyxl formatting for the ASMT-11 annexure output.
GSTR-2A vs GSTR-2B — Key Differences
GSTR-2A
- →Dynamic — updates continuously
- →Reflects latest supplier filings
- →Useful for chasing late suppliers
- →No ITC eligibility basis
GSTR-2B
- →Static — locked on 14th of month
- →Basis for ITC claims from FY 23
- →Mismatch here = ASMT-10 risk
- →Primary reconciliation target
Case Study: Mumbai Trading Co.
ASMT-10 received for a ₹14 lakh ITC mismatch across 212 invoices. The Python engine ran in under two minutes and classified 187 mismatches as timing differences (suppliers filed after the 2B lock date) and 25 as genuine data-entry errors correctable with credit notes. The ASMT-11 reply with the annexure was accepted by the officer. Notice closed in 21 days with zero penalty.
Common Questions
For ITC eligibility, GSTR-2B is the primary document. However, GSTR-2A is essential for the notice response — it shows whether a supplier has since filed (timing difference) versus genuinely never filed. The Python engine uses 2B as the primary match and 2A to classify timing differences, which are the most defensible mismatches in an ASMT-11 reply.
GSTR-2A and 2B are downloaded as JSON from the GST portal — the script reads these directly. The purchase register can be exported as CSV or Excel from Tally, SAP, Zoho Books, or any accounting software. The script has parsers for the most common Tally and SAP column formats and is adaptable for others.
Yes — and this is the best use of the tool. Running the reconciliation before filing GSTR-3B lets you identify and reverse ineligible ITC before it becomes a mismatch in the department's system. Proactive reversal eliminates the notice risk entirely. Most clients now run this as a monthly close step before the 20th.
Invoices from non-filing suppliers are flagged as "Supplier Not Filed" in the output. For the ASMT-11 response, these need to be supported with the original tax invoice, proof of payment, and evidence of goods/services receipt. The Python output also generates a supplier-wise non-filer summary which is useful for vendor follow-up and future ITC planning.
Run the reconciliation — before the notice arrives
Share your GSTR-2B JSON and purchase register. Ryan will run the Python engine and deliver a classified mismatch report within 24 hours.
WhatsApp Ryan → +91 95384 16161