Integration guide 8 min read

GST Verification in n8n Workflows

Build an n8n workflow that verifies GSTINs from a form, sheet or CRM using the HTTP Request node, with error handling and retries.

Written and reviewed by the GSTIN API team Last reviewed

n8n is a good home for GST verification because it gives you what Zapier and Power Automate make you pay extra for: a plain HTTP Request node, a Code node for the one piece of logic that needs it, loops with real batching, and a proper error workflow. This guide builds the whole thing: a trigger that produces a GSTIN, a format check, the API call with the key stored as a credential, a branch on the returned status, a write-back to your sheet and a Slack alert when a supplier comes back Cancelled.

The shape of the workflow

Every GST verification workflow in n8n is the same five stages, whatever the source of the GSTIN:

  1. Trigger — a new sheet row, a webhook from your app, or a form submission.
  2. Format check — a Code or IF node that drops anything that is not a well-formed GSTIN.
  3. HTTP Request — the API call, one per item.
  4. IF on status — Active goes one way, Cancelled or Suspended another.
  5. Write back and alert — update the source record, notify a person when it matters.

If you have built the same thing in Zapier or Power Automate, the logic is identical. What changes is that n8n processes a list of items through each node, so the batch case is a small extension of the single-record case rather than a different design.

Step 1: pick a trigger

Pick the trigger that matches where the GSTIN first enters your process:

  • Google Sheets Trigger on "Row Added" for a vendor onboarding sheet. It polls, so expect a short delay after the row appears.
  • Webhook node when your own application should ask n8n to verify a GSTIN at signup or checkout. Your app POSTs a JSON body containing the GSTIN; the workflow can reply with the result using a Respond to Webhook node.
  • n8n Form Trigger when you want a hosted form for suppliers or internal staff with no other system involved.

Whichever you use, add a Set (Edit Fields) node right after it that copies the GSTIN into a field with a fixed name, say gstin, trimmed and uppercased. Every later node then references the same field, and swapping the trigger later does not break anything downstream.

Step 2: check the GSTIN format before you spend a credit

A GSTIN is 15 characters with a fixed structure: two-digit state code, the holder's PAN, an entity number, a literal Z and a check character. The anchored pattern, explained character by character in GSTIN regex explained, is:

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

The no-code option is an IF node with a String condition, "matches regex", against the gstin field. The Code node option lets you tag each item instead of dropping it, which is better when you want to write "Invalid format" back to the sheet:


// Code node, mode: Run Once for All Items
const pattern = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/;

return $input.all().map(item => {
  const gstin = String(item.json.gstin || '').trim().toUpperCase();
  return {
    json: { ...item.json, gstin, formatOk: pattern.test(gstin) },
  };
});

Follow it with an IF node on formatOk. The regex does not check the final check character; that needs the mod-36 calculation, which you can also do in the Code node or leave to the API. Our API rejects a GSTIN that fails format or check-digit validation without billing a credit, but filtering early still keeps those items off your error path. Paste a few suspect values into the GSTIN validator if you want to see which rule they break.

Step 3: the HTTP Request node

First create the credential: in Credentials, add a Header Auth credential, set the name to X-API-Key and the value to your key from the API access page. Then add an HTTP Request node on the "valid" branch and configure it like this:

SettingValueWhy
MethodGETThe lookup is a read; there is no request body
URLhttps://gstinapi.com/api/get-taxpayer-info/ followed by an expression for gstinThe GSTIN goes in the path
AuthenticationGeneric Credential Type → Header AuthSends X-API-Key from the encrypted credential
Options → Timeout15–30 secondsStops an item hanging on a slow upstream response
Settings → Retry On FailOn, 3 tries, a few seconds apartAbsorbs a transient 429, 502 or network drop
Settings → On ErrorContinue (using error output)Sends failed items down a separate branch instead of stopping the run
HTTP Request node settings for a GSTIN lookup.

If you open the node's JSON (copy the node and paste it into a text editor), the parameters look roughly like the snippet below. Treat it as an illustration of the settings, not an importable export: exact parameter names and the node's type version depend on your n8n version.

{
  "name": "Verify GSTIN",
  "type": "n8n-nodes-base.httpRequest",
  "parameters": {
    "method": "GET",
    "url": "=https://gstinapi.com/api/get-taxpayer-info/{{ $json.gstin }}",
    "authentication": "genericCredentialType",
    "genericAuthType": "httpHeaderAuth",
    "options": { "timeout": 20000 }
  },
  "retryOnFail": true,
  "maxTries": 3,
  "waitBetweenTries": 3000,
  "onError": "continueErrorOutput"
}

The call answers HTTP 200 even for a GSTIN with no registration behind it, so read the body, not just the status code. The registration sits under taxpayer_data: status_code is 1 for a live registration and 0 when none exists (with the reason in taxpayer_data.error, and no credit charged). Alongside it come name (the legal name), tradename, status, registrationDate, constitution and the principal address in pradr, with GSTR filing history in filing_data from the same response. The full schema is in the API documentation.

Step 4: branch on status and write the result back

Add an IF node after the HTTP Request node's success output with two conditions: {{ $json.taxpayer_data.status_code }} equals 1, and {{ $json.taxpayer_data.status }} equals Active. A status_code of 0 means the GSTIN is not registered at all and belongs on the alert path too. Both outputs lead to a write-back; only one leads to an alert.

  • Write back. A Google Sheets node with "Update Row" (or "Append or Update Row"), matching on the gstin column, writing status, legal name, registration date and the time of the check. Record the timestamp every time; a "verified" flag with no date is useless a month later.
  • Alert on Cancelled. On the false branch, add a second IF or a Switch node that separates Cancelled from Suspended, and send a Slack message for Cancelled with the GSTIN, legal name and cancellation date. Suspended usually deserves a review rather than an immediate block; the reasoning is in automated daily vendor GSTIN monitoring.
  • Webhook callers. If the trigger was a Webhook node, finish with Respond to Webhook so your application gets the status back in the same request.

Why Cancelled deserves an alert: a supplier whose registration is cancelled cannot charge GST from the cancellation date, so tax on their later invoices is not something you can take input tax credit on. That is a payment decision, and it should reach a person rather than sit in a cell.

Verifying a whole list without tripping rate limits

Point the workflow at a sheet with 3,000 existing vendors and n8n will try to push every item through the HTTP Request node as fast as it can. Pace it deliberately, using one of two approaches:

  • Loop Over Items (called Split In Batches in older versions) with a batch size of, say, 10 to 25, then the format check and HTTP Request inside the loop, then a Wait node before looping back. Simple to read and easy to tune.
  • The HTTP Request node's own Batching option (under Options), which sends a set number of items per batch with a fixed interval between batches, without a loop.

Size the pace from the per-key limit in the API documentation, leave headroom, and let Retry On Fail handle the occasional 429. Why a steady rate beats bursts and retries is covered in GST API rate limits, retries and webhooks. For a large one-off backfill it can be simpler to upload the file to bulk verification and keep n8n for new records. If your team already lives in a spreadsheet, the Google Sheets guide covers doing it without a workflow tool at all.

Cost is the same as any other integration: ₹0.50 per verification, or ₹0.40 once a single credit purchase crosses 2,500 credits, and purchased credits do not expire. On n8n Cloud, also count executions against your plan: a sheet trigger that fires once per row uses far more executions than a scheduled workflow that reads the sheet and loops over it in one run.

Retries, error outputs and an error workflow

Three layers, each catching what the one before it cannot:

  1. Retry On Fail on the HTTP Request node handles transient failures: a 429, a 502 when the upstream source is briefly unavailable, a dropped connection. Our API does not bill for an upstream 502.
  2. The error output catches what retries could not fix. A 401 means the credential is wrong and a 402 means the account is out of credits. Retrying these will not help, so write "Needs manual check" and the status code to the sheet. A GSTIN that is not registered is not an error: it comes back as a 200 with taxpayer_data.status_code set to 0, so route it on that field instead.
  3. An error workflow catches the workflow itself failing: a sheet that was renamed, a Slack token that expired. Build a small workflow starting with an Error Trigger node that posts the failed workflow's name and execution link to Slack, then select it under the main workflow's Settings → Error Workflow.

Frequently asked questions

Not as far as we are aware at the time of writing. You do not need one: the built-in HTTP Request node can call any REST API, and a GST verification call is a single GET request with one header. If a community node appears later, the workflow logic in this guide stays the same.
Create a Header Auth credential with the header name X-API-Key and your key as the value, then select it in the HTTP Request node. n8n stores credentials encrypted and keeps them out of the node parameters, so the key does not travel with an exported or shared workflow the way a hard-coded header would.
On our API, a GSTIN that fails format or check-digit validation never reaches the upstream lookup and is not billed. Filtering malformed values in a Code or IF node before the HTTP Request node is still worth doing, because it saves an execution and keeps your error path for real failures.
Use the Loop Over Items node to process the list in small batches and put a Wait node inside the loop, or use the HTTP Request node's own batching option to space requests out. Set the pace below the per-key limit published in the API documentation, and turn on Retry On Fail so an occasional 429 is retried after a pause rather than failing the run.
Yes. The HTTP Request, IF, Code, Loop Over Items and Google Sheets nodes behave the same on both. The differences are operational: on self-hosted you manage the encryption key, updates and uptime yourself, while n8n Cloud plans limit executions, so a large batch job needs to fit your plan.
Write the status back to the source record and alert a person, typically in Slack or by email. A cancelled registration means the supplier cannot legally charge GST from the cancellation date, so invoices from them need review before you pay or claim input tax credit on them.

A note on accuracy. GST rules change often. This article reflects our understanding as of 23 September 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 tool

Build it into your product

One REST call, JSON back. Get an API key and 20 free verification credits in under a minute.

Start free