Early accessWe're onboarding teams in batches. The sandbox and docs are open to everyone. Request access →

Skip to content
APIserver.in
Docs menu

Endpoint

PAN Verify

PAN (+ optional name) → Valid, name match score, holder category. ₹2.00 per successful call, GST included.

POST/v1/pan/verify₹2.00 incl. GST · failed ₹0

Checks a PAN, decodes the holder category from its 4th character, and — if you pass a name — returns a 0–1 name match score with a match verdict.

Also available as the pan module of Business360.

Request

curl https://api.apiserver.in/v1/pan/verify \
  -H "Authorization: Bearer as_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pan":"AAJCK4821M","name":"Kaveri Textiles Pvt Ltd"}'
const res = await fetch("https://api.apiserver.in/v1/pan/verify", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.APISERVER_KEY ?? "as_test_YOUR_KEY"}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "pan": "AAJCK4821M",
    "name": "Kaveri Textiles Pvt Ltd"
  }),
});

const { success, data, meta, error } = await res.json();
console.log(meta.charged, meta.amount_inr); // failed calls are never charged
import os, requests

res = requests.post(
    "https://api.apiserver.in/v1/pan/verify",
    headers={
        "Authorization": f"Bearer {os.getenv('APISERVER_KEY', 'as_test_YOUR_KEY')}",
    },
    json={
        "pan": "AAJCK4821M",
        "name": "Kaveri Textiles Pvt Ltd",
    },
    timeout=10,
)
body = res.json()
print(body["meta"]["charged"], body["meta"]["amount_inr"])
<?php
$ch = curl_init('https://api.apiserver.in/v1/pan/verify');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . (getenv('APISERVER_KEY') ?: 'as_test_YOUR_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'pan' => 'AAJCK4821M',
        'name' => 'Kaveri Textiles Pvt Ltd',
    ]),
]);
$body = json_decode(curl_exec($ch), true);
echo $body['meta']['charged'] ? 'charged' : 'not charged';
Request fields
FieldTypeDescription
panrequiredstring10-character PAN. The 4th character encodes the holder type.
namestringOptional name to match against the PAN holder's name.

Response

{  : true,  : "as_req_01J9X2K7R8M4V6T2Q9W3E5Y1ZB",  : "pan.verify",  : "2026-10-01",  : {    : "AAJCK4821M",    : true,    : "Valid",    : "Company",    : "KAVERI TEXTILES PRIVATE LIMITED",    : {      : "Kaveri Textiles Pvt Ltd",      : 1,      : "match"    }  },  : {    : true,    : 2,    : 263,    : "live",    : 1,    : "2026-10-03T09:12:00+05:30",    : "live"  }}

Response fields

Response data fields
FieldTypeDescription
panstring—
validbooleanWhether the PAN exists and is active
status"Valid" | "Invalid"Status from source
categorystringHolder category decoded from the 4th character
registered_namestringName on PAN as returned by the source (partially masked for individuals)
name_matchobject | nullPresent when you send `name`
↳inputstring—
↳scorenumber0–1 similarity score
↳result"match" | "partial" | "no_match"—

Errors

Errors this endpoint can return
HTTPCodeWhat it meansRetryBilled
400VALIDATION_FAILEDSomething in the request isn't in the right shape — usually an ID with a typo or a missing field.no₹0
401AUTH_INVALID_KEYWe couldn't find a valid API key on this request.no₹0
402WALLET_INSUFFICIENT_BALANCEYour wallet doesn't have enough for this call, so we didn't run it.no₹0
404RECORD_NOT_FOUNDThe source has no record for this ID.no₹0
429RATE_LIMITEDYou sent requests faster than your key's limit.yes₹0
503PROVIDER_UNAVAILABLEAll upstream sources for this check were down, even after fallback.yes₹0
504PROVIDER_TIMEOUTThe upstream source took too long to answer.yes₹0

Try it: open in playground · product page