The GST API npm package

@dlminds/gstin-api is the official Node.js and TypeScript client for GSTIN API. It validates any Indian GST number offline — format, modulus-36 check digit, state, embedded PAN — and verifies it against the live government register when you give it a key.

npm install @dlminds/gstin-api
View on npm Source on GitHub MIT · Node 18+ · zero dependencies

Both layers in ten lines

import { isValidGstin, parseGstin, GstinApiClient } from '@dlminds/gstin-api';

isValidGstin('27AAACR5055K1Z7');       // true — format + check digit, offline
parseGstin('27AAACR5055K1Z7').state;   // 'Maharashtra'

// Reads GSTINAPI_API_KEY from the environment. One credit per lookup.
const taxpayer = await new GstinApiClient().lookup('27AAACR5055K1Z7');

taxpayer?.legalName;                   // 'RELIANCE INDUSTRIES LIMITED'
taxpayer?.isActive;                    // true — the thing a checksum cannot tell you
// null instead of an object means no registration exists. That is not billed.

What it exports

Offline — no key, no network, no quota

Export What it does
isValidGstin(value) true when the string is a well-formed GSTIN and its check digit matches.
gstinRejectionReason(value) Why it failed, in words you can put next to a form field — or null when it passed.
normalizeGstin(value) Trims, strips spaces and upper-cases, so pasted input stops being a support ticket.
parseGstin(value) State, embedded PAN, PAN holder type, entity code and check digit as a typed object.
explainGstin(value) The same breakdown as human-readable rows — what the CLI prints.
stateForCode(code) The state behind the first two digits, including whether it charges SGST or UTGST.
buildGstin(parts) Constructs a structurally valid GSTIN — for fixtures, not for pretending a business exists.

Online — one credit per resolved lookup

Export What it does
client.lookup(gstin) The register record, or null when nothing is registered against that number.
client.verify(gstin) Never throws for a bad number or a missing registration — puts the outcome in a message field.
client.verifyMany(list) The same, across a list, with bounded concurrency.
latestFiling(taxpayer) The most recent return on record, without reaching into the array yourself.
Errors are typed: InvalidGstinError, AuthenticationError, InsufficientCreditsError, RateLimitError, ServiceError and TransportError, so a catch block can tell a typo apart from an outage.

The full reference, including every field on the returned taxpayer record, is in the package README and in the API documentation. The internals of the checksum are walked through in the check digit algorithm, measured.

Frequently asked questions

The official package is @dlminds/gstin-api. Install it with npm install @dlminds/gstin-api. It validates GSTIN format and the modulus-36 check digit offline with no API key, and calls the GSTIN API service for live taxpayer details when you supply one.
It is written in TypeScript and ships its own declarations, so there is no @types package to install. Both ESM and CommonJS builds are published, and it targets Node 18 and above.
Yes. isValidGstin, gstinRejectionReason, normalizeGstin, parseGstin and the state helpers all run locally with no network call, no key and no quota. Only the GstinApiClient methods reach the register, and only those cost a credit.
The offline half does — it is pure arithmetic with no Node built-ins, so it bundles into any front end. Do not run the client half in a browser: that would ship your API key to every visitor. Validate in the browser, verify on your server.
None. The package has zero runtime dependencies and uses the global fetch, which is why the install is small enough to put in a form-validation bundle.

Also available for Python

pip install gstin-toolkit — the same API surface, tested against the same corpus, so the two cannot disagree about a number.