Node.js — WhatsApp Data API

Node.js examples with built-in `fetch` (Node 18+) and `axios`. TypeScript-ready.

No-dependency fetch (Node 18+)

Direct proxy uses your direct-purchase key. For RapidAPI marketplace, swap base URL to https://whatsapp-data1.p.rapidapi.com AND add x-rapidapi-host header.

const BASE = "https://whatsapp-proxy.checkleaked.cc";
const HEADERS = {
  "x-rapidapi-key": process.env.WHATSAPP_API_KEY,
};

export async function lookup(number) {
  const res = await fetch(`${BASE}/number/${encodeURIComponent(number)}`, { headers: HEADERS });
  if (!res.ok) throw new Error(`Status ${res.status}`);
  return res.json();
}

const data = await lookup("13105551234");
console.log("On WhatsApp:", data.isWAContact);
console.log("Business:", data.isBusiness);
console.log("About:", data.about);

Axios (any Node version)

import axios from "axios";

const api = axios.create({
  baseURL: "https://whatsapp-proxy.checkleaked.cc",
  headers: { "x-rapidapi-key": process.env.WHATSAPP_API_KEY },
  timeout: 10_000,
});

// RapidAPI marketplace variant:
// const api = axios.create({
//   baseURL: "https://whatsapp-data1.p.rapidapi.com",
//   headers: {
//     "x-rapidapi-key":  process.env.RAPIDAPI_KEY,
//     "x-rapidapi-host": "whatsapp-data1.p.rapidapi.com",
//   },
// });

async function lookup(number) {
  const { data } = await api.get(`/number/${number}`);
  return data;
}

async function bulkCheck(numbers) {
  const { data } = await api.post("/bulk_check", { numbers });
  return data; // ARRAY of BulkCheckItem (see TypeScript types below)
}

Concurrent lookups with concurrency cap

import pLimit from "p-limit";

// MEGA tier supports 4 req/sec; lower tiers cap at 2.
const limit = pLimit(2);

async function lookupMany(numbers) {
  const tasks = numbers.map((n) => limit(() => lookup(n)));
  return Promise.all(tasks);
}

const results = await lookupMany([
  "13105551234",
  "447911123456",
  "34612345678",
]);

TypeScript response types (live shape)

// GET /number/{number} response
export interface WhatsAppEntry {
  number: string;
  phone?: string;            // formatted with leading +
  countryCode?: string;
  type?: string;             // e.g. "FIXED_LINE_OR_MOBILE"
  about?: string | null;
  isWAContact: boolean;
  isUser: boolean;
  isBusiness: boolean;
  isGroup: boolean;
  isBlocked?: boolean;
  isMyContact?: boolean;
  isEnterprise?: boolean;
  isVerified?: boolean;
  id: { server: string; user: string; _serialized: string };
  businessProfile?: Record<string, unknown>;
  // profilePic is an object, NOT a URL string
  profilePic: { success: false; image_status: string } | { success: true; url: string };
  date?: string;
  cached?: boolean;
  // Present on lookup misses
  error?: string;
  exists?: boolean;
  reason?: string;
  status?: number;
}

// POST /bulk_check returns an ARRAY of these
export interface BulkCheckItem {
  success: boolean;
  number: string;
  hasWhatsapp: boolean;      // note: lowercase 'a'
  isBanned: boolean;
  formatted: string;
  country: string;
  countryCallingCode: string;
  nationalNumber: string;
  isPossible: boolean;
  isValid: boolean;
  type: string;
  error?: string;
  db: boolean;
}

// Short error envelope (auth / 429)
export interface ApiError { error: string; }

429 / retry handling with axios-retry

import axios from "axios";
import axiosRetry from "axios-retry";

const api = axios.create({
  baseURL: "https://whatsapp-proxy.checkleaked.cc",
  headers: { "x-rapidapi-key": process.env.WHATSAPP_API_KEY },
});

axiosRetry(api, {
  retries: 5,
  retryDelay: axiosRetry.exponentialDelay,
  retryCondition: (err) => {
    const s = err.response?.status;
    return s === 429 || (s >= 500 && s < 600);
  },
});

Related

What Our Users Say

Real reviews from our satisfied customers

4.5/5 (162 reviews)