
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Official Node.js & TypeScript SDK for WhizoAI - Enterprise web scraping, crawling, and AI-powered data extraction API
Official Node.js and TypeScript SDK for the WhizoAI web scraping and data extraction API.
npm install whizoai
Or with yarn:
yarn add whizoai
Or with pnpm:
pnpm add whizoai
import { WhizoAI } from 'whizoai';
// Initialize the client
const whizoai = new WhizoAI({
apiKey: process.env.WHIZOAI_API_KEY, // Get your API key from https://whizo.ai/app/api-keys
});
// Scrape a webpage
const result = await whizoai.scrape('https://example.com', {
format: 'markdown',
onlyMainContent: true,
});
console.log(result.data.content);
console.log(`Credits used: ${result.creditsUsed}`);
Get your API key from the WhizoAI Dashboard.
export WHIZOAI_API_KEY="whizo_your_api_key_here"
import { WhizoAI } from 'whizoai';
const whizoai = new WhizoAI({
apiKey: process.env.WHIZOAI_API_KEY,
});
const whizoai = new WhizoAI({
apiKey: 'whizo_your_api_key_here',
});
const result = await whizoai.scrape('https://example.com', {
format: 'markdown', // 'markdown' | 'html' | 'text' | 'json'
onlyMainContent: true,
includeScreenshot: false,
includePDF: false,
waitFor: 0, // milliseconds to wait before scraping
headers: {
'User-Agent': 'Custom User Agent',
},
});
console.log(result.data.content);
console.log(result.data.metadata.title);
console.log(`Credits used: ${result.creditsUsed}`);
const result = await whizoai.crawl('https://example.com', {
maxPages: 10,
maxDepth: 2,
allowedDomains: ['example.com'],
excludePaths: ['/admin', '/private'],
format: 'markdown',
onlyMainContent: true,
});
console.log(`Crawled ${result.data.pages.length} pages`);
result.data.pages.forEach(page => {
console.log(`${page.url}: ${page.content.substring(0, 100)}...`);
});
Extract structured data from webpages using AI:
const result = await whizoai.extract('https://github.com/anthropics', {
schema: {
companyName: 'string',
description: 'string',
mainProducts: ['string'],
teamSize: 'number',
},
model: 'gpt-3.5-turbo', // or 'gpt-4'
prompt: 'Extract information about this company',
});
console.log(result.data.extractedData);
// {
// companyName: "Anthropic",
// description: "AI safety company...",
// mainProducts: ["Claude", "Constitutional AI"],
// teamSize: 150
// }
Search the web with optional content scraping:
const result = await whizoai.search('best web scraping tools 2025', {
maxResults: 10,
scrapeResults: true, // Scrape each search result
searchEngine: 'google', // 'google' | 'bing' | 'duckduckgo'
country: 'us',
language: 'en',
});
console.log(`Found ${result.data.results.length} results`);
result.data.results.forEach(item => {
console.log(`${item.title}: ${item.url}`);
if (item.content) {
console.log(`Content: ${item.content.substring(0, 200)}...`);
}
});
Discover all URLs on a website:
const result = await whizoai.map('https://example.com', {
maxDepth: 3,
maxPages: 100,
includeSubdomains: false,
});
console.log(`Found ${result.totalUrls} URLs`);
result.data.urls.forEach(urlInfo => {
console.log(`${urlInfo.url} (depth: ${urlInfo.depth})`);
});
Process multiple URLs in parallel:
const result = await whizoai.batch({
urls: [
'https://example.com',
'https://example.com/about',
'https://example.com/contact',
],
scrapeType: 'scrape',
options: {
format: 'markdown',
onlyMainContent: true,
},
});
console.log(`Total credits used: ${result.totalCreditsUsed}`);
result.data.results.forEach((item, i) => {
console.log(`Result ${i + 1}: ${item.status}`);
if (item.data) {
console.log(item.data.content.substring(0, 100));
}
});
const jobs = await whizoai.listJobs({
limit: 20,
offset: 0,
status: 'completed', // 'pending' | 'running' | 'completed' | 'failed'
scrapeType: 'scrape', // Filter by type
});
console.log(`Found ${jobs.data.total} jobs`);
jobs.data.jobs.forEach(job => {
console.log(`${job.id}: ${job.url} - ${job.status}`);
});
const job = await whizoai.getJob('job-id-here');
console.log(`Status: ${job.data.status}`);
console.log(`Progress: ${job.data.progress}%`);
console.log(`Credits used: ${job.data.creditsUsed}`);
await whizoai.cancelJob('job-id-here');
console.log('Job cancelled successfully');
await whizoai.deleteJob('job-id-here');
console.log('Job deleted successfully');
const credits = await whizoai.getCreditBalance();
console.log(`Plan: ${credits.data.plan}`);
console.log(`Monthly credits: ${credits.data.monthlyCredits}`);
console.log(`Used this month: ${credits.data.creditsUsedThisMonth}`);
console.log(`Remaining: ${credits.data.creditsRemaining}`);
console.log(`Lifetime credits: ${credits.data.lifetimeCredits}`);
const profile = await whizoai.getUserProfile();
console.log(`Email: ${profile.data.email}`);
console.log(`Name: ${profile.data.fullName}`);
console.log(`Plan: ${profile.data.plan}`);
await whizoai.updateUserProfile({
fullName: 'John Doe',
email: 'john@example.com',
});
const usage = await whizoai.getUsageAnalytics({
startDate: '2025-01-01',
endDate: '2025-01-31',
groupBy: 'day', // 'hour' | 'day' | 'week' | 'month'
});
console.log(`Total requests: ${usage.data.totalRequests}`);
console.log(`Total credits: ${usage.data.totalCredits}`);
usage.data.breakdown.forEach(item => {
console.log(`${item.date}: ${item.requests} requests, ${item.credits} credits`);
});
const keys = await whizoai.listApiKeys();
keys.data.forEach(key => {
console.log(`${key.name}: ${key.maskedKey} (${key.isActive ? 'Active' : 'Inactive'})`);
console.log(` Last used: ${key.lastUsedAt}`);
console.log(` Usage: ${key.usageCount} requests`);
});
const newKey = await whizoai.createApiKey({
name: 'Production API Key',
scopes: ['scrape', 'crawl', 'extract'],
rateLimitPerHour: 100,
expiresAt: '2025-12-31T23:59:59Z', // Optional
});
console.log(`New API key: ${newKey.data.apiKey}`);
console.log('⚠️ Save this key - you won\'t see it again!');
await whizoai.updateApiKey('key-id-here', {
name: 'Updated Key Name',
isActive: false, // Disable the key
});
await whizoai.deleteApiKey('key-id-here');
console.log('API key deleted successfully');
const webhooks = await whizoai.listWebhooks();
webhooks.data.forEach(webhook => {
console.log(`${webhook.url} - ${webhook.events.join(', ')}`);
});
const webhook = await whizoai.createWebhook({
url: 'https://your-app.com/webhooks/whizoai',
events: ['job.completed', 'job.failed'],
secret: 'your-webhook-secret', // For signature verification
});
console.log(`Webhook created: ${webhook.data.id}`);
await whizoai.deleteWebhook('webhook-id-here');
The SDK provides structured error types for better error handling:
import {
WhizoAI,
WhizoAIError,
AuthenticationError,
ValidationError,
InsufficientCreditsError,
RateLimitError,
NetworkError
} from 'whizoai';
try {
const result = await whizoai.scrape('https://example.com');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key:', error.message);
} else if (error instanceof ValidationError) {
console.error('Invalid input:', error.details);
} else if (error instanceof InsufficientCreditsError) {
console.error('Out of credits:', error.message);
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded:', error.message);
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
} else if (error instanceof WhizoAIError) {
console.error('WhizoAI error:', error.message, error.code);
} else {
console.error('Unexpected error:', error);
}
}
For self-hosted or testing environments:
const whizoai = new WhizoAI({
apiKey: process.env.WHIZOAI_API_KEY,
apiUrl: 'http://localhost:8080', // Default: https://api.whizo.ai
});
const whizoai = new WhizoAI({
apiKey: process.env.WHIZOAI_API_KEY,
timeout: 60000, // 60 seconds (default: 30000)
});
const whizoai = new WhizoAI({
apiKey: process.env.WHIZOAI_API_KEY,
maxRetries: 5, // Default: 3
retryDelay: 2000, // Initial delay in ms (default: 1000)
});
The SDK is written in TypeScript and provides complete type definitions:
import type {
ScrapeOptions,
ScrapeResponse,
CrawlOptions,
CrawlResponse,
ExtractOptions,
ExtractResponse,
JobStatus,
UserPlan,
} from 'whizoai';
const options: ScrapeOptions = {
format: 'markdown',
onlyMainContent: true,
includeScreenshot: false,
};
const result: ScrapeResponse = await whizoai.scrape('https://example.com', options);
Check out the examples directory for more usage examples:
| Operation | Base Cost | Additional |
|---|---|---|
| Basic scraping | 1 credit | - |
| Screenshot | +1 credit | Per page |
| PDF generation | +1 credit | Per page |
| AI extraction (GPT-3.5) | 3 credits | Per page |
| AI extraction (GPT-4) | 6 credits | Per page |
| Web search | 1 credit | Per search |
| Stealth mode | +4 credits | Per page |
Rate limits vary by subscription plan:
| Plan | Requests/Hour | Requests/Day |
|---|---|---|
| Free | 10 | 100 |
| Starter | 50 | 500 |
| Pro | 200 | 2,000 |
| Enterprise | 1,000 | 10,000 |
MIT License - see LICENSE file for details.
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
See CHANGELOG.md for a list of changes in each version.
Made with ❤️ by the WhizoAI Team
FAQs
Official Node.js & TypeScript SDK for WhizoAI - Enterprise web scraping, crawling, and AI-powered data extraction API
We found that whizoai demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.