Engineering

WHOIS API Caching Explained: When to Use _forceRefresh (and When Not To)

WhoisJSON caches WHOIS responses for three hours by default. That keeps lookups fast and cheap — until you need live registry data. This guide shows when the cache is correct, when to send _forceRefresh=1, and how to avoid burning credits on unnecessary live queries.

September 21, 202610 min readEngineering · WHOIS Cache · Force Refresh · API Credits

Introduction

A WHOIS API call looks simple: authenticate, pass a domain, parse JSON. In production, one design choice dominates cost and correctness — whether you accept a cached response or force a live registry lookup.

WhoisJSON caches successful WHOIS responses for about three hours. Most portfolio scans, onboarding checks and scheduled monitors should use that cache. Force-refresh exists for the minority of requests where stale registry data is wrong: post-transfer verification, incident response, expiry-cliff decisions and change confirmation.

This article explains the cache contract, the_forceRefresh=1 query parameter, credit cost, decision rules, and copy-paste patterns in Python and Node.js. It complements rate limits and 429 retries — cache controls freshness; rate limits control throughput.

Why WHOIS APIs Cache Responses

WHOIS and RDAP lookups depend on upstream registries and thin clients. Caching is not a shortcut around accuracy — it is how production APIs stay fast, fair and resilient.

  • Latency. Cached JSON returns in milliseconds. Live WHOIS can take hundreds of milliseconds to several seconds depending on the TLD.
  • Upstream protection. Registries and WHOIS servers are not designed for uncontrolled polling. Caching absorbs repeated lookups for the same domain.
  • Cost predictability. Default requests consume one credit. Live force-refresh costs more because it hits the origin path.
  • Stable integrations. Bulk jobs and dashboards stay responsive when popular domains are served from cache instead of waiting on every registry round-trip.
WhoisJSON’s default WHOIS cache TTL is 3 hours. That window covers most operational needs: daily monitors, CI gates and portfolio inventories rarely need second-by-second registry truth.

How the WhoisJSON WHOIS Cache Works

On a normalGET /api/v1/whois?domain=example.com request (no force-refresh flag):

  1. The API checks Redis for a recent WHOIS payload for that domain.
  2. If a valid cache entry exists, it returns the cached JSON immediately.
  3. If not, it queries the live WHOIS/RDAP path, normalizes the response, stores it with a TTL near three hours, and returns the result.

Cached responses include the same structured fields as live responses — registrar, dates, EPP status, nameservers — so your parsers do not change. Treat cache as an acceleration layer, not a different schema.

BehaviorDefault requestWith _forceRefresh=1
Data sourceCache if fresh, else livePrefer live registry path
Typical latencyFaster (cache hit)Higher (upstream round-trip)
Credit cost1 credit2 credits
Plan availabilityAll plansPro and above
Best forScans, monitors, dashboardsIncidents, transfers, confirmations

What _forceRefresh=1 Does

Append_forceRefresh=1 to the query string to ask for live data instead of a cached payload:

GET /api/v1/whoisHTTP
GET /api/v1/whois?domain=example.com&_forceRefresh=1
Authorization: Token=YOUR_API_KEY

Important product rules (also documented on documentation and FAQs):

  • Force-refresh costs 2 credits instead of 1.
  • It is available on Pro plans and above.
  • The same parameter applies to related endpoints such as DNS (nslookup) andSSL when you need live resolution or certificate data after a change.
Do not force-refresh every request. Polling a portfolio with_forceRefresh=1 doubles credit burn and adds unnecessary load for data that rarely changes within three hours.

When the Default Cache Is Enough

Use the default cached path unless you have a concrete reason to pay for live data.

  • Daily or hourly portfolio expiry scans
  • SaaS onboarding that checks registration age or registrar once per signup
  • CI/CD domain health gates on every deploy (expiry and lock presence)
  • Security dashboards that baseline registrar, NS and EPP status
  • Bulk WHOIS enrichment where “within three hours” is acceptable truth
  • Deduplicated jobs that look up the same domain many times in one run

For high-volume enrichment patterns, see the Bulk WHOIS API product page and the bulk WHOIS guide.

When You Should Force Refresh

Force-refresh when a wrong answer from a three-hour-old snapshot would cause a bad operational decision.

  • Post-transfer verification. Confirm the gaining registrar and re-enabledclientTransferProhibited after an authorized move (see the transfer security checklist).
  • Incident / hijack triage. After an alert on lock removal or NS change, fetch live WHOIS before escalating.
  • DNS or SSL change confirmation. After a cutover, force-refreshnslookup or SSL to confirm propagation — not for every routine poll.
  • Expiry-cliff decisions. Hours before auto-renew or drop risk, prefer liveexpires over a cached date.
  • Customer support “is it done yet?” When a user just changed registrar settings and needs confirmation now.
Selective force-refresh pattern: run the portfolio on cache; only re-query with_forceRefresh=1 for domains that failed a policy check or were flagged by monitoring.

Decision Matrix: Cache vs Force Refresh

ScenarioUse cache?Force refresh?
Nightly expiry report (5,000 domains)YesNo
Same domain looked up 40 times in one jobYes (dedupe + cache)No
Alert: transfer lock missing on apexFirst look: cache OKConfirm + escalate: yes
Transfer completed 10 minutes agoNoYes
DNS cutover just pushedOptional first checkYes on verification pass
“Refresh all domains every 5 minutes”No — redesign the jobNever as a default

Common Mistakes

  • Appending_forceRefresh=1 to every client helper “just in case”.
  • Confusing cache freshness withHTTP 429 rate limits — fixing one does not fix the other.
  • Treating a cached response as “wrong” when the registry simply has not updated yet.
  • Force-refreshing Free/Basic plans expecting live data without checking plan eligibility.
  • Ignoring the 2× credit cost in budget forecasts for monitoring fleets.
  • Forgetting that DNS and SSL also support force-refresh — and burning credits on both when only one signal changed.

Python: Cached Lookup vs Force Refresh

whois_client.pyPython
import os
import requests

API_KEY = os.environ["WHOISJSON_API_KEY"]
BASE = "https://whoisjson.com/api/v1/whois"

def whois_lookup(domain: str, force_refresh: bool = False) -> dict:
    params = {"domain": domain}
    if force_refresh:
        params["_forceRefresh"] = 1

    response = requests.get(
        BASE,
        params=params,
        headers={"Authorization": f"Token={API_KEY}"},
        timeout=30,
    )
    response.raise_for_status()
    return response.json()

# Default: 1 credit, may be served from the 3-hour cache
cached = whois_lookup("example.com")

# Live path: 2 credits, Pro+ — use only when freshness matters
live = whois_lookup("example.com", force_refresh=True)

print(cached.get("registrar", {}).get("name"))
print(live.get("expires"))

Node.js: Selective Force Refresh After a Flag

whoisClient.jsJavaScript
const API_KEY = process.env.WHOISJSON_API_KEY;
const BASE = 'https://whoisjson.com/api/v1/whois';

async function whoisLookup(domain, { forceRefresh = false } = {}) {
  const url = new URL(BASE);
  url.searchParams.set('domain', domain);
  if (forceRefresh) {
    url.searchParams.set('_forceRefresh', '1');
  }

  const res = await fetch(url, {
    headers: { Authorization: `Token=${API_KEY}` },
  });

  if (!res.ok) {
    throw new Error(`WHOIS ${res.status}: ${await res.text()}`);
  }

  return res.json();
}

function transferLocked(whois) {
  const analysis = whois.statusAnalysis || {};
  if (typeof analysis.transferLocked === 'boolean') {
    return analysis.transferLocked;
  }
  const status = [].concat(whois.status || []).join(' ').toLowerCase();
  return status.includes('clienttransferprohibited')
    || status.includes('servertransferprohibited');
}

async function verifyCriticalDomain(domain) {
  // Pass 1: cheap cached check
  const cached = await whoisLookup(domain);
  if (transferLocked(cached)) {
    return { domain, source: 'cache', ok: true, whois: cached };
  }

  // Pass 2: confirm with live data before paging on-call
  const live = await whoisLookup(domain, { forceRefresh: true });
  return {
    domain,
    source: 'live',
    ok: transferLocked(live),
    whois: live,
  };
}

verifyCriticalDomain('example.com').then(console.log).catch(console.error);

Cache Freshness vs Rate Limits

Teams often mix two different failure modes. Keep them separate in logging and runbooks.

ConcernSymptomFix
Stale dataRegistrar/NS/status looks outdated after a known changeSelective_forceRefresh=1
ThroughputHTTP 429, exhausted minute quotaBackoff, concurrency caps, see rate-limits guide
Monthly budgetCredits burn too fastDefault to cache; force-refresh only flagged domains

Watch theRemaining-Requests response header on every call. Force-refresh does not bypass plan limits — it only changes freshness and credit cost per request.

FAQ

How long does WhoisJSON cache WHOIS responses?

The default cache TTL is about three hours. After expiry, the next request fetches live data and repopulates the cache.

Does _forceRefresh=1 always hit the live WHOIS server?

It requests the live path and costs 2 credits on eligible plans. Use it when you need current registry state — not as a default for every integration call.

Which plans can use force-refresh?

Force-refresh is available on Pro plans and above. See pricing for plan details and monthly quotas.

Does force-refresh work on DNS and SSL endpoints?

Yes. Add_forceRefresh=1 to nslookup and SSL requests when you need live resolution or certificate data after a change.

Should my monitor force-refresh every poll?

No. Poll on the default cache path. Force-refresh only domains that fail a policy check or that an analyst needs to confirm during an incident.

Is cache the same as rate limiting?

No. Cache controls data freshness. Rate limits control how many requests you may send per minute and per billing period. Handle both — retries for 429, selective force-refresh for staleness.

Build WHOIS Workflows Without Wasting Credits

Start with the 3-hour cache. Reserve _forceRefresh=1 for transfers, incidents and confirmations — then scale with a free API key.

Get API KeyRead the Docs
WHOIS Cache & Force Refresh

Fast by Default. Live When It Matters.

Use the 3-hour WHOIS cache for scans and monitors. Add _forceRefresh=1 only for transfers, incidents and change confirmation — without doubling every credit.

3-hour default cache_forceRefresh=1 (2 credits)Python & Node.js patterns1,000 free requests/month