Most vendor fraud does not need a sophisticated attacker. It needs a vendor master that accepts whatever a form says. A GSTIN copied from a real company, a bank account that belongs to someone else, a "change of bank details" email that looks routine: each of these succeeds because nobody checked the number against a source before the payment run. A vendor verification API closes that gap by checking, at the moment a vendor is created or changed, that the PAN, GSTIN, MSME registration and bank account in the form exist, are active and belong together. This page is for finance, procurement and platform teams who want to build that check into the vendor master and keep it running.
The scope is deliberately narrow. These checks tell you what a registry or bank says about a number you supply. They do not tell you whether a vendor can deliver, whether its prices are fair or whether its owners are honest, and they are not a substitute for your procurement policy or for advice from your tax and legal advisers.
Key takeaways
- Put the check where vendors enter or change: the onboarding form and the bank-detail change request. Those two events carry most of the risk.
- A solid default is PAN, then GSTIN (or CIN for a company), then a bank-account check, with Udyam for suppliers who claim micro or small status. Cross-check that the PAN inside the GSTIN matches the PAN on the form before you spend a single paid call.
- Block payment, not onboarding. Let a vendor be created in a pending state, and let the payment system refuse any vendor whose checks are incomplete.
- A bank-detail change is a new vendor event. Re-verify the account and require a second approver, no matter how routine the email looks.
valid: falseandfound: falseare completed, billable answers. Do not loop them. Retry only 429 and 502 with a cap.- Re-verification is a risk-tiered schedule, not a blanket annual job: spend where spend and risk are highest.
- Per vendor, the core three-check flow costs a few rupees at the published rates; the cost tables below show the arithmetic from the rate card for three onboarding volumes and a one-off backfill.
Where vendor errors and fraud actually come from
Before choosing endpoints, list the failure modes your control has to stop. In practice they cluster into five.
Borrowed identity. A vendor quotes a real GSTIN or PAN that belongs to a different business. The documents attached look plausible, because they were copied.
Shell or dormant entities. The registration exists but the business does not trade, or its registration has been cancelled or suspended and nobody noticed.
Account substitution. The vendor is genuine, the account is not. An emailed change of bank details redirects the next payment to a fraudster's account.
Honest typing errors. A transposed digit in an account number sends money to a stranger. This is far more common than fraud and just as expensive to recover.
Misclassified suppliers. A vendor claims micro or small status for payment-term reasons, or lacks a registration you assumed it held, and your payables process then treats it wrongly.
Each of these maps to a check you can automate, which is why a four-field verification at creation time pays for itself so quickly. The mapping is the next section.
What the vendor master should verify
| Risk | Check | Endpoint | What you compare |
|---|---|---|---|
| Borrowed identity | PAN belongs to the declared name | POST /v1/verify/pan | registeredName, nameMatchScore, type against the legal name on the form |
| Borrowed or cancelled registration | GSTIN exists and is active | POST /v1/verify/gstin | registrationStatus, legalName, tradeName, principalPlaceOfBusiness |
| Company status | Entity is incorporated and active | POST /v1/verify/cin | companyStatus, cinStatus, directors |
| MSME claims | Udyam number exists | POST /v1/verify/udyam | found, udyamStatus, organizationType |
| Hidden registrations | What else is linked to this PAN | POST /v1/verify/pan-to-gstin | list of GSTINs, their states and statuses |
| Account substitution, typos | Account is real and in the vendor's name | POST /v1/verify/bank-account | valid, accountStatus, nameAtBank, nameMatchScore |
Not everything on that list is needed for every vendor. A one-off freelancer paid below your GST threshold may only need PAN and bank. A regular supplier of goods will need a GSTIN. A company will need a CIN. Your tiers, below, decide.
Free checks you should run before any paid call
A GSTIN is not an opaque number. Its fifteen characters begin with a two-digit state code, followed by the ten-character PAN of the taxpayer, then an entity number for registrations under that PAN in the state, a default letter, and a check character. That structure gives you three free checks.
First, the pattern: fifteen characters in the right shape. Second, the PAN inside positions three to twelve must equal the PAN on the form. Third, the state code must be consistent with the state in the vendor's declared address, with the caveat that a business can hold registrations in several states and a head office can sit in a different state from the registration you were given. These checks catch typos and many crude fabrications before the network is involved.
The same applies to the PAN itself: ten characters, five letters, four digits, a letter, and a fourth character that indicates the holder type (for example, a company or a firm instead of an individual). A "company" vendor whose PAN says individual deserves a question. IFSC codes have eleven characters, with a zero in the fifth position, and account numbers are numeric and typically nine to eighteen digits long for this endpoint. The endpoints reject malformed input with a 400; catching it first is simply faster and free.
The onboarding workflow, step by step
The sequence below is for a regular goods or services supplier with a GST registration. Drop steps for simpler vendors.
- Vendor submits the form. Collect legal name, trade name, PAN, GSTIN (or CIN), declared state, Udyam number if claimed, and bank account details with IFSC. Collect consent text for the checks if your privacy notice requires it. Decision: nothing paid yet; the vendor record is created in a "pending verification" state.
- Normalise and run the free checks. Upper-case and trim, check patterns, check that the PAN inside the GSTIN equals the PAN field. Decision: send the form back with a precise error, or continue.
- Verify the PAN with the legal name.
POST /v1/verify/panwithpanandname. Decision:valid: falsestops the process; a weak score goes to review;typethat contradicts the declared entity type goes to review. - Verify the registration.
POST /v1/verify/gstinwithgstinandbusinessName. The response has no match score, so comparelegalNameandtradeNamewith your normalised form data yourself. Decision:registrationStatusnot active stops the vendor for goods-and-service supply that relies on tax invoices; names that cannot be explained go to review. - For a company, verify the CIN.
POST /v1/verify/cin. Decision:companyStatusandcinStatusthat are not active stop the process; the directors list gives your reviewer names to recognise. - For a claimed MSME, verify Udyam.
POST /v1/verify/udyam. Decision:found: falseor a status that is not active means the claim cannot be recorded; mark the vendor as non-MSME for payables until a document resolves it. - Cross-check linked registrations. Optionally call
pan-to-gstinto see all GSTINs for the PAN. Decision: a registration that the vendor did not mention but that is cancelled may be benign or may be a flag; send to review. - Verify the bank account.
POST /v1/verify/bank-accountwithaccountNumber,ifscand the vendor's legal name. Decision: release for payment only if the account is valid and the name score clears your threshold. - Approve and activate. When every required check for the vendor's tier is complete, a reviewer or a rule activates the vendor and the payment system will now accept it.
- Write the evidence. Store
referenceId, time, key response fields and decision per check, linked to the vendor id.
Sample request and response: the GSTIN step
This is the call where the response differs from PAN and bank in an important way: it carries facts, not a score, so the comparison is your code's job.
curl -X POST "https://api-b2b.stampmitra.in/v1/verify/gstin" \
-H "Authorization: Bearer $STAMPMITRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"gstin":"07AAAAA1111A1Z1","businessName":"Jane Doe Enterprises"}'{
"referenceId": "SMV-20260927-9K21P4",
"GSTIN": "07AAAAA1111A1Z1",
"valid": true,
"legalName": "Jane Doe Enterprises Private Limited",
"tradeName": "Jane Doe Enterprises",
"registrationStatus": "Active",
"principalPlaceOfBusiness": "123, MG Road, Bengaluru, Karnataka, 560001",
"message": "GSTIN Exists"
}| Field | Meaning | Use in the vendor master |
|---|---|---|
valid | The GSTIN resolved | false stops the flow; store the referenceId |
legalName | Name on the registration | Compare with the legal name on the form, after normalising |
tradeName | Trading name | A match here is acceptable when the legal name differs only in the suffix |
registrationStatus | Active, or something else | Anything other than active needs a decision, never a silent pass |
principalPlaceOfBusiness | Registered address | Compare state and city with the declared address |
referenceId | StampMitra transaction id | Store it; it ties your record to the call |
The comparison below is a reasonable starting point in Python. It strips company suffixes and punctuation, then compares token sets so that word order and a missing "Private Limited" do not cause false mismatches. Tune it with your own data.
import re
SUFFIXES = {"private", "pvt", "limited", "ltd", "llp", "and", "co", "company", "the"}
def tokens(name: str) -> set[str]:
words = re.sub(r"[^a-z0-9 ]", " ", name.lower()).split()
return {w for w in words if w not in SUFFIXES}
def names_agree(form_name: str, legal_name: str, trade_name: str = "") -> str:
form = tokens(form_name)
best = 0.0
for candidate in (legal_name, trade_name):
cand = tokens(candidate)
if form and cand:
best = max(best, len(form & cand) / len(form | cand))
if best >= 0.8:
return "agree"
if best >= 0.5:
return "review"
return "disagree"Decision table: valid, mismatch, inactive, not found
| Outcome | PAN | GSTIN or CIN | Udyam | Bank account |
|---|---|---|---|---|
| Valid and consistent | Record; continue | Record; continue | Mark as MSME, record the type | Mark account verified; allow payment |
| Valid, name mismatch | Review with both names | Review; many vendors trade under a different name | Review the enterprise name | Hold payment; confirm with the vendor on a known channel |
| Inactive, cancelled or lapsed | Stop; vendor must fix the PAN status | Stop for tax-invoice suppliers; ask for current status | Do not record as MSME | Do not pay; request another account |
Not found or valid: false | One re-entry, then stop | One re-entry, then request documents | Treat as non-MSME until proven | One re-entry, then hold; never guess digits |
| Call failed | Pending; retry | Pending; retry | Pending; retry | Pending; payment stays blocked |
The bank-detail change problem
Most losses to vendor fraud come through changed bank details rather than new vendors, because an existing vendor already has trust and a payment history. Treat any change of account as a new-vendor event with a few extra rules.
Run the bank-account check on the new account before it is accepted, with the vendor's legal name. If the name at the bank does not match well, do not activate the change. Require the request to come through the vendor portal or be confirmed by a call-back to a number already on file, not to a number in the email that asked for the change. Require a second approver who did not enter the request. Put a short cooling-off window between approval and the first payment to the new account, so that a payment run does not pick up a change made minutes earlier. And keep the old account on record, marked inactive, so that an investigation can see what changed and when.
None of these steps is expensive. The verification call costs the flat bank-account rate on every plan; the cooling-off window and the call-back cost a little time and nothing else.
Re-verification: a schedule by risk, not a calendar
A vendor verified once is not verified forever. A GST registration can be cancelled, a company can be struck off, and an account can be closed. But re-running everything on every vendor each year is wasteful. Tier the vendors.
- Tier 1: high spend or critical supply. Re-verify registration status and company status at a short interval you choose, and verify the bank account on any change. These are the vendors whose failure stops your operations or whose payments are large.
- Tier 2: regular suppliers. Re-verify registration status once a year, or at contract renewal, and bank account only on change.
- Tier 3: occasional or small vendors. Verify at onboarding. Re-verify only when they are reactivated after a long gap or when their spend crosses a tier boundary.
Add event triggers on top of the calendar: a returned payment, a mismatch noticed by AP staff, a change of authorised signatory, or an adverse note from a buyer. Each event reopens the checks that apply.
Migrating an existing vendor base
Most teams start with thousands of vendors already in the system. A backfill is a batch job with three constraints: rate limits, cost and resumability.
Per-endpoint rate limits apply (the documented error example is 60 requests per 60 seconds; read your own limits from the dashboard and the pricing page, since they depend on the plan). Run the batch with a small worker pool and a pacing delay, back off on 429, and stop if the 402 wallet error appears. Make the job resumable by writing each result to a table keyed by vendor id and check, so a restart skips what is done. Order the batch by tier so that the highest-risk vendors are checked first, and review the first few hundred results manually before you tighten any rule.
const BASE = "https://api-b2b.stampmitra.in";
const headers = {
Authorization: `Bearer ${process.env.STAMPMITRA_API_KEY}`,
"Content-Type": "application/json",
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function call(path, body, attempt = 0) {
const res = await fetch(`${BASE}${path}`, { method: "POST", headers, body: JSON.stringify(body) });
if (res.status === 402) throw new Error("WALLET_EMPTY");
if ((res.status === 429 || res.status === 502) && attempt < 4) {
await sleep(1000 * 2 ** attempt + Math.random() * 500);
return call(path, body, attempt + 1);
}
return { status: res.status, body: await res.json() };
}
export async function backfill(vendors, saveResult, alreadyDone) {
for (const v of vendors) {
if (alreadyDone(v.id, "gstin")) continue;
const out = await call("/v1/verify/gstin", { gstin: v.gstin, businessName: v.legalName });
await saveResult(v.id, "gstin", out);
await sleep(1100); // stay inside the documented per-minute window
}
}Designing the vendor portal so verification is cheap and polite
Many teams let vendors self-register through a portal. Done well, the portal does most of the data cleaning before a single paid call is made.
Validate as the vendor types, with patterns and the PAN-in-GSTIN rule, and show a plain message ("the PAN inside this GSTIN does not match the PAN you entered") instead of a generic failure. Make the vendor confirm the legal name exactly as it appears on the registration, and tell them that bank details must be for an account in that name. Do not call a paid endpoint on every keystroke or on a "check" button that can be pressed repeatedly: call once on submit, and keep the result with the submission so that a refresh does not call again. If the vendor has to correct a field, re-run only the checks that depend on that field. A corrected account number needs a new bank check; a corrected phone number needs nothing.
Never prefill editable form fields with the registry's response in a way that lets the vendor overwrite what you verified. Store the verified values in separate columns from the declared values, so a reviewer can always see both, and so the declared value cannot quietly become the verified one.
Rate limiting and abuse belong in your gateway. An open registration form that triggers paid calls can be driven by a script to drain your wallet, so require a verified email or mobile number before the checks run, limit attempts per vendor and per IP, and alert on unusual volume.
Proprietors, partnerships and companies: what changes
The same form serves very different legal entities, and the right checks differ.
A sole proprietor is an individual trading under a name. The PAN is the individual's, the GSTIN (if any) shows the proprietor's name as legal name and the shop name as trade name, and the bank account is often a personal one. Expect the PAN type to say individual, and expect the bank name to match the individual, not the shop. For these vendors the bank-name comparison should be against the proprietor's name, and the trade name is just a label.
A partnership firm or an LLP has its own PAN, with a fourth character that differs from an individual's. The account should be in the firm's name. There is no CIN-style endpoint for an LLP on this platform, so the evidence for an LLP comes from the PAN, the GSTIN and the bank account, plus whatever documents your policy asks for, such as the registration certificate.
A company has a CIN, and the CIN call returns its status and directors. The directors list is useful to your reviewers for recognising the people behind the vendor, and for checking that the person who signed the vendor form is connected to the company. It does not prove that person's authority to bind the company, which is a document question.
Trusts, societies and government bodies follow their own rules and often have no GSTIN. Route them through a manual path rather than forcing them through a flow built for companies.
What auditors and internal control teams usually ask
If your vendor controls are reviewed, the questions tend to be the same. How do you know the vendor exists? Show the check and its transaction id. How do you stop a changed account being used for fraud? Show the bank-change rule, the second approver and the cooling-off period. Who can override a failed check? Show the role, the reason field and the log. How do you know a vendor was still active last year? Show the re-verification schedule and the exceptions it opened. How do you handle vendors you verified before the control existed? Show the backfill plan and its progress.
A clean evidence record answers all of these in minutes. Design it as a report you can export, not as something an engineer has to assemble under pressure.
Connecting the result to the ERP or payment run
The cleanest integration point is a payment block, not a gate on data entry. Let procurement create vendors freely, mark each as "unverified" until the required checks pass, and have the payment proposal logic exclude any vendor that is not verified or that has an open review. That way a slow verification never blocks a purchase order, and a failed verification can never be bypassed by a rushed payment run.
Keep the verification state in your own table: vendor id, check type, outcome, referenceId, decision time, decided by, and the version of the rule applied. Whatever ERP you run reads that state through whatever integration it supports. StampMitra does not push webhooks for verification results; the calls are synchronous, so your onboarding service makes them and writes the outcomes itself.
Five scenarios from an accounts-payable desk
These are hypothetical, to show how responses and rules combine.
The vendor with a real GSTIN and someone else's PAN
The form lists a GSTIN whose embedded PAN differs from the PAN field. The free check fails before any paid call. The form goes back with a precise message. Cost: nothing.
The trade-name vendor
The legal name on the registration is a long company name; the form carries the brand. The name comparison returns "review" because token overlap is moderate. The reviewer sees legalName and tradeName next to the form name, recognises the brand, and approves with a note. No second paid call was needed.
The cancelled registration
A long-standing supplier's GSTIN now returns a status that is not active during a Tier 1 re-check. The system opens an exception, flags open purchase orders, and procurement contacts the supplier. Whether to continue buying, and how to handle tax documents, is for procurement and the tax adviser, not the code.
The urgent bank change
An email asks to change the account before the next payment run. AP enters the request, the bank check on the new account returns a valid account whose nameAtBank is a different person. The change is held, the call-back goes to the number on file, and the vendor confirms they sent no such request. The event goes to the fraud log.
The proprietor with no GST
A small supplier has a PAN and a bank account but no GSTIN. The policy for sub-threshold suppliers needs only PAN and bank. Both pass, the vendor is activated in Tier 3, and a note records that no registration was required.
Review rules a finance team can copy
These are suggestions for your policy to adapt.
- Auto-activate a vendor when every check required for its tier is valid, the PAN-in-GSTIN check passes, the names agree and the bank score is above your high threshold.
- Send to review when a name comparison falls in the middle band, a type contradicts the declared entity, or a linked registration is not active.
- Hard stop on an invalid PAN, an inactive registration for a tax-invoice supplier, or an account that is not valid.
- Second approver for every bank-detail change and every override of a hard stop.
- Payment hold until the checks are complete; no exceptions by default, and any exception named and logged.
- Spend-based escalation: require procurement-head approval for new vendors whose expected annual spend is above a figure you set, and for any vendor whose bank account was changed in the last few days.
- Segregation of duties: the person who creates a vendor does not approve it and does not approve its first payment.
What to store and for how long
Keep the evidence that explains the decision: referenceId per call, timestamps, the environment of the key, masked identifiers, the response fields you used, the decision, the rule version, and who approved overrides. Do not write full PAN or account numbers into application logs. Keep a clear separation between the vendor master (operational) and the evidence store (audit).
Retention periods for vendor records come from several places: tax and accounting record-keeping requirements, company law, contract limitation considerations, and data-protection obligations for any personal data in the records (sole proprietors and directors are individuals). We cannot give you the periods. Take the question to your counsel and tax adviser, write the answer into a retention schedule and then automate deletion or archival accordingly. StampMitra's own approach to data is in its retention and deletion schedule.
What it costs: three onboarding volumes and a backfill
At the pay-as-you-go rate card, PAN, GSTIN, CIN and Udyam calls are ₹5 each (the standard band), and the bank-account check is ₹4. The Growth and Scale plans lower the standard rate and add a monthly fee, and the bank rate is the same on all of them. All amounts exclude GST at 18%.
The core vendor flow is PAN, GSTIN and bank account. A supplier who also claims MSME status adds a Udyam call.
| Plan | Cost of one vendor, PAN plus GSTIN plus bank, before GST |
|---|---|
| Pay as you go | ₹14 |
| Growth | ₹12 |
| Scale | ₹11 |
| Plan | Cost of one MSME vendor, adding Udyam, before GST |
|---|---|
| Pay as you go | ₹19 |
| Growth | ₹16 |
| Scale | ₹14.50 |
For the monthly models, assume one in four new vendors claims MSME status. At 100 new vendors a month that is 100 PAN, 100 GSTIN, 25 Udyam (225 standard calls) and 100 bank checks.
| Plan | Usage charges | Plan fee | Subtotal | GST at 18% | Total for the month |
|---|---|---|---|---|---|
| Pay as you go | ₹1,525 | ₹0 | ₹1,525 | ₹274.50 | ₹1,799.50 |
| Growth | ₹1,300 | ₹999 | ₹2,299 | ₹413.82 | ₹2,712.82 |
| Scale | ₹1,187.50 | ₹4,999 | ₹6,186.50 | ₹1,113.57 | ₹7,300.07 |
At 1,000 new vendors a month: 2,250 standard calls and 1,000 bank checks.
| Plan | Usage charges | Plan fee | Subtotal | GST at 18% | Total for the month |
|---|---|---|---|---|---|
| Pay as you go | ₹15,250 | ₹0 | ₹15,250 | ₹2,745 | ₹17,995 |
| Growth | ₹13,000 | ₹999 | ₹13,999 | ₹2,519.82 | ₹16,518.82 |
| Scale | ₹11,875 | ₹4,999 | ₹16,874 | ₹3,037.32 | ₹19,911.32 |
At 5,000 new vendors a month, as a marketplace or large buyer might see: 11,250 standard calls and 5,000 bank checks.
| Plan | Usage charges | Plan fee | Subtotal | GST at 18% | Total for the month |
|---|---|---|---|---|---|
| Pay as you go | ₹76,250 | ₹0 | ₹76,250 | ₹13,725 | ₹89,975 |
| Growth | ₹65,000 | ₹999 | ₹65,999 | ₹11,879.82 | ₹77,878.82 |
| Scale | ₹59,375 | ₹4,999 | ₹64,374 | ₹11,587.32 | ₹75,961.32 |
A one-off backfill of 20,000 existing vendors with PAN, GSTIN and bank checks is 40,000 standard calls and 20,000 bank checks. If you run it in a single month on a plan, the month looks like this:
| Plan | Usage charges | Plan fee | Subtotal | GST at 18% | Total for the month |
|---|---|---|---|---|---|
| Pay as you go | ₹2,80,000 | ₹0 | ₹2,80,000 | ₹50,400 | ₹3,30,400 |
| Growth | ₹2,40,000 | ₹999 | ₹2,40,999 | ₹43,379.82 | ₹2,84,378.82 |
| Scale | ₹2,20,000 | ₹4,999 | ₹2,24,999 | ₹40,499.82 | ₹2,65,498.82 |
Two practical readings. For a small buyer the plan fees outweigh the lower rates, so stay on pay as you go until your monthly usage makes the difference visible. For a large backfill it can be worth moving to a lower tier for the month the job runs, and a spend of this size is also the point at which a conversation about an enterprise arrangement on the contact page is sensible. The tables assume GST applies to the plan fee as well; confirm on an invoice. Usage is recorded only after a successful response, so calls that fail with an error are not charged, while a valid: false answer is. Compare the cost with the cost of one misdirected payment, and with the staff time spent checking by hand, to see the return on your own numbers; we do not quote an industry figure.
Rollout: sandbox, pilot, production
Sandbox. Build the whole flow against the sandbox, where responses are sample data and no wallet debit happens. The sandbox responder gives a valid result for PAN SNDBX0000A and an invalid one for SNDBX9999F; for GSTIN the pair is 09SNDBX0000A1Z5 and 09SNDBX9999F1Z5, with the failing one returning a cancelled registration. Other inputs return stable but arbitrary outcomes, so do not write assertions on them. Check the current test values in the dashboard before relying on these. Test every cell of the decision table, the free checks, and the batch resume logic.
Pilot. Request production access, which depends on your organisation's KYC approval and the per-product production application, and run the onboarding flow for new vendors in one business unit while AP continues to check manually in parallel. Compare outcomes for a few weeks and write down every disagreement.
Production. Turn on the payment block for the pilot unit, then widen unit by unit. Run the backfill in tier order. Alert on wallet balance well before it runs out; see the sandbox versus production keys guide for keys, scopes and the IP allowlist.
Metrics worth watching
- Share of vendors activated without human review, by tier.
- Review queue size and the age of the oldest item.
- Hard stops by reason: invalid PAN, inactive registration, invalid account, name disagreement.
- Bank-detail change requests, how many were held, how many were later confirmed as genuine.
- Vendors with an open exception that still received payment. This should be zero by construction; if it is not, the payment block is leaking.
- Re-verification coverage per tier, against your schedule.
- Calls per vendor. More than the expected count means duplicate submissions or retry loops.
Mistakes that weaken a vendor check
- Verifying once and trusting forever. Statuses change.
- Checking the vendor, not the account. Most fraud is in the account.
- Matching names with exact equality. Suffixes and trade names make that useless.
- Treating a GST registration as proof of a real business. It shows a registration exists in a status, not that goods exist.
- Letting urgency bypass the process. The urgent request is the typical attack.
- No segregation of duties. One person who creates, approves and pays defeats the control.
- Logging full identifiers. Keep them out of application logs.
- Ignoring the type of PAN. A company that quotes an individual PAN is worth a question.
API reference at a glance
PAN
POST /v1/verify/panRequest parameters
| Field | Type | Description |
|---|---|---|
Authorizationrequired | header | Bearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted. |
panrequired | string | PAN, format ABCDE1234F. |
name | string | Name to match against records (max 256 chars). |
POST /v1/verify/pan{
"referenceId": "SMV-20260927-8F42K7",
"pan": "ABCDE1234F",
"type": "Individual",
"valid": true,
"registeredName": "RAHUL KUMAR",
"fatherName": "SURESH KUMAR",
"panStatus": "VALID",
"panStatusCode": "E",
"panStatusDescription": "Existing and valid PAN",
"nameMatchResult": "MATCH",
"nameMatchScore": "100",
"aadhaarSeedingStatus": "y",
"aadhaarSeedingStatusDescription": "Aadhaar linked",
"lastUpdatedAt": "2023-04-01",
"message": "PAN is Valid"
}POST /v1/verify/panPAN: ₹5 per successful call, pay-as-you-go (lower on Growth and Scale).
GSTIN
POST /v1/verify/gstinRequest parameters
| Field | Type | Description |
|---|---|---|
Authorizationrequired | header | Bearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted. |
gstinrequired | string | 15-character GSTIN, format 07AAAAA1111A1Z1. |
businessName | string | Business (legal or trade) name to cross-check against the registration. |
POST /v1/verify/gstin{
"referenceId": "SMV-20260927-9K21P4",
"verificationId": "VRF-4M8Q2T7XB9KD",
"gstin": "29AAICP2912R1ZR",
"GSTIN": "29AAICP2912R1ZR",
"valid": true,
"legalNameOfBusiness": "UJJIVAN SMALL FINANCE BANK LIMITED",
"tradeNameOfBusiness": "UJJIVAN SMALL FINANCE BANK",
"centerJurisdiction": "I-A RANGE",
"stateJurisdiction": "GUWAHATI - A - 1",
"dateOfRegistration": "2017-09-30",
"constitutionOfBusiness": "Public Limited Company",
"taxpayerType": "Regular",
"gstinStatus": "Active",
"lastUpdateDate": "2022-03-01",
"natureOfBusinessActivities": [
"Retail Business",
"Supplier of Services",
"Recipient of Goods or Services",
"Office / Sale Office",
"Others"
],
"principalPlaceAddress": "First Floor 3512-DISPUR Prithivi Mansion opp. KFC building G.S. Road, Lachit Nagar Assam 781007",
"principalPlaceSplitAddress": {
"buildingName": "Prithivi Mansion",
"street": "G.S. Road",
"location": "Lachit Nagar",
"buildingNumber": "3512-DISPUR",
"district": "Guwahati",
"state": "Assam",
"city": "Dispur",
"flatNumber": "First Floor",
"latitude": "26.1445",
"longitude": "91.7362",
"pincode": "781007"
},
"additionalAddresses": [
{
"address": "Mirza Santipur NH-37 Dist-Kamrup Rural PS-Palashbari, PO Mirza Kamrup Assam 781125",
"splitAddress": {
"buildingName": "",
"street": "NH-37",
"location": "Santipur, Mirza",
"buildingNumber": "",
"district": "Kamrup Rural",
"state": "Assam",
"city": "Palashbari",
"flatNumber": "",
"latitude": "26.0926",
"longitude": "91.5069",
"pincode": "781125"
}
},
{
"address": "N.A.C.C.I. Foundation 3559-Tezpur CHAMBER BHAWAN Binjraj Road, P. o. and P.S. - Tezpur, Dist. Binjraj Road, P. o. and P.S. - Tezpur, Dist. Sonitpur Assam 784154",
"splitAddress": {
"buildingName": "CHAMBER BHAWAN",
"street": "Binjraj Road",
"location": "Tezpur",
"buildingNumber": "3559-Tezpur",
"district": "Sonitpur",
"state": "Assam",
"city": "Tezpur",
"flatNumber": "",
"latitude": "26.6338",
"longitude": "92.8006",
"pincode": "784154"
}
}
],
"message": "GSTIN Exists",
"legalName": "UJJIVAN SMALL FINANCE BANK LIMITED",
"tradeName": "UJJIVAN SMALL FINANCE BANK",
"registrationStatus": "Active",
"principalPlaceOfBusiness": "First Floor 3512-DISPUR Prithivi Mansion opp. KFC building G.S. Road, Lachit Nagar Assam 781007"
}POST /v1/verify/gstinGSTIN: ₹5 per successful call, pay-as-you-go (lower on Growth and Scale).
Bank Account
POST /v1/verify/bank-accountRequest parameters
| Field | Type | Description |
|---|---|---|
Authorizationrequired | header | Bearer <api-key> (e.g. sk_test_... in sandbox, sk_live_... in production). The x-api-key header is also accepted. |
accountNumberrequired | string | 9-18 digit numeric bank account number. |
ifscrequired | string | 11-character IFSC code, e.g. ICIC0001234. |
name | string | Beneficiary name to match. |
phone | string | Account holder's 10-digit Indian mobile number, when available; improves match confidence. |
POST /v1/verify/bank-account{
"referenceId": "SMV-20260927-3B71A0",
"valid": true,
"nameAtBank": "RAVI KUMAR",
"bankName": "ICICI Bank",
"utr": "017952100012345",
"city": "Mumbai",
"branch": "Andheri West",
"micr": "400229002",
"nameMatchScore": "100",
"nameMatchResult": "GOOD_MATCH",
"accountStatus": "ACCOUNT_IS_VALID",
"accountStatusCode": "1",
"ifscDetails": {
"bank": "ICICI Bank",
"ifsc": "ICIC0001234",
"micr": "400229002",
"address": "Andheri West, Mumbai",
"city": "Mumbai",
"state": "Maharashtra",
"branch": "Andheri West"
}
}POST /v1/verify/bank-accountBank Account: ₹4 per successful call, pay-as-you-go (lower on Growth and Scale).
Frequently asked questions
Which checks should every new vendor go through?
At minimum a PAN check with the legal name and a bank-account check in the same name. Suppliers who issue tax invoices add a GSTIN check, companies add CIN, and suppliers claiming micro or small status add Udyam. Your tiers and policy decide who needs what, so write them down.
Why verify the bank account if the GSTIN is valid?
A valid GSTIN proves a registration exists, not that the account on the form belongs to that business. Most vendor fraud and many honest errors happen in the account number, so a bank-account check with a name comparison is the control that protects the payment itself.
How do we handle a vendor who asks to change bank details?
Treat it as a new-vendor event. Verify the new account with the legal name, confirm the request by a call-back to a number already on file, require a second approver, add a short cooling-off period before the first payment, and keep the old account on record as inactive.
Can we check the PAN inside a GSTIN without calling the API?
Yes. A GSTIN contains the taxpayer's PAN in positions three to twelve, so you can compare it with the PAN on the form locally, for free. Do the same for pattern and, with care, the state code, before spending any paid call.
Should onboarding be blocked until verification finishes?
Block payment rather than onboarding. Let procurement create the vendor in a pending state and have the payment proposal exclude vendors that are unverified or have an open review. That keeps purchasing moving and ensures no payment can bypass the checks.
How often should vendors be re-verified?
Use risk tiers. High-spend or critical vendors are re-checked on a short interval you choose, regular suppliers annually or at contract renewal, and occasional vendors only on reactivation. Add event triggers such as returned payments, signatory changes or mismatches noticed by staff.
What does it cost to verify one vendor?
The core flow of PAN, GSTIN and bank account costs the sum of the two standard calls and one bank-account call at your plan's rates, and an MSME vendor adds a Udyam call. The page shows the arithmetic for each plan before 18 percent GST.
Do verification calls retry automatically if the source is down?
No, you decide. Retry 429 and 502 with capped, jittered backoff, keep the vendor in a pending state during the outage, and never retry a valid false or found false answer, because those are completed, billable results that would simply return again.
How do we migrate thousands of existing vendors?
Run a resumable batch with a small worker pool, pacing inside the endpoint's rate limit, results saved per vendor and check, and an order by risk tier. Stop on a 402 wallet error, review the first few hundred results by hand and only then tighten rules.
Is a verified vendor a safe vendor?
No. The checks confirm that identifiers exist, are active and match a name. They do not assess delivery capability, financial health, prices or integrity, and they do not replace your procurement due diligence or advice from your tax and legal advisers.
Sources
- StampMitra verification API reference, pricing page and sandbox documentation on developer.stampmitra.in (read 2026-10-29).
- GSTIN structure (state code, PAN, entity number, default letter, check character) as described in the GST Common Portal's published guidance on the GSTIN format at gst.gov.in (general structure only, written from general knowledge in 2026 and not re-checked against the portal for this page; confirm before you build rules on it).
- Income Tax Act and MSMED Act provisions on payment timelines to micro and small enterprises: general reference only and not independently verified for this page in 2026; confirm the current text and your obligations with your tax adviser.
- StampMitra Developer Data Retention and Deletion Schedule.