GST Verification API Error Codes: A Troubleshooting Guide
Common GST API error codes explained — invalid GSTIN, unauthorised, rate limited, timeout — with a fix for each.
Every error a GST verification API can return falls into one of three buckets: something wrong with your request (4xx), something wrong on the server or upstream (5xx), or a perfectly valid request whose answer happens to be "this GSTIN doesn't exist." Mixing up the third case with an actual error is the single most common bug in GST API integrations, and this guide is built around getting that distinction right.
HTTP status codes, cause and fix
Start with the HTTP layer. This is the transport-level signal your HTTP client sees before your code ever looks at the response body:
| Status | Typical cause | Fix |
|---|---|---|
| 400 Bad Request | GSTIN missing or malformed — wrong length, invalid characters, bad checksum | Validate the GSTIN format client-side before calling; see the checksum rules in our GSTIN format guide |
| 401 Unauthorized | X-API-Key header missing, mistyped, or revoked | Check the key value and header name exactly; regenerate the key from your dashboard if needed |
| 402 Payment Required | Account has exhausted its verification credits | Top up or upgrade on your pricing plan; this is not a retryable error |
| 403 Forbidden | Key is valid but not permitted for this route, or IP/domain restrictions are set and not matched | Check key scopes and any configured allow-list in account settings |
| 404 Not Found | Wrong URL path — not the same as a GSTIN that doesn't exist (see below) | Confirm the endpoint path exactly matches /api/get-taxpayer-info/{gstin} |
| 422 Unprocessable Entity | Request is syntactically fine but semantically invalid — e.g. an unsupported query parameter | Check the request against current API documentation |
| 429 Too Many Requests | Rate limit exceeded for your plan | Respect Retry-After; back off with jitter — see our rate limits and webhooks guide |
| 500 Internal Server Error | Unexpected failure on the API side | Retry with backoff after a short delay; contact support if it persists |
| 502 Bad Gateway | A problem between the API and its upstream (often GSTN-side) | Retry with backoff; treat as transient |
| 504 Gateway Timeout | Upstream lookup took too long to respond | Retry once with backoff; if consistent, the upstream government system may be under load |
A "does not exist" GSTIN is not a transport error
This is the distinction that trips up the most integrations, so it is worth stating plainly: a well-formed GSTIN that has never been issued, or that no longer exists, is a successful API call with a not-found result — it is not the same thing as a 404, a 500, or any other transport-level failure. The HTTP request succeeded. The API did exactly what it was asked to do: it queried the live record and reported back that none exists for that number. Code that treats this outcome as an exception to catch, log, and alert on will generate constant false-positive noise, because "this GSTIN doesn't exist" is an entirely normal, expected answer — it happens every time someone mistypes a digit or tries to verify a number that was never real in the first place.
Upstream GSTN errors: SWEB_9035 and friends
Underneath the API's own response shape sits the government's own GSTN system, which has its own family of internal error codes. The one you will see most often is SWEB_9035 — "Invalid GSTIN / UID", which is GSTN's own way of reporting exactly the not-found case described above: the number is structurally valid but does not correspond to any taxpayer on record. When this code surfaces, it confirms the lookup reached the government system and got a definitive "no match" answer, rather than failing somewhere in between.
Other upstream error families exist for GSTN-side maintenance windows, temporary unavailability, and malformed queries, but SWEB_9035 is the one worth knowing by name because it is the one you will encounter routinely in normal usage — every time a customer, vendor, or user submits a GSTIN that turns out to be fake or mistyped.
Why a failed validation does not cost you a credit
It matters, practically, where in the pipeline a request fails. A request rejected for basic validation reasons — a malformed GSTIN that fails the checksum before it is even sent upstream, a missing or invalid API key, a request to the wrong path — never reaches a real lookup against GSTN records, and this API does not charge a verification credit for it. You are only billed for a completed lookup: one where the API actually queried the record and returned a result, whether that result is an active taxpayer, a cancelled registration, or a genuine not-found. This is a meaningful distinction if you are validating user-entered GSTINs at scale — client-side format checks (using the checksum described in our GSTIN format guide) filter out typos for free, before they ever touch your credit balance.
A sane error-handling pattern
Putting it together, a reasonable client-side handler treats HTTP status, the response body's own status field, and retryability as three separate questions:
async function verifyGstin(gstin) {
const res = await fetch(`https://gstinapi.com/api/get-taxpayer-info/${gstin}`, {
headers: { 'X-API-Key': process.env.GSTINAPI_KEY },
});
if (res.status === 401 || res.status === 403) {
throw new Error('Check your API key and account permissions.');
}
if (res.status === 402) {
throw new Error('Out of verification credits — upgrade your plan.');
}
if (res.status === 429) {
const retryAfter = Number(res.headers.get('Retry-After')) || 5;
await sleep(retryAfter * 1000);
return verifyGstin(gstin); // retry once, respecting the server's timing
}
if (res.status >= 500) {
throw new RetryableError('Upstream/API error — safe to retry with backoff.');
}
if (res.status === 400 || res.status === 422) {
throw new Error('GSTIN is malformed — check format before calling.');
}
const data = await res.json();
if (data.status === 'not_found') {
// Not an error: a successful call, no matching taxpayer.
return { exists: false };
}
return { exists: true, ...data };
}
Notice that the "not found" branch sits after a successful HTTP response, not inside the error handling at all — that placement is the whole point. For the retry logic itself, including how long to wait and how to add jitter, see our detailed rate limits, retries and webhooks guide.
Frequently asked questions
A note on accuracy. GST rules change often. This article reflects our understanding as of 30 August 2026 and is general information, not tax or legal advice. For the authoritative position, check gst.gov.in and cbic-gst.gov.in, or speak to a qualified tax professional about your specific situation.
Check a GSTIN right now, free
Five lookups a day, no account required. Status, filing history, e-invoicing and jurisdiction.
Free GST search toolBuild it into your product
One REST call, JSON back. Get an API key and 20 free verification credits in under a minute.
Start freeMore on developer integration guides
Browse every guide in the GST API blog.