# GST Taxpayer Lookup | GSTIN Verification, Nature of Business (`themineworks/gst-taxpayer-lookup`) Actor

Verify Indian GSTINs against the official GST portal: legal name, trade name, status, constitution, registration date, jurisdiction, and Nature of Business Activities. Solves the portal CAPTCHA with a vision model, no manual step. No result, no charge.

- **URL**: https://apify.com/themineworks/gst-taxpayer-lookup.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 gstin verifieds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GST Taxpayer Lookup | GSTIN Verification, HSN Codes, Line of Business

Verify any Indian GSTIN against the official GST portal and get back what
accounting and compliance work actually needs: legal name, trade name,
status, constitution, registration date, jurisdiction, the **HSN and SAC
codes the supplier declared**, and a **one-sentence plain-English line of
business**.

The government portal gates every lookup behind a CAPTCHA. This actor reads
it with a vision model, so a batch of 500 GSTINs needs nobody sitting there
typing codes.

### Why use this GSTIN verification actor

- **It tells you what the supplier actually sells.** Most GSTIN tools stop
  at "Retail Business", which tells you nothing. This returns the declared
  HSN codes (`71141910 ARTICLES OF GOLD`) and turns them into a readable
  line: *"trades in gold articles through wholesale and retail channels."*
  That is the difference between confirming a number and classifying a
  supplier.
- **No result, no charge.** A lookup that fails, portal down, CAPTCHA
  exhausted, malformed GSTIN, is never billed. Two other GSTIN actors on
  this store were run against the same 18 real GSTINs in August 2026: both
  returned zero usable records and both charged for every failed row.
- **Measured, not claimed.** In a batch of 50 real supplier GSTINs pulled
  from a live purchase register, **49 verified (98%)**. The one miss was
  the portal's own transient session error, on a GSTIN that verified fine
  on another run. Concurrent by default: five at a time completes a
  five-GSTIN run in about 26 seconds.
- **Re-runs are free.** A GSTIN you looked up in the last 7 days (tunable
  to 90) is served from your own cache and **is not charged again**. Point
  it at the same supplier list every month and you only pay for the
  suppliers that are new.
- **Grounded, not guessed.** The line of business is written only from the
  codes the lookup itself returned. Ask a general chatbot to describe a
  GSTIN and it will confidently invent a company; this cannot, because the
  model only ever summarises facts already fetched from the portal.

### Verify a batch of supplier GSTINs

Feed it the GSTIN column from a purchase register.

```json
{
  "gstins": ["27ABQFM7569K1Z9", "24AAWFA8982B1Z3", "23AHBPS6324B1ZT"],
  "concurrency": 5
}
```

### Classify suppliers whose name tells you nothing

"QIVO VENTURES", "Geddit", "CHIRAG COMMERCE". The HSN codes and the line of
business do the work the name cannot.

```json
{
  "gstins": ["23AHBPS6324B1ZT"],
  "describeBusiness": true
}
```

Returns electrical machinery and plastics, not the groceries the name might
suggest.

### Check a vendor before onboarding

```json
{ "gstins": ["24AAWFA8982B1Z3"] }
```

Watch `status` for `Active` and `cancellationDate` for a non-null value. A
cancelled registration still returns its full record, so you can tell a
lapsed vendor from a fake number.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `gstins` | array | required | GSTINs to verify, standard 15-character format |
| `concurrency` | integer | 5 | How many to look up at once (1 to 10) |
| `maxAttempts` | integer | 6 | CAPTCHA retries per GSTIN. Costs time on a misread, never money |
| `describeBusiness` | boolean | true | Add the one-sentence line of business |
| `cacheMaxAgeDays` | integer | 7 | Reuse a recent result instead of re-fetching and re-charging. 0 disables |

### Output

One record per GSTIN.

```json
{
  "gstin": "24AAWFA8982B1Z3",
  "found": true,
  "legalName": "A P GEMS",
  "tradeName": "A P GEMS",
  "status": "Active",
  "constitutionOfBusiness": "Partnership",
  "taxpayerType": "Regular",
  "registrationDate": "01/07/2017",
  "cancellationDate": null,
  "principalAddress": "4TH FLOOR, 403, DEV BHUMI APPT, ADAJAN, Surat, Gujarat, 395009",
  "natureOfBusinessActivities": ["Retail Business", "Office / Sale Office", "Factory / Manufacturing"],
  "goodsHsn": [
    { "code": "71023910", "description": "DIAMOND, CUT OR OTHERWISE WORKED BUT NOT MOUNTED OR SET" },
    { "code": "71021000", "description": "UNSORTED" }
  ],
  "servicesSac": [
    { "code": "9988", "description": "Manufacturing services on physical inputs owned by others" }
  ],
  "lineOfBusiness": "This business manufactures, tests, and sells diamonds, precious stones, and jewellery, while also providing professional technical and business services.",
  "aadhaarVerified": "Yes",
  "eInvoiceStatus": "Yes",
  "attempts": 1,
  "error": null
}
```

A failed lookup returns the same shape with `found: false` and `error` set,
and is not billed.

### FAQ

**Do I need an API key or a GSP account?**
No. This reads the public taxpayer search the GST portal already exposes.
No GSP empanelment, no subscription, no key of yours.

**What does it cost?**
**$4 per 1,000 verified GSTINs on the Free plan**, $3.60 on Bronze, $3.20
on Silver, $3 on Gold and above. No result, no charge, and a GSTIN served
from your cache inside the window is not charged at all.

**How does the cache work?**
Every verified result is written to a key-value store in your own account,
keyed by GSTIN. A later run inside `cacheMaxAgeDays` reads it back and
returns it without touching the portal and without billing you. It is your
storage, so nothing is shared between accounts. Set `cacheMaxAgeDays` to 0
when you need a guaranteed-fresh status check, for example before releasing
a large payment.

**Where does the line of business come from?**
Only from the HSN and SAC codes and the nature-of-business flags this
lookup returned. It is a summary of retrieved facts, never a guess about a
company from its name. If a supplier declared no goods or services, it says
so plainly rather than inventing an activity.

**Why do some suppliers have no HSN codes?**
Declaring goods and services at registration is not always enforced. Those
records return empty `goodsHsn` and `servicesSac`, and the line of business
says the activity is not determinable.

**Why do some lookups take more than one attempt?**
The portal returns a generic session error for a wrong CAPTCHA rather than
saying the CAPTCHA was wrong, so recovery means a fresh session and a fresh
image. `attempts` on every record tells you how many it took. Retries are
free: only a verified result is billed, so raising `maxAttempts` costs you
time on a stubborn GSTIN, never money.

**Does a cancelled GSTIN still return data?**
Yes, with `cancellationDate` populated. Useful when reconciling old
invoices against a supplier who has since deregistered.

**Can I look up by company name instead of GSTIN?**
No. The portal's public search is GSTIN-keyed.

### Point-in-time evidence

A taxpayer record is a snapshot of what the GST portal publishes at the
moment of the lookup, not a tax opinion or a compliance clearance. The line
of business is a plain-language reading of the codes the supplier declared,
which is not always the same as what they invoiced you for. Use both as
evidence to review, not as a filing decision on their own.

# Actor input Schema

## `gstins` (type: `array`):

One or more GSTINs to verify, standard 15-character format (for example 27ABQFM7569K1Z9). Malformed entries are rejected before any request is sent, so they never cost you anything.

## `maxAttempts` (type: `integer`):

The portal returns a generic session error on a wrong CAPTCHA, so recovery means a fresh session and a fresh image. Retries are free: only a verified result is billed, so a higher value costs time on a stubborn GSTIN, never money.

## `concurrency` (type: `integer`):

How many GSTINs to look up at once. Nearly all of a lookup is spent waiting on the CAPTCHA model, so raising this shortens a big batch a lot. 5 is a good default.

## `describeBusiness` (type: `boolean`):

Writes a one-sentence description of what the supplier actually deals in, generated strictly from the HSN and SAC codes this lookup returns. Facts always come from the portal; this only summarises them.

## `cacheMaxAgeDays` (type: `integer`):

A GSTIN looked up within this many days is served from your own cache and is NOT charged again. Re-run a supplier list monthly and you only pay for what is new. Set 0 to always fetch fresh.

## Actor input object example

```json
{
  "gstins": [
    "27ABQFM7569K1Z9",
    "24AAWFA8982B1Z3"
  ],
  "maxAttempts": 6,
  "concurrency": 5,
  "describeBusiness": true,
  "cacheMaxAgeDays": 7
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "gstins": [
        "27ABQFM7569K1Z9",
        "24AAWFA8982B1Z3"
    ],
    "maxAttempts": 6,
    "concurrency": 5,
    "describeBusiness": true,
    "cacheMaxAgeDays": 7
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/gst-taxpayer-lookup").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "gstins": [
        "27ABQFM7569K1Z9",
        "24AAWFA8982B1Z3",
    ],
    "maxAttempts": 6,
    "concurrency": 5,
    "describeBusiness": True,
    "cacheMaxAgeDays": 7,
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/gst-taxpayer-lookup").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "gstins": [
    "27ABQFM7569K1Z9",
    "24AAWFA8982B1Z3"
  ],
  "maxAttempts": 6,
  "concurrency": 5,
  "describeBusiness": true,
  "cacheMaxAgeDays": 7
}' |
apify call themineworks/gst-taxpayer-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/gst-taxpayer-lookup"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/c40ytaJggffpfx6hy/builds/jEVLvcR7MGFmhSO5o/openapi.json
