Verify GST numbers in Excel and Google Sheets

You have a column of GSTINs — a vendor master, a purchase register — and you want to know which are active, which are cancelled, and who they belong to. There are three ways to do it from a spreadsheet, from no code at all to a formula-style setup.

Up to 100 free lookups — they never expire. No credit card.

1. No code: upload the sheet and download a filled-in copy

The dashboard has a Bulk GSTIN Check. Upload an .xlsx file with a GSTIN column and you get the same file back with legal name, trade name, registration date, constitution, status, taxpayer type, address, monthly-or-quarterly filing frequency and the GSTR-1 and GSTR-3B filed-till dates filled in.

It reads whatever header row your file already has. A column headed "GST No.", "GSTIN" or anything containing "GST" is taken as the GSTIN column; if your sheet already has columns named like "Legal Name of Business" or "GSTIN / UIN Status" they are filled in place, and any others are appended. Every other column in your file is left untouched. A "gstinapi.in status" column is added so you can see which rows resolved.

It costs 1 credit per GSTIN that resolves with the Search option (name, status, address) or 2 credits with Profile (adds filing frequency and filed-till dates). Malformed numbers, numbers the GST network has no record of and provider errors cost nothing. A file can have up to 2,000 rows. If your data is a CSV, open it in Excel and save it as .xlsx first.

Open Bulk GSTIN Check (sign in required)

2. Google Sheets: a menu that fills in the results

This adds a "GSTIN check" menu to your sheet. Select a column of GSTINs (no header row) and it writes the status, legal name and registration date into the three empty columns to the right. Those three columns are overwritten, so leave them empty.

In your sheet choose Extensions, then Apps Script. Paste the code below. Open Project Settings, add a script property named GSTIN_API_KEY with your key as the value, and reload the sheet. Keeping the key in a script property means it never appears in a cell.

const API = 'https://www.gstinapi.in/v1/gstin/';
const MAX_ROWS_PER_RUN = 500;

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('GSTIN check')
    .addItem('Verify selected GSTINs', 'verifySelected')
    .addToUi();
}

function verifySelected() {
  const ui = SpreadsheetApp.getUi();
  const key = PropertiesService.getScriptProperties().getProperty('GSTIN_API_KEY');
  if (!key) {
    ui.alert('Add GSTIN_API_KEY under Project Settings > Script properties first.');
    return;
  }
  const range = SpreadsheetApp.getActiveRange();
  if (range.getNumColumns() !== 1) {
    ui.alert('Select one column of GSTINs (no header row).');
    return;
  }
  const rows = Math.min(range.getNumRows(), MAX_ROWS_PER_RUN);
  const gstins = range.offset(0, 0, rows, 1).getValues()
    .map(r => String(r[0]).trim().toUpperCase());
  const out = gstins.map(g => (g ? lookup(g, key) : ['', '', '']));
  range.offset(0, 1, rows, 3).setValues(out);
}

function lookup(gstin, key) {
  if (!/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/.test(gstin)) {
    return ['Invalid format', '', ''];
  }
  for (let attempt = 1; attempt <= 3; attempt++) {
    const res = UrlFetchApp.fetch(API + encodeURIComponent(gstin), {
      headers: { 'x-api-key': key },
      muteHttpExceptions: true,
    });
    const code = res.getResponseCode();
    if (code === 200) {
      const d = JSON.parse(res.getContentText()).data;
      return [d.status, d.legal_name, d.registration_date];
    }
    if (code === 429 || code === 502) {
      if (attempt < 3) Utilities.sleep(2000 * attempt);
      continue;
    }
    if (code === 404) return ['Not found', '', ''];
    if (code === 402) return ['Out of credits', '', ''];
    return ['Error ' + code, '', ''];
  }
  return ['Try again later', '', ''];
}

Google Apps Script. The first run asks you to authorise the script to connect to an external service.

A malformed GSTIN is caught before any call is made, so it never spends a credit. A 429 or 502 is retried up to three times, which is the retry policy in the API docs; a 404 means the GST network has no such registration and is never charged. Each run handles up to 500 rows, because Apps Script stops a script that runs too long — for more rows, use the upload in step 1.

Sources: Google Apps Script: custom functions and the services they can use

3. Excel: a Power Query function

Power Query can call the API once per row of a table. In Excel choose Data, Get Data, From Other Sources, Blank Query, then Advanced Editor, and paste the function below. Name the query fnGstin. To keep the key out of the query text, first add a parameter: Home, Manage Parameters, New Parameter, text type, named ApiKey, with your key as the current value.

(gstin as text) as record =>
let
    response = Web.Contents(
        "https://www.gstinapi.in",
        [
            RelativePath = "v1/gstin/" & Text.Upper(Text.Trim(gstin)),
            Headers = [#"x-api-key" = ApiKey],
            ManualStatusHandling = {400, 402, 404, 429, 502}
        ]
    ),
    parsed = try Json.Document(response) otherwise null,
    data = try parsed[data] otherwise null,
    result = [
        gstin = gstin,
        success = try parsed[success] otherwise false,
        status = try data[status] otherwise null,
        legal_name = try data[legal_name] otherwise null,
        trade_name = try data[trade_name] otherwise null,
        registration_date = try data[registration_date] otherwise null,
        error = try parsed[error] otherwise null
    ]
in
    result

Power Query M. Headers, RelativePath and ManualStatusHandling are documented Web.Contents options.

Load your GSTIN column as a table (Data, From Table/Range). Then on the Add Column tab choose Invoke Custom Function, pick fnGstin, and point it at the GSTIN column. Expand the record column that appears to get one column per field. If Excel asks about data privacy levels, set the two sources to a level that lets them combine, and choose Anonymous for www.gstinapi.in, since the key travels in the header.

One thing to know before you press Refresh: a refresh runs the lookup again for every row, and each successful lookup spends a credit. Refresh only when you want fresh data, and copy the result to a normal sheet if you want to keep it without paying again.

Sources: Microsoft Learn: Web.Contents

Frequently asked questions

Why is there no =GSTIN() formula for Google Sheets?

A cell formula is recalculated whenever the sheet reloads or the inputs change, and every recalculation would make a fresh lookup and spend a credit. A menu that writes values does the lookup once and leaves the result in the cell. That is why the script above fills values instead of defining a formula.

How many credits does verifying a spreadsheet cost?

One credit per GSTIN that resolves. Malformed numbers, numbers the GST network has no record of and provider errors are not charged. Every account gets up to 100 free lookups: 25 on signup and 25 for each of three dashboard setup steps. Credits never expire.

Can I verify more than 2,000 GSTINs at once?

The bulk upload takes up to 2,000 rows per file, so split larger files. The API itself allows 60 requests a minute per key, so a script working through a long list should pace itself and retry on a 429.

Will it tell me if a vendor has stopped filing returns?

The bulk upload fills in the GSTR-1 and GSTR-3B filed-till dates and the monthly or quarterly filing frequency, so a vendor whose last filed period is months old stands out. Through the API, the returns endpoint lists every return filed in a financial year and the compliance endpoint summarises it.

Is my API key safe in Apps Script or Power Query?

Your API key is a secret. Anyone who has it can spend your credits, so do not paste it into a file you share. In Apps Script the key sits in a script property, which is not part of the sheet. In Power Query it sits in a parameter; note that anyone you send the workbook to can read it.

Try it on your own GSTINs

Create an account and you start with 25 free lookups — up to 100 once you finish the setup steps. No card, and they never expire.

Get your free API key

Need to check a single GSTIN right now? Use the free search tool — no signup.