evomi-client
v1.0.3
Published
JavaScript client for Evomi API
Readme
Evomi JavaScript Client
The official JavaScript client for Evomi — a powerful web scraping and proxy platform. Extract data from any website with AI-powered processing, browser rendering, and a global proxy network.
Installation
npm install evomi-clientQuick Start
import { EvomiClient } from 'evomi-client';
const client = new EvomiClient({ apiKey: 'your-api-key' });
// Scrape a webpage
const result = await client.scrape('https://example.com');
console.log(result.content);Core Features
- Web Scraping — Extract content from any URL with automatic JS rendering detection
- AI-Powered Extraction — Get structured data using natural language prompts
- Crawling & Mapping — Discover and scrape entire websites
- Proxy Network — Access residential, datacenter, and mobile proxies worldwide
Usage Examples
Basic Scraping
import { EvomiClient } from 'evomi-client';
const client = new EvomiClient({ apiKey: 'your-api-key' });
// Simple scrape (auto-detects if JS rendering is needed)
const result = await client.scrape('https://example.com');
console.log(result.content);AI-Powered Data Extraction
Extract structured data without writing selectors:
const result = await client.scrape('https://example.com/products', {
aiEnhance: true,
aiPrompt: 'Extract all product names, prices, and availability',
});
console.log(result.ai_data);Browser Mode for JavaScript Sites
Force browser rendering for dynamic content:
const result = await client.scrape('https://spa-example.com', {
mode: 'browser', // Forces headless browser
waitSeconds: 2, // Wait for dynamic content
});Crawling Websites
Discover and scrape multiple pages:
const result = await client.crawl('example.com', {
maxUrls: 50,
depth: 2,
urlPattern: '/blog/.*', // Only crawl blog pages
});Async Tasks
For long-running operations, use async mode:
// Start the crawl
const { task_id } = await client.crawl('example.com', { asyncMode: true });
// Check status later
const status = await client.getTaskStatus(task_id, 'crawl');
if (status.status === 'completed') {
console.log(status.results);
}Proxy String Builder
Evomi provides a proxy network you can use with any HTTP client. Build proxy strings for fetch, axios, or any other library:
import { EvomiClient, ProxyType } from 'evomi-client';
const client = new EvomiClient({ apiKey: 'your-api-key' });
// Build a proxy string for US residential proxy
const proxyString = await client.buildProxyString({
proxyType: ProxyType.RESIDENTIAL,
country: 'US',
session: 'abc12345', // Sticky session
});
console.log(proxyString);
// Output: http://user:[email protected]:1000Manual Proxy Configuration
import { ProxyConfig, ProxyType, ProxyProtocol } from 'evomi-client';
const config = new ProxyConfig({
proxyType: ProxyType.RESIDENTIAL,
protocol: ProxyProtocol.HTTP,
country: 'US',
city: 'New York',
username: 'your-username',
password: 'your-password',
});
const proxyString = config.buildProxyString();Proxy Types
| Type | Endpoint | Use Case |
|------|----------|----------|
| Residential | rp.evomi.com:1000 | Human-like browsing, anti-bot bypass |
| Datacenter | dcp.evomi.com:2000 | Fast, high-volume requests |
| Mobile | mp.evomi.com:3000 | Highest trust, mobile-specific targets |
API Reference
Scraping Operations
scrape(url, options)
Scrape a single URL with configurable options.
const result = await client.scrape('https://example.com', {
mode: 'auto', // 'request', 'browser', or 'auto'
output: 'markdown', // 'html', 'markdown', 'screenshot', 'pdf'
device: 'windows', // 'windows', 'macos', 'android'
proxyType: 'residential',
proxyCountry: 'US',
proxySessionId: 'abc123',
waitUntil: 'domcontentloaded',
aiEnhance: true,
aiPrompt: 'Extract product data',
aiSource: 'markdown',
jsInstructions: [{ click: '.load-more' }],
executeJs: 'window.scrollTo(0, document.body.scrollHeight)',
waitSeconds: 2,
screenshot: false,
pdf: false,
excludedTags: ['nav', 'footer'],
excludedSelectors: ['.ads'],
blockResources: ['image', 'stylesheet'],
additionalHeaders: { 'X-Custom': 'value' },
captureHeaders: true,
networkCapture: [{ url_pattern: '/api/.*' }],
asyncMode: false,
configId: 'cfg_abc123',
schemeId: 'sch_abc123',
extractScheme: [{ label: 'title', type: 'content', selector: 'h1' }],
storageId: 'stor_abc123',
useDefaultStorage: false,
noHtml: false,
});| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| url | string | required | URL to scrape |
| mode | string | 'auto' | Scraping mode: 'request', 'browser', 'auto' |
| output | string | 'markdown' | Output format: 'html', 'markdown', 'screenshot', 'pdf' |
| device | string | 'windows' | Device type: 'windows', 'macos', 'android' |
| proxyType | string | 'residential' | Proxy type: 'datacenter', 'residential' |
| proxyCountry | string | 'US' | Two-letter country code |
| proxySessionId | string | — | Proxy session ID (6-8 chars) |
| waitUntil | string | 'domcontentloaded' | Wait condition |
| aiEnhance | boolean | false | Enable AI extraction |
| aiPrompt | string | — | Prompt for AI extraction |
| aiSource | string | — | AI source: 'markdown', 'screenshot' |
| aiForceJson | boolean | true | Force AI response to valid JSON |
| jsInstructions | array | — | JS actions: click, wait, fill, wait_for |
| executeJs | string | — | Raw JavaScript to execute |
| waitSeconds | number | 0 | Seconds to wait after page load |
| screenshot | boolean | false | Capture screenshot |
| pdf | boolean | false | Capture PDF |
| excludedTags | array | — | HTML tags to remove |
| excludedSelectors | array | — | CSS selectors to remove |
| blockResources | array | — | Resource types to block |
| additionalHeaders | object | — | Extra HTTP headers |
| captureHeaders | boolean | false | Capture response headers |
| networkCapture | array | — | Network capture filters |
| asyncMode | boolean | false | Return immediately with task ID |
| configId | string | — | Saved config ID |
| schemeId | string | — | Saved extraction schema ID |
| extractScheme | array | — | Inline extraction schema |
| storageId | string | — | Storage config ID |
| useDefaultStorage | boolean | false | Use default storage |
| noHtml | boolean | false | Exclude HTML from response |
crawl(domain, options)
Crawl a website to discover and scrape multiple pages.
const result = await client.crawl('example.com', {
maxUrls: 100,
depth: 2,
urlPattern: '/blog/.*',
scraperConfig: { mode: 'browser', output: 'markdown' },
asyncMode: false,
});| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| domain | string | required | Domain to crawl |
| maxUrls | number | 100 | Maximum URLs to crawl |
| depth | number | 2 | Crawl depth |
| urlPattern | string | — | Regex pattern to filter URLs |
| scraperConfig | object | — | Config for scraping each page |
| asyncMode | boolean | false | Return immediately with task ID |
mapWebsite(domain, options)
Discover URLs from a website via sitemaps, CommonCrawl, or crawling.
const result = await client.mapWebsite('example.com', {
sources: ['sitemap', 'commoncrawl'],
maxUrls: 500,
urlPattern: '/products/.*',
checkIfLive: false,
depth: 1,
asyncMode: false,
});| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| domain | string | required | Domain to map |
| sources | array | ['sitemap', 'commoncrawl'] | Sources: 'sitemap', 'commoncrawl', 'crawl' |
| maxUrls | number | 500 | Maximum URLs to discover |
| urlPattern | string | — | Regex pattern to filter URLs |
| checkIfLive | boolean | false | Check if URLs are live |
| depth | number | 1 | Crawl depth if using crawl source |
| asyncMode | boolean | false | Return immediately with task ID |
searchDomains(query, options)
Find domains by searching the web.
// Single query
const result = await client.searchDomains('e-commerce platforms', {
maxUrls: 20,
region: 'us-en',
});
// Multiple queries (up to 10)
const result = await client.searchDomains(
['web scraping tools', 'data extraction services'],
{ maxUrls: 20, region: 'us-en' }
);| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| query | string or array | required | Search query or list of up to 10 queries |
| maxUrls | number | 20 | Max domains per query (max: 100) |
| region | string | 'us-en' | Region for results |
agentRequest(message)
Send a natural language request to the AI agent.
const result = await client.agentRequest(
'Scrape example.com and extract all product prices'
);| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| message | string | required | Natural language request |
getTaskStatus(taskId, taskType)
Check the status of an async task.
const result = await client.getTaskStatus('abc123', 'scrape');
// taskType: 'scrape' | 'crawl' | 'map' | 'config_generate' | 'schema'| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| taskId | string | required | Task ID to check |
| taskType | string | 'scrape' | Task type |
Config Management
Save and reuse scrape configurations.
listConfigs(options)
List all saved scrape configs.
const configs = await client.listConfigs({
page: 1,
perPage: 20,
sortBy: 'created_at',
sortOrder: 'desc',
});createConfig(name, config)
Create a new scrape config.
const config = await client.createConfig('Product Scraper', {
mode: 'browser',
output: 'markdown',
});getConfig(configId)
Get a scrape config by ID.
const config = await client.getConfig('cfg_abc123');updateConfig(configId, options)
Update an existing scrape config.
const config = await client.updateConfig('cfg_abc123', {
name: 'New Name',
config: { mode: 'request' },
});deleteConfig(configId)
Delete a scrape config.
await client.deleteConfig('cfg_abc123');generateConfig(name, prompt)
Generate a scrape config from natural language using AI.
const config = await client.generateConfig(
'Amazon Scraper',
'Scrape product title and price from Amazon product pages'
);Schema Management
Define reusable structured data extraction schemas.
listSchemas(options)
List all saved extraction schemas.
const schemas = await client.listSchemas({
page: 1,
perPage: 20,
sortBy: 'created_at',
sortOrder: 'desc',
});createSchema(name, config, options)
Create a new extraction schema.
const schema = await client.createSchema(
'Product Schema',
{
url: 'https://example.com/product',
extract_scheme: [
{ label: 'title', type: 'content', selector: 'h1' },
{ label: 'price', type: 'content', selector: '.price' },
],
},
{ test: true, fix: false }
);getSchema(schemeId)
Get an extraction schema by ID.
const schema = await client.getSchema('sch_abc123');updateSchema(schemeId, name, config, options)
Update an existing extraction schema.
const schema = await client.updateSchema(
'sch_abc123',
'Updated Schema',
{ url: '...', extract_scheme: [...] },
{ test: true }
);deleteSchema(schemeId)
Delete an extraction schema.
await client.deleteSchema('sch_abc123');getSchemaStatus(schemeId)
Get the test status of a schema.
const status = await client.getSchemaStatus('sch_abc123');Schedule Management
Run scrape configs on a recurring schedule.
listSchedules(options)
List all scheduled jobs.
const schedules = await client.listSchedules({
page: 1,
perPage: 20,
activeOnly: false,
});createSchedule(name, configId, intervalMinutes, options)
Create a new scheduled scrape job.
const schedule = await client.createSchedule(
'Daily Price Check',
'cfg_abc123',
1440, // Daily (in minutes)
{ startTime: '09:00', stopOnError: true }
);getSchedule(scheduleId)
Get a scheduled job by ID.
const schedule = await client.getSchedule('sched_abc123');updateSchedule(scheduleId, options)
Update an existing scheduled job.
const schedule = await client.updateSchedule('sched_abc123', {
name: 'New Name',
intervalMinutes: 720,
});deleteSchedule(scheduleId)
Delete a scheduled job.
await client.deleteSchedule('sched_abc123');toggleSchedule(scheduleId)
Toggle a scheduled job active/inactive.
await client.toggleSchedule('sched_abc123');listScheduleRuns(scheduleId, options)
Get execution history for a scheduled job.
const runs = await client.listScheduleRuns('sched_abc123', {
page: 1,
perPage: 20,
});Storage Management
Connect cloud storage to automatically save scrape results.
listStorageConfigs()
List all storage configurations.
const configs = await client.listStorageConfigs();createStorageConfig(name, storageType, config, options)
Create a new storage configuration.
// S3-compatible storage
const storage = await client.createStorageConfig(
'My S3',
's3_compatible',
{
bucket: 'my-bucket',
region: 'us-east-1',
access_key: '...',
secret_key: '...',
},
{ setAsDefault: true }
);
// Google Cloud Storage
const storage = await client.createStorageConfig(
'My GCS',
'gcs',
{ bucket: 'my-bucket', credentials_json: '...' }
);
// Azure Blob Storage
const storage = await client.createStorageConfig(
'My Azure',
'azure_blob',
{ container: 'my-container', connection_string: '...' }
);updateStorageConfig(storageId, options)
Update an existing storage configuration.
const storage = await client.updateStorageConfig('stor_abc123', {
name: 'Renamed Storage',
setAsDefault: true,
});deleteStorageConfig(storageId)
Delete a storage configuration.
await client.deleteStorageConfig('stor_abc123');Webhook Notifications
Receive real-time notifications when your scraping operations complete, fail, or start. Webhooks support Discord, Slack, and custom HTTP endpoints.
Quick Start
const result = await client.scrape('https://example.com', {
webhook: {
url: 'https://your-webhook-endpoint.com/webhook',
type: 'custom',
events: ['completed', 'failed'],
},
});Webhook Configuration
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| url | string | Yes | Your webhook endpoint URL |
| type | string | Yes | Webhook type: 'discord', 'slack', or 'custom' |
| events | array | Yes | List of events to subscribe to |
| secret | string | No | Secret key for HMAC signature (custom webhooks only) |
Supported Events
| Operation | Events |
|-----------|--------|
| Scrape | scrape.started, scrape.completed, scrape.failed |
| Crawl | crawl.started, crawl.completed, crawl.failed |
| Map | map.started, map.completed, map.failed |
| Search | search.started, search.completed, search.failed |
| Schedule | schedule.started, schedule.completed, schedule.failed, schedule.paused |
You can use shorthand notation: ['completed', 'failed'] or full names: ['scrape.completed', 'scrape.failed'].
Webhook Types
Discord Webhooks
const result = await client.scrape('https://example.com', {
webhook: {
url: 'https://discord.com/api/webhooks/...',
type: 'discord',
events: ['completed', 'failed'],
},
});Discord webhooks receive rich embeds with operation details.
Slack Webhooks
const result = await client.scrape('https://example.com', {
webhook: {
url: 'https://hooks.slack.com/services/...',
type: 'slack',
events: ['completed', 'failed'],
},
});Slack webhooks receive formatted attachments with operation details.
Custom Webhooks
const result = await client.scrape('https://example.com', {
webhook: {
url: 'https://your-server.com/webhook',
type: 'custom',
events: ['completed', 'failed'],
secret: 'your-secret-key', // Optional HMAC signature
},
});Custom Webhook Payload
Custom webhooks receive a JSON POST request with the following structure:
{
"event": "scrape.completed",
"timestamp": "2026-03-06T20:51:00Z",
"user_id": 123,
"username": "user_name",
"task_id": "abc123",
"data": {
"url": "https://example.com",
"domain": "example.com",
"status_code": 200,
"credits_used": 1.5
},
"signature": "sha256=..."
}| Field | Type | Description |
|-------|------|-------------|
| event | string | The event that triggered the webhook |
| timestamp | string | ISO 8601 timestamp |
| user_id | number | Your user ID |
| username | string | Your username |
| task_id | string | The task ID associated with the operation |
| data | object | Operation-specific data |
| signature | string | HMAC SHA256 signature (if secret configured) |
Security: HMAC Signature Verification
When you provide a secret, custom webhooks include an HMAC SHA256 signature in the payload. Verify the signature to ensure requests are from Evomi:
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler (e.g., Express)
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'] || '';
if (!verifyWebhook(req.body, signature, 'your-secret-key')) {
return res.status(401).json({ error: 'Invalid signature' });
}
const data = JSON.parse(req.body);
// Process the webhook...
res.json({ received: true });
});The signature is sent in the X-Webhook-Signature header.
Usage Examples
Per-Request Webhook
Add a webhook to any scraping operation:
const result = await client.scrape('https://example.com', {
webhook: {
url: 'https://your-server.com/webhook',
type: 'custom',
events: ['scrape.completed', 'scrape.failed'],
secret: 'your-secret-key',
},
});Schedule with Webhook
Attach a webhook to a scheduled job:
const schedule = await client.createSchedule(
'Daily Price Check',
'cfg_abc123',
1440,
{
webhook: {
url: 'https://your-server.com/webhook',
type: 'discord',
events: ['completed', 'failed'],
},
}
);Crawl with Webhook
const result = await client.crawl('example.com', {
maxUrls: 100,
webhook: {
url: 'https://hooks.slack.com/services/...',
type: 'slack',
events: ['crawl.completed', 'crawl.failed'],
},
});Public API
Access proxy credentials and related data.
getProxyData()
Get detailed information about your proxy products.
const data = await client.getProxyData();
// Returns: { products: { rp: {...}, sdc: {...}, mp: {...} }, ... }getTargetingOptions()
Get available targeting parameters for different proxy types.
const options = await client.getTargetingOptions();getScraperData()
Get information about your Scraper API access.
const data = await client.getScraperData();
// Returns: { credits: ..., concurrency_limit: ..., ... }getBrowserData()
Get information about your Browser API access.
const data = await client.getBrowserData();
// Returns: { credits: ..., concurrency_limit: ..., endpoint: ..., ... }rotateSession(sessionId, product)
Force an IP address change for an existing proxy session.
const result = await client.rotateSession('abc12345', 'rp');
// product: 'rpc', 'rp', 'sdc', 'mp'generateProxies(options)
Generate proxy strings with specific targeting parameters.
const proxies = await client.generateProxies({
product: 'rp',
countries: 'US,GB,DE',
city: 'New York',
session: 'sticky',
amount: 10,
protocol: 'http',
lifetime: 30,
adblock: true,
});
// Returns plain text, one proxy per line| Parameter | Type | Description |
|-----------|------|-------------|
| product | string | Proxy product type |
| countries | string | ISO country codes, comma-separated |
| city | string | Target city name |
| region | string | Target region |
| isp | string | Target ISP name |
| session | string | 'sticky' or 'hard' |
| amount | number | Number of proxies to generate (1-100) |
| format | string | Output format (1, 2, or 3) |
| prependProtocol | boolean | Prepend protocol to proxy string |
| protocol | string | 'http' or 'socks5' |
| lifetime | number | Session duration in minutes |
| adblock | boolean | Enable ad-blocking |
Account Info
getAccountInfo()
Get account info including credit balance.
const info = await client.getAccountInfo();
console.log(info.credits);Proxy Helpers
buildProxyConfig(options)
Build a proxy configuration with credentials from the Public API.
import { ProxyType, ProxyProtocol, ResidentialMode } from 'evomi-client';
const config = await client.buildProxyConfig({
proxyType: ProxyType.RESIDENTIAL,
protocol: ProxyProtocol.HTTP,
country: 'US',
city: 'New York',
region: 'California',
continent: 'north.america',
isp: 'att',
session: 'abc12345',
lifetime: 30,
mode: ResidentialMode.SPEED,
latency: 100,
fraudscore: 20,
device: 'windows',
http3: true,
});buildProxyString(options)
Build a proxy connection string directly.
const proxyString = await client.buildProxyString({
proxyType: ProxyType.RESIDENTIAL,
country: 'US',
session: 'abc12345',
});Configuration
API Key
Set your API key via environment variable:
export EVOMI_API_KEY="your-api-key"Or pass it directly:
const client = new EvomiClient({ apiKey: 'your-api-key' });Proxy Credentials (Optional)
If you have separate credentials for the proxy API:
const client = new EvomiClient({
apiKey: 'your-api-key',
publicApiKey: 'your-proxy-api-key',
});Error Handling
try {
const result = await client.scrape('https://example.com');
} catch (error) {
console.error('Scraping failed:', error.message);
}Credits & Pricing
All operations consume credits:
- Base request: 1 credit
- Browser mode: 5x multiplier
- Residential proxy: 2x multiplier
- AI enhancement: +30 credits
Credit usage is returned in the result:
console.log(result._credits_used);
console.log(result._credits_remaining);Requirements
- Node.js >= 18 (for native
fetch)
Links
License
MIT
