BKNSWhois Lookup

BKNS Whois API

REST API for WHOIS lookup and domain availability checking.
Supports 1,260+ TLDs · .vn data from official VNNIC · Latency < 200ms

Base URLhttps://whois.bkns.vn/api/v1

All requests over HTTPS. JSON response, UTF-8 encoding.

Authentication

Attach your API key to the X-API-Key header in every request. Missing or invalid key → HTTP 401.

http
GET /api/v1/whois?domain=bkns.vn
X-API-Key: bkns_dmo_2376da23bd44858c8390aeeb93065404d21ede1ba2c5d59c0cffc33d6e83c2dd
Content-Type: application/json
Keep your API key secret. Do not embed in client-side JavaScript or mobile apps. Contact info@bkns.vn to get or rotate a key.

Demo API key — try it now

Copy the key below and paste it into the X-API-Key header to test your integration immediately — no sign-up required.

http
X-API-Key: bkns_dmo_2376da23bd44858c8390aeeb93065404d21ede1ba2c5d59c0cffc33d6e83c2dd

Demo limits: 2 requests/min and 200 requests/day per IP · Only GET /api/v1/whois and GET /api/v1/domain/check · Bulk WHOIS returns 403.

To use Bulk WHOIS or need a higher rate limit, request a Partner key at info@bkns.vn or via the admin panel.

Rate Limits

Request limits per tier. Exceeding the threshold → 429 Too Many Requests with a Retry-After header.

Public
10 req/min
Lookup via UI. No API key needed.
Demo
2 req/min
+ 200 req/day per IP
Public demo key shown on this page. Lookup-only (GET /api/v1/whois + /api/v1/domain/check).
Partner
300 req/min
Server-side integration. Contact us to get a key.
response headers
X-RateLimit-Limit:     300
X-RateLimit-Remaining:  0
X-RateLimit-Reset:      1711234567
Retry-After:           15

Error codes

200OK — SuccessProcess response normally
400Bad Request — Invalid domainValidate format before calling
401Unauthorized — Invalid or missing API keyCheck X-API-Key header
429Too Many Requests — Rate limit exceededWait per Retry-After header
500Internal Server ErrorRetry later, report if recurring
503Service Unavailable — Registry not respondingExponential backoff retry

Error envelope: v1 vs v2

v1 (legacy) returns a flat error body with errorCode. v2 (standard) wraps the error in an error object with a BKNS-WHOIS-NNN code, bilingual message, and a correlation_id for tracing.

json · v1 (legacy)
{
  "errorCode": "INVALID_DOMAIN",
  "message": "Invalid domain name",
  "statusCode": 400
}

v2 error code catalog — BKNS-WHOIS-001…014

Every v2 error carries a fixed BKNS-WHOIS-NNN code with its HTTP status. The error.details.legacyCode field (when present) is the equivalent v1 code, used as a bridge during the transition — it will be removed once every consumer reads error.code.

v2 codeHTTPMeaning (English)v1 code (legacy)
BKNS-WHOIS-001400Invalid domain nameINVALID_DOMAIN
BKNS-WHOIS-002400Request validation failedINVALID_INPUT
BKNS-WHOIS-003400Too many domains (max 10)TOO_MANY_DOMAINS
BKNS-WHOIS-004400Too many domains (max 20)TOO_MANY_DOMAINS_BULK
BKNS-WHOIS-005401API key requiredAPI_KEY_REQUIRED
BKNS-WHOIS-006403Invalid API keyINVALID_API_KEY
BKNS-WHOIS-007403Tier insufficientFORBIDDEN
BKNS-WHOIS-008429Too many requestsRATE_LIMITED
BKNS-WHOIS-009503Service temporarily unavailableALL_BACKENDS_FAILED
BKNS-WHOIS-010500An internal error occurredINTERNAL_ERROR
BKNS-WHOIS-014404Resource not foundNOT_FOUND
correlation_id is returned on every v2 error — log it and quote it to support (info@bkns.vn) for fast tracing. It's also returned as the X-Correlation-ID response header on both surfaces (v1 and v2); you may send your own inbound X-Correlation-ID and BKNS will echo it back.

API v2 & Migration

BKNS Whois API now serves two versions in parallel on the same gateway. Pick the version that fits your integration — there is no mandatory cutover.

v1 — Stable, kept indefinitely
https://whois.bkns.vn/api/v1

The original API contract. No removal plan, no deadline. Existing integrations keep working with zero changes.

v2 — Recommended for new integrations
https://whois.bkns.vn/api/v2

Same endpoints, same success response as v1 — but with a standardized error envelope and strict request validation. Use this for any new integration.

v1 → v2 migration guide

  1. 1

    Step 1 — Change the base URL

    Change /api/v1 to /api/v2. Success response bodies are 100% identical — same fields, same flat structure, no success/data wrapper — no code change needed for the success path.

  2. 2

    Step 2 — Update error handling

    Read error.code (e.g. BKNS-WHOIS-001) instead of the top-level errorCode, and error.message / error.messageEn instead of message. Use the code catalog table in the Error codes section to map; during the transition, error.details.legacyCode still carries the old code so you can match either.

  3. 3

    Step 3 — Strict requests

    v2 rejects any unknown query/body field from the very first request — a 400 BKNS-WHOIS-002, with no grace window. Send only documented parameters: domain, raw, bypass_cache (bulk: domains). Remove any stray parameters before switching to v2.

  4. 4

    Step 4 — Nothing else changes

    Authentication (X-API-Key), tier-based rate limits, and the status values (pending | registered | available | reserved | auction) are unchanged between v1 and v2. v2 shares the same rate-limit budget as v1 — switching surfaces does not reset your quota.

No deadline. v1 will never be removed — migrate whenever it's convenient for you.

GETWHOIS Lookup

Full WHOIS lookup: owner, registrar, creation/expiry dates, nameservers, EPP status.

Also available at /api/v2/whois with the standard error envelope (v2) — see the v1 → v2 migration guide

GET/api/v1/whoisWHOIS Lookup

Parameter / Type / Description

ParameterTypeDescription
domain requiredstringDomain to look up. Accepts ASCII (bkns.vn), punycode (xn--...), or Unicode IDN (münchen.de). Automatically normalizes to punycode.

Response

json · HTTP 200 · source: vnnic-relay
{
  "domain": "bkns.vn",
  "tld": "vn",
  "status": "registered",
  "cached": true,
  "cacheTtlRemaining": null,
  "data": {
    "registrant": {
      "name": "Công ty Cổ phần Giải pháp Mạng Bạch Kim"
    },
    "registrar": {
      "name": "Công ty cổ phần giải pháp mạng Bạch Kim"
    },
    "nameservers": ["ns1.bkdns.vn", "ns2.bkdns.vn", "ns3.bkdns.vn"],
    "dates": {
      "created": "2010-06-24T17:00:00.000Z",
      "updated": null,
      "expiry": "2030-06-24T17:00:00.000Z",
      "renewalDeadline": null
    },
    "domainStatus": ["clientTransferProhibited"],
    "dnssec": false
  }
}
Only for .vn: The data.registrant field is returned. International domains typically do not include registrant information.

GETDomain Check

Quickly check whether a domain is available. Faster than WHOIS as it only returns status.

Also available at /api/v2/domain/check with the standard error envelope (v2) — see the v1 → v2 migration guide

GET/api/v1/domain/checkAvailability check

Parameter / Type / Description

ParameterTypeDescription
domain requiredstringDomain to check. Accepts ASCII, punycode, or Unicode IDN. Automatically normalizes to punycode.
json · HTTP 200
{
  "domain": "example-notexist.vn",
  "tld": "vn",
  "available": true,
  "premium": false,
  "cached": false
}

.vn reserved / auction domains

json · HTTP 200 · .vn
// congchung.vn — reserved
{ "domain": "congchung.vn", "available": false, "reserved": true, "reservedBy": "Cục CNTT – Bộ Tư pháp" }

// bk.vn — auction-only (.vn 1–2 ký tự)
{ "domain": "bk.vn", "available": false, "auction": true }
For .vn: reserved (held) and auction (1–2 char, auction-only) both return available = false — NOT registrable. reserved includes reservedBy. Do not treat them as available.

POSTBulk WHOIS

Look up multiple domains in a single request. Maximum 20 domains/request. Requires Partner tier.

Note: Bulk WHOIS requires a Partner key — the demo key returns 403 on this endpoint.

Also available at /api/v2/whois/bulk with the standard error envelope (v2) — see the v1 → v2 migration guide

POST/api/v1/whois/bulkBulk lookup

Request Body

json
{
  "domains": ["bkns.vn", "google.com", "example.org"]
}

Response

json · HTTP 200
{
  "results": [
    { "domain": "bkns.vn",     "status": "registered", "data": { ... } },
    { "domain": "example.org", "status": "available" }
  ],
  "total": 3,
  "queryTime": 512
}

Response Schema

Full structure of the WHOIS response object.

Top-level fields

domainstringDomain in ASCII/punycode form (canonical key). Example: "xn--mnchen-3ya.de"
idnDomainoptionalstring | undefinedUnicode display form of an IDN domain. Only present when the domain contains internationalized labels (xn--). Example: "münchen.de". Omitted for pure ASCII domains.
tldstringTLD of the domain: "vn", "net", "com"…
status"pending" | "registered" | "available" | "reserved" | "auction"pendingregisteredavailablereservedauction
reservedByoptionalstring | undefinedThe agency holding the reserved domain (provided by VNNIC). Present only when status = "reserved".
cachedbooleanWhether the response came from cache or a live query
dataoptionalobject | undefinedOnly present when status = "registered" or "pending"
backendsTriedoptionalarray | undefinedBackends attempted, only present when cached = false

data object (registered only)

data.registrant.nameoptionalstring | undefinedOwner name. Only available for .vn domains
data.registrar.namestringRegistrar name
data.nameserversstring[]List of nameservers
data.dates.createdISO 8601 | nullDomain creation date
data.dates.expiryISO 8601 | nullDomain expiry date
data.dates.updatedISO 8601 | nullLast updated date
data.domainStatusstring[]EPP status codes: "clientTransferProhibited", "ok"…
data.dnssecbooleanDNSSEC enabled
data.autoRenewHoldoptionalobject | undefinedPresent only when a registered gTLD domain (never .vn) is detected in a registrar auto-renew hold. Optional, additive — absent entirely on all other domains.
data.autoRenewHold.level"suspected" | "confirmed""confirmed" (verified against the registrar RDAP) or "suspected" (registrar RDAP cross-check was unavailable or inconclusive; flagged on the Tier-1 heuristic only).
data.autoRenewHold.registrarstring | nullRegistrar name, taken from the registrar entity in the WHOIS/RDAP response.
data.autoRenewHold.registryExpiryISO 8601 | nullThe masked expiry (auto-renewed +1 year) as reported by registry WHOIS — identical to data.dates.expiry.
data.autoRenewHold.trueExpiryISO 8601 | nullThe REAL expiry, read directly from the registrar's RDAP. null when level = "suspected".
data.autoRenewHold.trueStatusstring | nullThe registrar's REAL status, e.g. "inactive". null when not corroborated or level = "suspected".
data.autoRenewHold.signalsstring[]Which detection signals fired, e.g. anniversary_updated_plus_1y, registrar_hold_ns.
data.autoRenewHold.source"rdap" | "heuristic""rdap" (Tier-2, confirmed via RDAP) or "heuristic" (Tier-1 fallback when cross-check wasn't possible).

Supported TLDs

1,260+ TLD types including all ccTLDs, popular gTLDs, and new gTLDs.

Domains .vn, .com.vn, .net.vn, .org.vn, .edu.vn, .gov.vn are queried directly via official VNNIC — most accurate and fastest data. Backend: vnnic-relay, latency ~145ms.

Code samples

WHOIS Lookup

javascript · Node.js 18+
const domain = 'bkns.vn';
const apiKey = 'bkns_dmo_2376da23bd44858c8390aeeb93065404d21ede1ba2c5d59c0cffc33d6e83c2dd';

const res = await fetch(
  `https://whois.bkns.vn/api/v1/whois?domain=${domain}`,
  { headers: { 'X-API-Key': apiKey } }
);

if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();

// Always check status before accessing data.*
if (data.status === 'registered') {
  console.log('Registrar:', data.data.registrar.name);
  console.log('Expires: ', data.data.dates.expiry);
  console.log('Nameservers:', data.data.nameservers.join(', '));
} else {
  console.log('Domain is not registered.');
}

Handle 429 — Retry with backoff

javascript
async function whoisWithRetry(domain, apiKey, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const res = await fetch(
      `https://whois.bkns.vn/api/v1/whois?domain=${domain}`,
      { headers: { 'X-API-Key': apiKey } }
    );
    if (res.status === 429) {
      const wait = Number(res.headers.get('Retry-After') ?? 5) * 1000;
      await new Promise(r => setTimeout(r, wait));
      continue;
    }
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  }
}

v2 example — endpoint & error envelope

The /api/v2/whois endpoint shares the same parameters as v1 (domain, raw, bypass_cache), but errors come back in the standard error envelope — see the Error codes section for the full catalog.

shell · v2
curl -s \
  "https://whois.bkns.vn/api/v2/whois?domain=bkns.vn" \
  -H "X-API-Key: bkns_dmo_2376da23bd44858c8390aeeb93065404d21ede1ba2c5d59c0cffc33d6e83c2dd" \
  | python3 -m json.tool
json · v2 (standard) · HTTP 400
{
  "success": false,
  "error": {
    "code": "BKNS-WHOIS-001",
    "message": "Tên miền không hợp lệ",
    "messageEn": "Invalid domain name",
    "details": { "legacyCode": "INVALID_DOMAIN" },
    "correlation_id": "01J8Z3K9QW7M2P5RXT6VYB4NDA"
  }
}

Contact

Need technical support or want to register a Partner API key?