Node.js SDK
The official Node.js/TypeScript SDK for AlterLab. Zero dependencies, fully typed, modern async API.
Installation
npminstall @alterlab/sdkQuick Start
import{ AlterLab }from'alterlab';
// Initialize clientconst client =newAlterLab({ apiKey:'sk_live_...'});
// Scrape a websiteconst result =await client.scrape('https://example.com');
console.log(result.text);// Extracted textconsole.log(result.json);// Structured JSONconsole.log(result.billing.costDollars);// Cost in USDconsole.log(result.billing.tierUsed);// Which tier succeededClient Options
import{ AlterLab }from'alterlab';
// Basic initializationconst client =newAlterLab({ apiKey:'sk_live_...'});
// With all optionsconst client =newAlterLab({ apiKey:'sk_live_...',// Required (or set ALTERLAB_API_KEY env var) baseUrl:'https://alterlab.io',// Custom API endpoint timeout:120000,// Request timeout in ms maxRetries:3,// Auto-retry on failures retryDelay:1000,// Initial retry delay in ms});
// From environment variable// Set ALTERLAB_API_KEY=sk_live_...const client =newAlterLab();// Reads from env| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | env var | Your AlterLab API key |
baseUrl | string | alterlab.io | API base URL |
timeout | number | 120000 | Request timeout in ms |
maxRetries | number | 3 | Max retries on failure |
retryDelay | number | 1000 | Initial retry delay in ms |
Scraping Methods
client.scrape(url, options?)
Main scraping method with auto mode detection.
const result =await client.scrape('https://example.com',{// Modemode:'auto',// 'auto' | 'html' | 'js' | 'pdf' | 'ocr'
// JavaScript optionswaitFor:'#content',// CSS selector to wait forscreenshot:true,// Capture screenshot
// Advanced optionsadvanced:{renderJs:true,waitCondition:'networkidle',mobile:false,viewportWidth:1920,viewportHeight:1080,},
// Output optionsformats:['text','json','markdown'],
// Cachingcache:true,cacheTtl:3600,// 1 hour
// Cost controlscostControls:{maxTier:3,prefer:'cost',failFast:true,},});client.scrapeHtml(url, options?)
HTML-only mode (fastest, cheapest).
const result =await client.scrapeHtml('https://example.com');console.log(result.html);console.log(result.billing.tierName);// 'curl' or 'http'client.scrapeJs(url, options?)
JavaScript rendering with Playwright.
const result =await client.scrapeJs('https://spa-app.com',{screenshot:true,waitFor:'.loaded',});
console.log(result.text);console.log(result.screenshotUrl);client.scrapePdf(url) / client.scrapeOcr(url)
Extract text from PDFs and images.
// PDF extractionconst pdfResult =await client.scrapePdf('https://example.com/doc.pdf');console.log(pdfResult.text);
// OCR for imagesconst ocrResult =await client.scrapeOcr('https://example.com/image.png',{language:'eng',});console.log(ocrResult.text);Structured Extraction
// Extract specific fields with JSON Schemaconst result =await client.scrape('https://store.com/product/123',{ extractionSchema:{ type:'object', properties:{ name:{ type:'string'}, price:{ type:'number'}, inStock:{ type:'boolean'}, reviews:{ type:'array', items:{ type:'string'}}}}});
console.log(result.json);// { name: "Product", price: 29.99, inStock: true, reviews: [...] }Search
Run web searches and get back AI-summarized results with source links.
import AlterLab from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Simple searchconst results =await client.search('best noise-cancelling headphones 2025');
for(const r of results.results){console.log(r.title);console.log(r.url);console.log(r.snippet);}
// Search with optionsconst filtered =await client.search('python web scraping',{ limit:10, country:'US', language:'en',});
// AI-generated summary of the resultsconsole.log(filtered.summary);Map
Discover all URLs on a website — returns a sitemap-style link list.
import AlterLab from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Map all URLs on a siteconst sitemap =await client.map('https://docs.example.com');
console.log(`Found ${sitemap.links.length} URLs`);for(const url of sitemap.links){console.log(url);}
// Map with filtersconst filtered =await client.map('https://example.com',{ includePaths:['/blog/*','/products/*'], excludePaths:['/admin/*'], includeSubdomains:false, limit:1000,});Extract
Extract structured data from a URL or raw HTML using a JSON Schema or natural language prompt — without a full scrape.
import AlterLab from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Extract using JSON Schemaconst data =await client.extract('https://shop.example.com/product-123',{ schema:{ type:'object', properties:{ name:{ type:'string'}, price:{ type:'number'}, inStock:{ type:'boolean'}, images:{ type:'array', items:{ type:'string'}},},},});
console.log(data.result.name);console.log(data.result.price);
// Extract using natural languageconst article =await client.extract('https://news.example.com/article-456',{ prompt:'Extract the headline, author name, publication date, and article body'});
console.log(article.result);Cost Controls
import{ AlterLab }from'alterlab';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Limit to cheap tiers onlyconst result =await client.scrape('https://example.com',{ costControls:{ maxTier:2,// Don't go above HTTP tier prefer:'cost',// Optimize for lowest cost failFast:true,// Error instead of escalating maxCostDollars:0.001// Cap cost at $0.001}});
// Estimate cost before scrapingconst estimate =await client.estimateCost('https://linkedin.com');console.log(`Estimated: $${estimate.estimatedCostDollars.toFixed(4)}`);console.log(`Confidence: ${estimate.confidence}`);console.log(`Likely tier: ${estimate.tierName}`);💰 BYOP Discount: Get 20% off by using your own proxy integration
const result =await client.scrape('https://example.com',{advanced:{useOwnProxy:true,proxyCountry:'US'// Optional geo targeting}});
if(result.billing.byopApplied){console.log(`Saved ${result.billing.byopDiscountPercent}%!`);}Async Jobs
import{ AlterLab }from'alterlab';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Start an async job (returns immediately)const jobId =await client.scrapeAsync('https://example.com',{ mode:'js', advanced:{ screenshot:true}});
console.log(`Job started: ${jobId}`);
// Option 1: Poll manuallyconst status =await client.getJobStatus(jobId);console.log(`Status: ${status.status}`);console.log(`Progress: ${status.progress}%`);
// Option 2: Wait for completion (blocking)const result =await client.waitForJob(jobId,{ pollInterval:2000,// Check every 2 seconds timeout:300000// 5 minute timeout});
console.log(result.text);Batch, Sessions & Scheduler
The Node.js SDK supports batch scraping, session management, and scheduled scrapes.
import AlterLab from'@alterlab/sdk';importtype{ BatchResult, Session, Schedule }from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// --- Batch Scraping ---const batch: BatchResult =await client.batchScrape({ urls:[{ url:'https://example.com/1'},{ url:'https://example.com/2', mode:'js'},], webhookUrl:'https://your-server.com/webhook',});console.log(`Batch ${batch.batchId}: ${batch.status}`);
// --- Sessions (Authenticated Scraping) ---const session: Session =await client.createSession({ name:'My Login Session', domain:'example.com', cookies:{'session-token':'...'},});const result =await client.scrape('https://example.com/dashboard',{ sessionId: session.id,});
// --- Scheduler ---const schedule: Schedule =await client.createSchedule({ name:'Hourly check', urls:['https://example.com/prices'], cron:'0 * * * *', formats:['json'],});const history =await client.getScheduleHistory(schedule.id);Monitors
Create website change monitors that run on a schedule and notify you when content changes.
import AlterLab from'@alterlab/sdk';importtype{ Monitor }from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Create a monitorconst monitor: Monitor =await client.createMonitor({ name:'Competitor pricing', url:'https://competitor.com/pricing', diffMode:'selector',// 'semantic' | 'exact' | 'selector' monitorSelectors:['.price'],// CSS selectors to watch checkInterval:'0 */6 * * *',// Every 6 hours notifyOn:'change',// 'change' | 'always' webhookUrl:'https://your-server.com/alerts',});
console.log(`Monitor ID: ${monitor.id}`);console.log(`Next check: ${monitor.nextRunAt}`);
// List monitorsconst monitors =await client.listMonitors();for(const m of monitors){console.log(`${m.name}: ${m.status}`);}
// Get change historyconst changes =await client.getMonitorChanges(monitor.id,{ limit:10});for(const change of changes){console.log(`${change.detectedAt}: ${change.summary}`);}
// Pause/resumeawait client.pauseMonitor(monitor.id);await client.resumeMonitor(monitor.id);Alerts
Configure account-level alerts for balance thresholds, usage spikes, and error rate anomalies.
import AlterLab from'@alterlab/sdk';importtype{ Alert }from'@alterlab/sdk';
const client =newAlterLab({ apiKey:'sk_live_...'});
// Create a low-balance alertconst balanceAlert: Alert =await client.createAlert({ name:'Low balance warning', type:'balance_low', threshold:5.0,// Trigger when balance < $5 channels:['email','webhook'], webhookUrl:'https://your-server.com/alerts',});
// Create a daily spend alertconst spendAlert: Alert =await client.createAlert({ name:'Unusual spend spike', type:'daily_spend', threshold:50.0,// Trigger when daily spend > $50 channels:['email'],});
// List alertsconst alerts =await client.listAlerts();for(const a of alerts){console.log(`${a.name}: ${a.type} (threshold: ${a.threshold})`);}
// Delete an alertawait client.deleteAlert(balanceAlert.id);Error Handling
import{ AlterLab, AuthenticationError, InsufficientCreditsError, RateLimitError, ScrapeError, TimeoutError, ValidationError,}from'alterlab';
const client =newAlterLab({ apiKey:'sk_live_...'});
try{const result =await client.scrape('https://example.com');console.log(result.text);}catch(error){if(error instanceofAuthenticationError){console.log('Invalid API key');}elseif(error instanceofInsufficientCreditsError){console.log(`Balance: $${error.balanceDollars}`);console.log('Please top up your balance');}elseif(error instanceofRateLimitError){console.log(`Rate limited. Retry after ${error.retryAfter}s`);}elseif(error instanceofValidationError){console.log(`Invalid request: ${error.message}`);}elseif(error instanceofScrapeError){console.log(`Scraping failed: ${error.message}`);}elseif(error instanceofTimeoutError){console.log('Request timed out');}}| Exception | HTTP Code | Description |
|---|---|---|
AuthenticationError | 401 | Invalid or missing API key |
InsufficientCreditsError | 402 | Insufficient balance |
RateLimitError | 429 | Too many requests |
ValidationError | 400 | Invalid request parameters |
ScrapeError | 422 | Scraping failed |
TimeoutError | - | Request timed out |
TypeScript
The SDK is written in TypeScript and exports all types. Your IDE will provide full autocomplete and type checking.
import{ AlterLab, AlterLabConfig, ScrapeResult, ScrapeOptions, BillingDetails, CostControls, AdvancedOptions, UsageStats, CostEstimate, JobStatus,}from'alterlab';
// All types are exportedconst options: ScrapeOptions ={ mode:'js', screenshot:true, costControls:{ maxTier:3, prefer:'cost',},};
const result: ScrapeResult =await client.scrape('https://example.com', options);
// Full autocomplete for all fieldsconst billing: BillingDetails = result.billing;console.log(billing.costDollars);console.log(billing.tierName);console.log(billing.escalationPath);API Reference
Full Documentation
ScrapeResult
interfaceScrapeResult{requestId: string;url: string;finalUrl: string;statusCode: number;text: string;html: string;json:Record<string, unknown>|null;markdownContent: string |null;title: string |null;author: string |null;screenshotUrl: string |null;pdfUrl: string |null;cached: boolean;responseTimeMs: number;sizeBytes: number;billing:BillingDetails;}BillingDetails
interfaceBillingDetails{tierUsed: number;// 1-5tierName:TierName;// 'curl' | 'http' | 'stealth' | 'browser' | 'captcha'costMicrocents: number;// 1,000,000 = $1costDollars: number;byopApplied: boolean;byopDiscountPercent: number;escalationPath:TierEscalation[];}