/^/
HardInternational7 min read

Indian GSTIN Regex

Validates the structural format of a 15-character Indian GST Identification Number (GSTIN): state code, embedded PAN, entity code, the fixed letter Z, and a checksum character.

#gst#gstin#india#tax-id#validation#international#business

Regex Pattern

^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$

Pattern Breakdown

Hover over a token to see what it does.

^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$
TokenMeaning
^Anchors the match to the start of the string
[0-9]{2}Two-digit state code (e.g. 27 for Maharashtra, 07 for Delhi)
[A-Z]{5}The first five characters of the taxpayer's embedded PAN
[0-9]{4}The four PAN digits
[A-Z]{1}The final PAN check letter
[1-9A-Z]{1}Entity/registration number for this PAN within the state (1-9 then A-Z for more than 9 registrations)
ZFixed literal 'Z', reserved by default for future use in the GSTIN scheme
[0-9A-Z]{1}$Final alphanumeric checksum character, then end of string

Detailed Explanation

What it does

This pattern validates that a string has the exact 15-character structural shape of a GSTIN: a 2-digit state code, a 10-character embedded PAN (5 letters, 4 digits, 1 letter), a 1-character entity code, the fixed letter 'Z', and a final alphanumeric check character. It does not independently verify the embedded PAN or recompute the checksum.

Why it works

GSTIN is a fixed-position code defined by the GST Council, so chaining exact-length character classes in sequence mirrors the specification directly: digits where digits are required, letters where letters are required, and a literal 'Z' at the position the scheme reserves. Anchoring the whole 15-character sequence with `^`/`$` prevents partial or padded matches.

Common use cases

  • Validating GSTIN fields on Indian B2B invoicing, e-way bill, or vendor onboarding forms
  • Filtering bulk-uploaded vendor/customer master data for structurally invalid tax IDs
  • Pre-flight format checks before calling the GST Network (GSTN) verification API
  • Extracting GSTIN-shaped tokens from scanned invoice text for further processing

Edge cases

  • Lowercase GSTINs are rejected since real GSTINs are always issued in uppercase and the pattern is case-sensitive
  • The 13th character (entity code) legitimately uses both digits 1-9 and letters, which [1-9A-Z] allows for
  • A structurally valid GSTIN with an incorrect checksum character still passes, since checksum math isn't performed by regex
  • State codes above 37 (the current max as of recent additions) still match numerically even if not yet a real state code

Limitations

  • Does not recompute or verify the checksum digit, which uses a modulus-36 algorithm regex cannot express
  • Does not confirm the embedded PAN portion is a real, issued PAN
  • Cannot verify the GSTIN is active or belongs to the claimed business (requires the GSTN portal/API)
  • Assumes the fixed 'Z' convention holds; any future scheme changes would require updating the pattern

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

22AAAAA0000A1Z5 27AAPFU0939F1ZV 07ABCDE1234F2Z9

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const gstinRegex = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/;
console.log(gstinRegex.test('22AAAAA0000A1Z5')); // true

Common Mistakes

Believing this regex confirms the GSTIN is active and registered

Fix: Call the GSTN public search API (or a KYC provider) after format validation for authoritative status

Forgetting the fixed literal 'Z' at position 14 and using [A-Z] there instead

Fix: Keep the literal Z; it is a reserved constant in the current GSTIN scheme, not a variable field

Allowing lowercase GSTINs by adding an 'i' flag

Fix: Real GSTINs are always uppercase; uppercase user input before validating rather than loosening the pattern

Performance Notes

  • All character classes have fixed counts, so the engine matches in linear time with no backtracking
  • The literal 'Z' anchor mid-pattern lets the engine fail fast on the majority of malformed 15-character strings
  • Compile the regex once at module load time since GSTIN validation is often run per-row over large vendor datasets

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes