1. Install the Python library
An official client library exists for Python, and it handles the auth header and response parsing for you.
pip install gstinapiThen verify a GSTIN in three lines:
from gstinapi import GstinApi
client = GstinApi(api_key="gak_your_key_here")
result = client.verify("33AAACC1206D1ZN")
print(result.legal_name) # "CHENNAI CORPORATION LIMITED"
print(result.status) # "Active"
print(result.taxpayer_type) # "Regular"Source on GitHub · package registry
Without the library (requests)
The API is a single GET with one header, so you can skip the library entirely if you would rather not add a dependency.
import requests
resp = requests.get(
"https://gstinapi.in/v1/gstin/33AAACC1206D1ZN",
headers={"x-api-key": "gak_your_key_here"},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
print(data["legal_name"], data["status"])2. Validate the GSTIN offline first
A malformed GSTIN returns 400 and costs nothing — but it still costs a round trip. The GSTIN checksum is computable offline, so catch typos before you spend the network call.
CODES = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def is_valid_gstin(gstin: str) -> bool:
"""Validate a GSTIN's format and check digit without calling the API."""
gstin = (gstin or "").strip().upper()
if len(gstin) != 15:
return False
total = 0
for i, ch in enumerate(gstin[:14]):
if ch not in CODES:
return False
product = CODES.index(ch) * (2 if i % 2 else 1)
total += product // 36 + product % 36
expected = CODES[(36 - total % 36) % 36]
return gstin[14] == expected
assert is_valid_gstin("33AAACC1206D1ZN")
assert not is_valid_gstin("33AAACC1206D1ZZ")This proves the GSTIN is well-formed. It cannot tell you whether the registration exists or is still active — only a live lookup does that, because registrations get cancelled.
3. Handle every status code
| Code | Meaning | What to do |
|---|---|---|
| 400 | Invalid GSTIN format | No credit charged. Validate client-side and this never fires. |
| 401 | Missing or invalid x-api-key | Check the header name and that the key is not truncated. |
| 402 | Out of credits | Different from 404 — the lookup never ran. Surface a recharge prompt, not "not found". |
| 404 | GSTIN not registered | A valid-format GSTIN that the GST network has no record of. |
| 429 | Rate limit exceeded | 60 requests/minute on standard accounts. Retry with backoff. |
| 502 | GST provider unavailable | Upstream GSP hiccup. Safe to retry — nothing was charged. |
Retry policy. Retry only on 429 and 502, with exponential backoff, maximum 3 attempts. Never retry 400, 401, 402, 403 or 404 — the answer will not change.
import time
import requests
RETRYABLE = {429, 502}
def verify(gstin: str, api_key: str, attempts: int = 3):
for attempt in range(attempts):
resp = requests.get(
f"https://gstinapi.in/v1/gstin/{gstin}",
headers={"x-api-key": api_key},
timeout=10,
)
if resp.status_code == 200:
return resp.json()
if resp.status_code == 404:
return None # valid format, no such registration
if resp.status_code == 402:
raise RuntimeError("Out of credits — recharge at https://gstinapi.in/buy-credits")
if resp.status_code not in RETRYABLE:
raise RuntimeError(resp.json().get("error", resp.text))
if attempt < attempts - 1:
time.sleep(2 ** attempt) # 1s, then 2s
raise RuntimeError("GST provider unavailable after retries")4. Wiring it into Django or FastAPI
Keep the key in an environment variable, never in source. Call the API at the point a vendor record is created or edited, not on every page render — a GSTIN changes rarely, so cache the result against the vendor row and re-check on a schedule instead.
import os
from gstinapi import GstinApi
client = GstinApi(api_key=os.environ["GSTIN_API_KEY"])Frequently asked questions
Is there a free way to verify GST numbers in Python?
Yes. Every account gets up to 100 free lookups — 25 on signup and 25 for each setup step — and they never expire. That is enough to evaluate the API properly against your own data without paying anything. No credit card is needed to get a key.
Can I validate a GSTIN in Python without an API call?
You can validate the format and the check digit offline — the code on this page does exactly that, and it catches typos for free. What you cannot do offline is confirm the GSTIN is actually registered, who it belongs to, or whether it is still active. Only a live lookup answers that, because registrations get cancelled.
How do I verify GST numbers in bulk from Python?
Loop over your list and call the endpoint per GSTIN, staying inside the 60 requests/minute limit — a short sleep between calls, or a semaphore capped well under 60/min if you go concurrent. Handle 429 by backing off rather than by hammering. There is no separate bulk endpoint; the per-call API is the bulk API.
Which Python version does the library need?
The gstinapi package targets currently supported Python 3 releases. If you are on something older, the raw requests example on this page works anywhere requests does.
The same guide in another language
Ready to integrate?
Create an account, generate a key, and you start with 25 free lookups — up to 100 once you finish the setup steps. No card, and they never expire.
Need to check a single GSTIN right now? Use the free search tool — no signup.