Developer Hub

API Documentation

Overview

Everything you need to call BankPay APIs's provider-backed APIs from your own systems.

Every API is reached under a common base URL and shares the same authentication scheme (see Authentication below). Each API is documented as its own section further down this page — start with BIN Checker, Mobile Prefill - KYC and Mobile Prefill - Name Lookup, the three APIs live today.

Base path/api/v1
Content typeapplication/json for all request and response bodies
AccessRequires a BankPay APIs-issued API key & secret — see the Developer Hub's how to get access steps

Response envelope

Every endpoint returns the same JSON envelope, camelCase throughout. The actual result of the call — the fields documented per endpoint below — sits under data.

{
  "success": true,
  "statusCode": "00",
  "message": "Success",
  "correlationId": "0HN...",
  "data": { /* endpoint-specific fields — see each API section below */ }
}
Check both "success" and "data.status" The outer success tells you the request itself was valid and authenticated. The inner data.status ("Success"/"Failed") tells you whether the underlying lookup actually found an answer — a request can be success: true at the envelope level while data.status is "Failed" (e.g. a BIN that doesn't resolve to any issuer). See Error Handling.

Authentication

Shared by every API on this platform — a plain API Key + API Secret pair, sent as headers.

Every request must include two headers. There is no request-signing/HMAC step and no OAuth flow — this is a deliberate choice: every call is over HTTPS, only IPs on your allowlist are ever accepted (see IP Allowlisting), and every request carries your own unique clientRefId, so a signed-canonical- request scheme would add integration friction without a meaningful security gain on top of TLS + IP allowlisting.

HeaderDescription
X-Api-KeyYour public API key — generate one from "API Credentials" in your merchant portal.
X-Api-SecretYour API secret, shown once at generation time. Never logged or displayed again — regenerate if lost.
Keep your secret server-side X-Api-Secret must never be sent from a browser or embedded in a mobile app — call these APIs from your own backend only.

Sample code

Each sample calls the BIN Checker endpoint. Replace the placeholder key/secret with your own.

curl -X POST "https://api.example.com/api/v1/verify/bin-check" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: your_api_key" \
  -H "X-Api-Secret: your_api_secret" \
  --data-raw '{
    "clientRefId": "REF-0001",
    "bin": "411111",
    "latitude": "12.9716",
    "longitude": "77.5946"
  }'
// Node.js (server-side only — never call this from a browser, it would
// expose your API secret to anyone viewing the page).
const https = require("https");

const body = JSON.stringify({
    clientRefId: "REF-0001",
    bin: "411111",
    latitude: "12.9716",
    longitude: "77.5946"
});

const options = {
    hostname: "api.example.com",
    path: "/api/v1/verify/bin-check",
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Content-Length": Buffer.byteLength(body),
        "X-Api-Key": "your_api_key",
        "X-Api-Secret": "your_api_secret",
    },
};

const req = https.request(options, (res) => {
    let data = "";
    res.on("data", (chunk) => (data += chunk));
    res.on("end", () => console.log(res.statusCode, data));
});
req.write(body);
req.end();
import json, requests

url = "https://api.example.com/api/v1/verify/bin-check"
headers = {
    "Content-Type": "application/json",
    "X-Api-Key": "your_api_key",
    "X-Api-Secret": "your_api_secret",
}
body = {
    "clientRefId": "REF-0001",
    "bin": "411111",
    "latitude": "12.9716",
    "longitude": "77.5946",
}

resp = requests.post(url, json=body, headers=headers)
print(resp.status_code, resp.json())
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        client.DefaultRequestHeaders.Add("X-Api-Key", "your_api_key");
        client.DefaultRequestHeaders.Add("X-Api-Secret", "your_api_secret");

        var body = "{\"clientRefId\":\"REF-0001\",\"bin\":\"411111\",\"latitude\":\"12.9716\",\"longitude\":\"77.5946\"}";
        var content = new StringContent(body, Encoding.UTF8, "application/json");

        var response = await client.PostAsync("https://api.example.com/api/v1/verify/bin-check", content);
        var responseBody = await response.Content.ReadAsStringAsync();
        System.Console.WriteLine((int)response.StatusCode + " " + responseBody);
    }
}

Error Handling

How failures are reported, and why some "failures" come back as HTTP 200.

A business-level outcome (like "this BIN could not be identified") is not the same as a request error (like "invalid credentials"). This platform distinguishes the two on purpose:

HTTP StatusMeaning
200 OKThe request itself was valid and authenticated. Check data.status to see whether the underlying lookup succeeded — a "not found" result is still a 200, and is not billed.
400 Bad RequestA required field was missing or invalid (e.g. bin isn't exactly 6 digits).
401 UnauthorizedMissing/invalid X-Api-Key or X-Api-Secret, or a revoked key.
403 ForbiddenThis request came from an IP not on your account's allowlist. See IP Allowlisting.
500 Internal Server ErrorAn unexpected error on our side. Safe to retry after a short delay.
Always check the body, not just the status code A 200 response can still mean "no result". Check data.status before treating a call as successful — see the response fields documented per API below.

IP Allowlisting Required

Two layers — one on your API key, one (optional) on the specific API.

Your API key does not work from any IP until at least one server IP is registered against it, from "API Credentials" in your merchant portal. A request from an unregistered IP is rejected with 403 Forbidden before it reaches any endpoint logic.

Separately, an individual API can carry its own IP allowlist for your account (configured by your account manager). A mismatch here is reported as a normal 200 response with data.status: "Failed" and a message explaining the call was blocked — not a 403 — since your key itself was valid.

New key, not yet whitelisted? If you've just generated a key and calls are failing with 403 Forbidden, this is almost always why — add your server IP(s) from "API Credentials" in your portal.

Test Mode

Integrate and test error handling before you ever touch a real upstream provider.

Each API key (ApiClient) is issued flagged as either Live or Test — ask your account manager for a Test key if you don't have one yet. A Test key goes through the exact same authentication and IP allowlist checks as a Live key, and the same field validation.

What's different: a Test-key call never reaches the real upstream provider and is never charged. By default it returns a generic success response; if your account has specific mock responses configured (e.g. a particular BIN or mobile number that should return a canned failure), it returns that instead — ask your account manager to set these up so you can exercise both success and failure paths deterministically.

Mobile Prefill test numbers For both Mobile Prefill - KYC and Mobile Prefill - Name Lookup, send mobileNumber: "9876543210" in Test Mode for a canned success response, or mobileNumber: "9000000000" for a canned "not found" failure. Any other number returns a generic success with an empty result.
BIN Checker test values For BIN Checker, send bin: "411111" in Test Mode for a canned success response, or bin: "000000" for a canned "not found" failure. Any other 6-digit BIN returns a generic success with an empty result.
Test transactions never touch your wallet Test-mode calls are recorded separately from live transactions and never appear in your live transaction history or affect your wallet balance.

BIN Checker Live

Look up issuer and card details for a 6-digit card BIN.

POST/api/v1/verify/bin-check

Request body

FieldTypeRequiredNotes
clientRefIdstringYesYour own unique reference for this call — must be unique per call. Reusing a clientRefId from an earlier request is rejected outright (status: "Failed", not reprocessed and not replayed) — even if the earlier issue has since been fixed, use a new clientRefId to try again.
binstringYesExactly 6 numeric digits.
latitudestringNoDecimal degrees.
longitudestringNoDecimal degrees.
{
  "clientRefId": "REF-0001",
  "bin": "411111",
  "latitude": "12.9716",
  "longitude": "77.5946"
}

Response — data fields

FieldTypeDescription
transactionIdnumberInternal transaction reference — quote this if contacting support.
clientRefIdstringEchoes your request value.
statusstringSuccess or Failed.
responseMessagestringA short status message — the reason on failure, or a success confirmation.
chargesobjectWhat was billed for this call, on your account's rate, and your wallet balance before/after — see below. All zero/unchanged on a failed lookup.
resultobjectThe full lookup result, passed through unmodified from the network — not a hand-picked subset. See fields below.

result fields

FieldTypeDescription
issuerBankstringCard-issuing bank.
cardNetworkstringe.g. VISA, MASTERCARD, RUPAY.
cardTypestringe.g. Credit, Debit.
cardLevelstringe.g. Platinum, Classic.
isoCountryName, isoCountryA2stringIssuing country — full name and ISO 2-letter code.
issuerWebsite, issuerPhonestringIssuer contact details, when the network reports them.
cardTransferstringWhether this card supports card-to-card transfer, per the card network.

charges fields

FieldTypeDescription
serviceCharge, serviceChargeGSTAmount, totalChargenumberWhat was billed for this call, on your account's rate.
walletBalanceBefore, walletBalanceAfternumberYour wallet balance before/after this call.
{
  "success": true,
  "statusCode": "00",
  "message": "Success",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100123,
    "clientRefId": "REF-0001",
    "status": "Success",
    "responseMessage": "BIN found.",
    "charges": {
      "serviceCharge": 0.42,
      "serviceChargeGSTAmount": 0.08,
      "totalCharge": 0.50,
      "walletBalanceBefore": 10000.00,
      "walletBalanceAfter": 9999.50
    },
    "result": {
      "issuerBank": "HDFC Bank",
      "cardNetwork": "VISA",
      "cardType": "Credit",
      "cardLevel": "Platinum",
      "isoCountryName": "India",
      "isoCountryA2": "IN",
      "issuerWebsite": "https://www.hdfcbank.com",
      "issuerPhone": "1800-xxx-xxxx",
      "cardTransfer": "Y"
    }
  }
}
{
  "success": true,
  "statusCode": "00",
  "message": "Failed",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100124,
    "clientRefId": "REF-0002",
    "status": "Failed",
    "responseMessage": "BIN not found or could not be verified.",
    "charges": {
      "serviceCharge": 0,
      "serviceChargeGSTAmount": 0,
      "totalCharge": 0,
      "walletBalanceBefore": 9999.50,
      "walletBalanceAfter": 9999.50
    }
  }
}
{
  "success": false,
  "statusCode": "VAL001",
  "message": "\"bin\" must be exactly 6 numeric digits.",
  "correlationId": "0HN..."
}
Billing You're only charged when data.status is "Success". Validation errors, auth failures and "not found" results are never billed.

Mobile Prefill - KYC Live

Resolve the full KYC profile — name, DOB, age, gender, PAN, email, reported address history and a bureau score — linked to a mobile number.

POST/api/v1/verify/mobile-prefill

Not the same as "Mobile Prefill - Name Lookup" This returns the full KYC profile (name + email + DOB + gender). If you only need the name linked to a mobile number, see Mobile Prefill - Name Lookup instead — it's a separate, lower-cost product. Ask your account manager which one (or both) your account is enabled for.

Request body

FieldTypeRequiredNotes
clientRefIdstringYesYour own unique reference for this call — must be unique per call. Reusing a clientRefId from an earlier request is rejected outright (status: "Failed", not reprocessed and not replayed) — even if the earlier issue has since been fixed, use a new clientRefId to try again.
mobileNumberstringYes10-digit mobile number.
{
  "clientRefId": "REF-2001",
  "mobileNumber": "9876543210"
}

Response — data fields

FieldTypeDescription
transactionIdnumberInternal transaction reference.
clientRefIdstringEchoes your request value.
statusstringSuccess or Failed.
responseMessagestringA short status message — the reason on failure, or a success confirmation.
chargesobjectWhat was billed, on your account's rate, and your wallet balance before/after — see below. All zero/unchanged on a failed lookup.
resultobjectThe full KYC result, passed through unmodified from the bureau — not a hand-picked subset. See fields below.

result fields

Every field the bureau returns is forwarded as-is — this is the current field set; the bureau can add fields over time without a version bump on our side, so treat unknown fields as forward-compatible rather than an error.

FieldTypeDescription
namestringFull name on record.
dobstringDate of birth, DD-MM-YYYY.
agestringAge in years, as of the bureau's record date.
genderstringMale or Female.
panstringPAN on record, if the bureau has one linked to this mobile number.
emailstringEmail on record — an empty string if the bureau has none.
addressarrayEvery address the bureau has on record for this person, most systems return more than one historical entry — see fields below. Any individual field within an entry can be null if the bureau didn't report it for that particular record.
scorestringBureau confidence/credit score for this record.

result.address[] fields

FieldTypeDescription
first_line_of_address, second_line_of_address, third_line_of_addressstringAddress lines as reported — not always split the same way between entries.
city, statestring or nullFrequently null on older or less-structured bureau records — fall back to the address lines when absent.
postal_codestringPIN code.
country_codestringBureau-specific country code, not necessarily an ISO 2-letter code.
reported_datestringWhen the bureau recorded this address — can be an empty string if unavailable.

charges fields

FieldTypeDescription
serviceCharge, serviceChargeGSTAmount, totalChargenumberWhat was billed for this call, on your account's rate.
walletBalanceBefore, walletBalanceAfternumberYour wallet balance before/after this call.
{
  "success": true,
  "statusCode": "00",
  "message": "Success",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100301,
    "clientRefId": "REF-2001",
    "status": "Success",
    "responseMessage": "KYC record found.",
    "charges": {
      "serviceCharge": 2.12,
      "serviceChargeGSTAmount": 0.38,
      "totalCharge": 2.50,
      "walletBalanceBefore": 9997.00,
      "walletBalanceAfter": 9994.50
    },
    "result": {
      "name": "Rohit Kumar Sharma",
      "dob": "14-05-1990",
      "age": "35",
      "gender": "Male",
      "pan": "ABCPS1234D",
      "email": "",
      "address": [
        {
          "first_line_of_address": "12-3-45/A, MG Road",
          "second_line_of_address": "Indiranagar",
          "third_line_of_address": "Bengaluru",
          "city": "Bengaluru",
          "state": "Karnataka",
          "postal_code": "560038",
          "country_code": "IB",
          "reported_date": ""
        },
        {
          "first_line_of_address": "12 3 45 A MG ROAD INDIRANAGAR",
          "second_line_of_address": "BENGALURU",
          "third_line_of_address": "560038",
          "city": null,
          "state": null,
          "postal_code": "560038",
          "country_code": "IB",
          "reported_date": ""
        }
      ],
      "score": "812"
    }
  }
}
{
  "success": true,
  "statusCode": "00",
  "message": "Failed",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100302,
    "clientRefId": "REF-2002",
    "status": "Failed",
    "responseMessage": "No KYC record found for this mobile number.",
    "charges": {
      "serviceCharge": 0,
      "serviceChargeGSTAmount": 0,
      "totalCharge": 0,
      "walletBalanceBefore": 9994.50,
      "walletBalanceAfter": 9994.50
    }
  }
}
Billing You're only charged when data.status is "Success".

Mobile Prefill - Name Lookup Live

Resolve the name linked to a mobile number.

POST/api/v1/verify/mobile-prefill-with-name

Not the same as "Mobile Prefill - KYC" This is a separate, name-only lookup product — it does not return email, DOB or gender. If you need the full KYC profile, see Mobile Prefill - KYC instead. Ask your account manager which one (or both) your account is enabled for.

Request body

FieldTypeRequiredNotes
clientRefIdstringYesYour own unique reference for this call — must be unique per call. Reusing a clientRefId from an earlier request is rejected outright (status: "Failed", not reprocessed and not replayed) — even if the earlier issue has since been fixed, use a new clientRefId to try again.
mobileNumberstringYes10-digit mobile number.
{
  "clientRefId": "REF-1001",
  "mobileNumber": "9876543210"
}

Response — data fields

FieldTypeDescription
transactionIdnumberInternal transaction reference.
clientRefIdstringEchoes your request value.
statusstringSuccess or Failed.
responseMessagestringA short status message — the reason on failure, or a success confirmation.
chargesobjectWhat was billed, on your account's rate, and your wallet balance before/after — see below. All zero/unchanged on a failed lookup.
resultobjectThe lookup result — name, the resolved name linked to the mobile number.

charges fields

FieldTypeDescription
serviceCharge, serviceChargeGSTAmount, totalChargenumberWhat was billed, on your account's rate.
walletBalanceBefore, walletBalanceAfternumberYour wallet balance before/after this call.
{
  "success": true,
  "statusCode": "00",
  "message": "Success",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100201,
    "clientRefId": "REF-1001",
    "status": "Success",
    "responseMessage": "Name resolved.",
    "charges": {
      "serviceCharge": 0.85,
      "serviceChargeGSTAmount": 0.15,
      "totalCharge": 1.00,
      "walletBalanceBefore": 9999.50,
      "walletBalanceAfter": 9998.50
    },
    "result": {
      "name": "Rohit Kumar Sharma"
    }
  }
}
{
  "success": true,
  "statusCode": "00",
  "message": "Failed",
  "correlationId": "0HN...",
  "data": {
    "transactionId": 100202,
    "clientRefId": "REF-1002",
    "status": "Failed",
    "responseMessage": "No name found for this mobile number.",
    "charges": {
      "serviceCharge": 0,
      "serviceChargeGSTAmount": 0,
      "totalCharge": 0,
      "walletBalanceBefore": 9998.50,
      "walletBalanceAfter": 9998.50
    }
  }
}
Billing You're only charged when data.status is "Success".

Payouts, BBPS & More Coming soon

Payouts (IMPS/NEFT/RTGS/UPI), bank account verification, PAN verification, BBPS bill fetch/pay and recharge collections will be documented here as they're published — the same authentication, error handling and billing model described above applies to every one of them.