How to Use Parallax SDK (ParallaxAPIs) in 2026

Anti-bot systems like DataDome and PerimeterX have become formidable gatekeepers on the modern web.

While browser automation tools like Selenium or Puppeteer can technically bypass these protections, they're slow, resource-intensive, and increasingly expensive to run at scale.

ParallaxAPIs SDK offers a different approach: request-based bypass that generates valid cookies and tokens in 200-400ms through direct HTTP requests—no browsers required.

The Parallax SDK supports multiple languages including Python, TypeScript/JavaScript, Go, and Playwright, making it easy to integrate anti-bot bypass into any tech stack.

In this guide, we'll cover everything you need to know about using the ParallaxAPIs SDK for DataDome and PerimeterX (HUMAN) bypass, with comprehensive examples in both Python and TypeScript.

Why Request-Based Bypass Beats Browser Automation

Let's be real: running headless browsers to bypass anti-bot systems is like bringing a tank to a knife fight. It works, but it's expensive and slow.

Browser automation approaches like Selenium with undetected-chromedriver or Puppeteer Stealth work by rendering full browser instances. Each instance consumes 200-500MB of memory, takes 5-10 seconds to initialize, and burns through residential proxy bandwidth like there's no tomorrow (2MB per page versus 250KB for HTTP requests).

Request-based bypass tools like the Parallax SDK take a fundamentally different approach. Instead of rendering entire browsers, they reverse-engineer the anti-bot detection logic and replay it through direct HTTP requests. The SDK handles all the complex fingerprinting, challenge solving, and token generation—returning valid cookies in a fraction of the time.

Here's what this means in practice:

  • Speed: 200-400ms response times versus 5-10+ seconds for browser automation
  • Resources: Minimal memory footprint versus 200-500MB per browser instance
  • Scalability: Handle thousands of concurrent requests on a single server
  • Cost: Lower proxy bandwidth usage (HTTP requests vs full page renders)

The tradeoff? Request-based solutions require the service provider to continuously reverse-engineer anti-bot systems. That's where ParallaxAPIs comes in—they handle all the reverse engineering and keep the SDK updated as DataDome and PerimeterX evolve.

Getting Started with ParallaxAPIs SDK

Available SDKs for DataDome & PerimeterX Bypass

ParallaxAPIs provides SDKs for multiple languages and frameworks, so you can integrate with your existing tech stack:

  • Python SDK - Comprehensive Python implementation (what we'll focus on first)
  • TypeScript/JavaScript SDK - Native TypeScript support for Node.js applications
  • Go SDK - High-performance Go implementation
  • Playwright SDK - Browser automation integration with automatic DataDome/PerimeterX solving

All Parallax SDKs share the same core API design, making it easy to switch between languages. The patterns we'll cover translate directly across all implementations.

Prerequisites

Before you start with the Parallax SDK, you'll need:

  • Python 3.7+ or Node.js 14+ (depending on your chosen SDK)
  • An API key from ParallaxAPIs (join their Discord and create a ticket to request access)
  • Proxies (residential or mobile proxies recommended for production use)

Installation

Python SDK:

pip install parallaxapis-sdk-py

TypeScript/JavaScript SDK:

npm install parallaxapis-sdk-ts
# or
yarn add parallaxapis-sdk-ts

Go SDK:

go get github.com/ParallaxAPIs/parallaxapis-sdk-go

That's it. No browser drivers, no Chrome installations, no Selenium dependencies—just lightweight packages.

Basic Configuration

The Parallax SDK supports both synchronous and asynchronous patterns across all language implementations.

Python Configuration:

from parallaxapis_sdk_py.sdk import SDKConfig

# Basic configuration
cfg = SDKConfig(
    host="example.com",  # Target website
    api_key="your_api_key_here"
)

# Advanced configuration with timeout and proxy
cfg = SDKConfig(
    host="example.com",
    api_key="your_api_key_here",
    timeout=60,  # Request timeout in seconds (default: 30)
    proxy="http://user:pass@proxy.example.com:8080"  # SDK-level proxy
)

TypeScript SDK Configuration:

import { SDKConfig } from 'parallaxapis-sdk-ts';

// Basic configuration
const cfg = new SDKConfig({
    host: "example.com",
    apiKey: "your_api_key_here"
});

// Advanced configuration with timeout and proxy
const cfg = new SDKConfig({
    host: "example.com",
    apiKey: "your_api_key_here",
    timeout: 60,  // Request timeout in seconds
    proxy: "http://user:pass@proxy.example.com:8080"
});

A note on proxies: The Parallax SDK supports proxies at two levels. The proxy parameter in SDKConfig routes SDK API requests through a proxy. When generating cookies or tokens, you can pass a separate proxy parameter to the task itself—this is the proxy that will be used for the actual bypass operation.

Cross-SDK Consistency: Python vs TypeScript

One of ParallaxAPIs' strengths is API consistency across languages. Here's the same DataDome cookie generation in multiple SDKs:

Python:

from parallaxapis_sdk_py.datadome import DatadomeSDK
from parallaxapis_sdk_py.sdk import SDKConfig
from parallaxapis_sdk_py.tasks import TaskGenerateDatadomeCookie

cfg = SDKConfig(host="example.com", api_key="key")
with DatadomeSDK(cfg=cfg) as sdk:
    result = sdk.generate_cookie(TaskGenerateDatadomeCookie(...))

TypeScript/JavaScript:

import { DatadomeSDK, SDKConfig, TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

const cfg = new SDKConfig({ host: "example.com", apiKey: "key" });
const sdk = new DatadomeSDK(cfg);
const result = await sdk.generateCookie(new TaskGenerateDatadomeCookie(...));

Go:

import "github.com/ParallaxAPIs/parallaxapis-sdk-go/datadome"

cfg := datadome.SDKConfig{Host: "example.com", APIKey: "key"}
sdk := datadome.NewDatadomeSDK(cfg)
result, err := sdk.GenerateCookie(datadome.TaskGenerateDatadomeCookie{...})

Playwright SDK:

import { DatadomePlaywright } from 'parallaxapis-sdk-playwright';

const sdk = new DatadomePlaywright({ host: "example.com", apiKey: "key" });
await sdk.solvePage(page); // Automatically handles DataDome on Playwright page

The Playwright SDK is particularly interesting—it wraps Playwright's browser automation with automatic DataDome/PerimeterX solving, giving you the best of both worlds: full browser rendering when you need it, with anti-bot bypass built in.

Working with DataDome Protection Using Parallax SDK

DataDome is one of the most sophisticated anti-bot systems out there. It uses a combination of server-side fingerprinting (TLS, HTTP/2, IP reputation) and client-side detection (JavaScript challenges, behavioral analysis) to identify bots.

Detecting DataDome Blocks

First, you need to know when you've been blocked. DataDome typically returns:

  • 403 Forbidden status codes
  • Response bodies containing dd JavaScript objects
  • Set-Cookie headers with datadome cookies
  • x-datadome response headers

Sometimes you'll hit a CAPTCHA challenge page—these are the slider challenges or interstitial pages that DataDome uses.

Generating a Valid User Agent with Parallax SDK

DataDome checks if your user agent matches expected browser fingerprints. The Parallax SDK can generate valid user agents:

Python:

from parallaxapis_sdk_py.datadome import DatadomeSDK
from parallaxapis_sdk_py.sdk import SDKConfig
from parallaxapis_sdk_py.tasks import TaskGenerateUserAgent

cfg = SDKConfig(host="example.com", api_key="your_key")

with DatadomeSDK(cfg=cfg) as sdk:
    user_agent = sdk.generate_user_agent(TaskGenerateUserAgent(
        region="com",  # Top-level domain
        site="example",
        pd="optional"  # Product type (optional)
    ))
    
    print(f"Generated User-Agent: {user_agent}")

TypeScript SDK:

import { DatadomeSDK, SDKConfig, TaskGenerateUserAgent } from 'parallaxapis-sdk-ts';

const cfg = new SDKConfig({ host: "example.com", apiKey: "your_key" });
const sdk = new DatadomeSDK(cfg);

const userAgent = await sdk.generateUserAgent(new TaskGenerateUserAgent({
    region: "com",
    site: "example",
    pd: "optional"
}));

console.log(`Generated User-Agent: ${userAgent}`);

Store this user agent and use it consistently across requests to the same site.

Parsing DataDome Challenges

When you hit a DataDome block, you'll need to extract challenge parameters before you can generate a valid cookie. The Parallax SDK provides multiple ways to do this:

From Challenge URL (Python):

from parallaxapis_sdk_py.datadome import DatadomeSDK

with DatadomeSDK(cfg=cfg) as sdk:
    challenge_url = "https://geo.captcha-delivery.com/captcha/?initialCid=xxx&cid=xxx&..."
    previous_cookie = "datadome=..."  # The cookie that got blocked
    
    task_data, product_type = sdk.parse_challenge_url(challenge_url, previous_cookie)

From Challenge URL (TypeScript SDK):

import { DatadomeSDK } from 'parallaxapis-sdk-ts';

const sdk = new DatadomeSDK(cfg);
const challengeUrl = "https://geo.captcha-delivery.com/captcha/?initialCid=xxx&cid=xxx&...";
const previousCookie = "datadome=...";

const [taskData, productType] = await sdk.parseChallengeUrl(challengeUrl, previousCookie);

Auto-detection (Python):

with DatadomeSDK(cfg=cfg) as sdk:
    # Works with both HTML and JSON responses
    response_body = your_scraped_content
    previous_cookie = "datadome=..."
    
    is_blocked, task_data, product_type = sdk.detect_challenge_and_parse(
        body=response_body,
        datadome_cookie=previous_cookie
    )
    
    if is_blocked:
        print("DataDome challenge detected")

Auto-detection (TypeScript SDK):

const [isBlocked, taskData, productType] = await sdk.detectChallengeAndParse(
    responseBody,
    previousCookie
);

if (isBlocked) {
    console.log("DataDome challenge detected");
}

The auto-detection method is your best bet for most use cases—it handles both challenge types automatically.

Generating Valid DataDome Cookies

Once you've parsed the challenge, generate a valid cookie using the Parallax SDK:

Python:

from parallaxapis_sdk_py.tasks import TaskGenerateDatadomeCookie

with DatadomeSDK(cfg=cfg) as sdk:
    cookie_response = sdk.generate_cookie(TaskGenerateDatadomeCookie(
        site="example",
        region="com",
        data=task_data,  # From parsing step
        pd=product_type,  # From parsing step
        proxy="http://user:pass@addr:port",  # Proxy for solving
        proxyregion="us"  # Proxy region (helps with geo-targeting)
    ))
    
    # Extract the cookie value
    new_cookie = cookie_response['cookie']
    print(f"New DataDome cookie: {new_cookie}")

TypeScript SDK:

import { TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

const cookieResponse = await sdk.generateCookie(new TaskGenerateDatadomeCookie({
    site: "example",
    region: "com",
    data: taskData,
    pd: productType,
    proxy: "http://user:pass@addr:port",
    proxyregion: "us"
}));

const newCookie = cookieResponse.cookie;
console.log(`New DataDome cookie: ${newCookie}`);

Important: The proxy parameter here is for the actual bypass operation. Use the same proxy you'll use for scraping to maintain consistency in fingerprinting.

Complete DataDome Bypass Example

Python Example:

import httpx
from parallaxapis_sdk_py.datadome import DatadomeSDK
from parallaxapis_sdk_py.sdk import SDKConfig
from parallaxapis_sdk_py.tasks import TaskGenerateUserAgent, TaskGenerateDatadomeCookie

# Configuration
cfg = SDKConfig(host="example.com", api_key="your_key")
proxy_url = "http://user:pass@proxy.example.com:8080"

with DatadomeSDK(cfg=cfg) as sdk:
    # Step 1: Generate a consistent user agent
    user_agent = sdk.generate_user_agent(TaskGenerateUserAgent(
        region="com",
        site="example"
    ))
    
    # Step 2: Make initial request
    headers = {"User-Agent": user_agent}
    response = httpx.get(
        "https://example.com/api/data",
        headers=headers,
        proxies=proxy_url
    )
    
    # Step 3: Check if blocked
    datadome_cookie = response.cookies.get("datadome", "")
    is_blocked, task_data, product_type = sdk.detect_challenge_and_parse(
        body=response.text,
        datadome_cookie=datadome_cookie
    )
    
    if is_blocked:
        print("Blocked by DataDome, generating new cookie...")
        
        # Step 4: Generate valid cookie
        cookie_response = sdk.generate_cookie(TaskGenerateDatadomeCookie(
            site="example",
            region="com",
            data=task_data,
            pd=product_type,
            proxy=proxy_url,
            proxyregion="us"
        ))
        
        # Step 5: Retry with new cookie
        headers["Cookie"] = f"datadome={cookie_response['cookie']}"
        response = httpx.get(
            "https://example.com/api/data",
            headers=headers,
            proxies=proxy_url
        )
        
        print(f"Success! Status: {response.status_code}")

TypeScript SDK Example:

import axios from 'axios';
import { DatadomeSDK, SDKConfig, TaskGenerateUserAgent, TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

// Configuration
const cfg = new SDKConfig({ host: "example.com", apiKey: "your_key" });
const proxyUrl = "http://user:pass@proxy.example.com:8080";

const sdk = new DatadomeSDK(cfg);

async function bypassDatadome() {
    // Step 1: Generate a consistent user agent
    const userAgent = await sdk.generateUserAgent(new TaskGenerateUserAgent({
        region: "com",
        site: "example"
    }));
    
    // Step 2: Make initial request
    let response = await axios.get("https://example.com/api/data", {
        headers: { "User-Agent": userAgent },
        proxy: false,
        httpsAgent: new HttpsProxyAgent(proxyUrl)
    });
    
    // Step 3: Check if blocked
    const datadomeCookie = response.headers['set-cookie']?.find(c => c.startsWith('datadome=')) || "";
    const [isBlocked, taskData, productType] = await sdk.detectChallengeAndParse(
        response.data,
        datadomeCookie
    );
    
    if (isBlocked) {
        console.log("Blocked by DataDome, generating new cookie...");
        
        // Step 4: Generate valid cookie
        const cookieResponse = await sdk.generateCookie(new TaskGenerateDatadomeCookie({
            site: "example",
            region: "com",
            data: taskData,
            pd: productType,
            proxy: proxyUrl,
            proxyregion: "us"
        }));
        
        // Step 5: Retry with new cookie
        response = await axios.get("https://example.com/api/data", {
            headers: { 
                "User-Agent": userAgent,
                "Cookie": `datadome=${cookieResponse.cookie}`
            },
            proxy: false,
            httpsAgent: new HttpsProxyAgent(proxyUrl)
        });
        
        console.log(`Success! Status: ${response.status}`);
    }
}

bypassDatadome();

Bypassing PerimeterX (HUMAN) with ParallaxAPIs SDK

PerimeterX (recently rebranded as HUMAN) is another major player in the anti-bot space. It's commonly found on e-commerce sites and works similarly to DataDome but with different detection techniques.

Understanding PerimeterX Protection

PerimeterX typically uses:

  • Cookie-based challenges: The _px3 cookie is the main session token
  • JavaScript challenges: Complex browser fingerprinting and behavior analysis
  • VID/CTS tokens: Additional verification tokens
  • "Press & Hold" challenges: Interactive CAPTCHA-style challenges

Generating PerimeterX Cookies with Parallax SDK

The basic flow for bypassing PerimeterX using the Parallax SDK:

Python:

from parallaxapis_sdk_py.perimeterx import PerimeterxSDK
from parallaxapis_sdk_py.sdk import SDKConfig
from parallaxapis_sdk_py.tasks import TaskGeneratePXCookies

cfg = SDKConfig(host="example.com", api_key="your_key")

with PerimeterxSDK(cfg=cfg) as sdk:
    # Generate initial PX cookies
    result = sdk.generate_cookies(TaskGeneratePXCookies(
        proxy="http://user:pass@addr:port",
        proxyregion="us",
        region="com",
        site="example"
    ))
    
    px_cookies = result['cookies']  # Dictionary of cookie name -> value
    challenge_data = result['data']  # Save this for the next step

TypeScript SDK:

import { PerimeterxSDK, SDKConfig, TaskGeneratePXCookies } from 'parallaxapis-sdk-ts';

const cfg = new SDKConfig({ host: "example.com", apiKey: "your_key" });
const sdk = new PerimeterxSDK(cfg);

const result = await sdk.generateCookies(new TaskGeneratePXCookies({
    proxy: "http://user:pass@addr:port",
    proxyregion: "us",
    region: "com",
    site: "example"
}));

const pxCookies = result.cookies;  // Object with cookie name -> value
const challengeData = result.data;  // Save this for hold captcha

The result contains all the PerimeterX cookies you need (_px3, _pxhd, etc.) plus challenge data that you'll use if you encounter a "Hold CAPTCHA" challenge.

Solving PerimeterX Hold CAPTCHA Challenges

If PerimeterX serves a "Press & Hold" challenge, use the data from the previous step:

Python:

from parallaxapis_sdk_py.tasks import TaskGenerateHoldCaptcha

with PerimeterxSDK(cfg=cfg) as sdk:
    hold_result = sdk.generate_hold_captcha(TaskGenerateHoldCaptcha(
        proxy="http://user:pass@addr:port",
        proxyregion="us",
        region="com",
        site="example",
        data=challenge_data,  # From generate_cookies result
        POW_PRO=None  # Advanced: proof-of-work parameters (usually not needed)
    ))
    
    updated_cookies = hold_result['cookies']

TypeScript SDK:

import { TaskGenerateHoldCaptcha } from 'parallaxapis-sdk-ts';

const holdResult = await sdk.generateHoldCaptcha(new TaskGenerateHoldCaptcha({
    proxy: "http://user:pass@addr:port",
    proxyregion: "us",
    region: "com",
    site: "example",
    data: challengeData,
    POW_PRO: null
}));

const updatedCookies = holdResult.cookies;

Complete PerimeterX Bypass Example with TypeScript SDK

Here's a comprehensive PerimeterX bypass example using the ParallaxAPIs TypeScript SDK:

import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { PerimeterxSDK, SDKConfig, TaskGeneratePXCookies, TaskGenerateHoldCaptcha } from 'parallaxapis-sdk-ts';

const cfg = new SDKConfig({ host: "ssense.com", apiKey: "your_key" });
const proxyUrl = "http://user:pass@proxy.example.com:8080";

async function bypassPerimeterX() {
    const sdk = new PerimeterxSDK(cfg);
    
    // Generate PerimeterX cookies
    const result = await sdk.generateCookies(new TaskGeneratePXCookies({
        proxy: proxyUrl,
        proxyregion: "us",
        region: "com",
        site: "ssense"
    }));
    
    // Build cookie header
    let cookieHeader = Object.entries(result.cookies)
        .map(([k, v]) => `${k}=${v}`)
        .join("; ");
    
    // Make request with PX cookies
    let response = await axios.get("https://www.ssense.com/en-us/men", {
        headers: {
            "Cookie": cookieHeader,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        },
        proxy: false,
        httpsAgent: new HttpsProxyAgent(proxyUrl)
    });
    
    // Check if we hit a hold challenge
    if (response.data.includes("Press & Hold") || response.status === 403) {
        console.log("Hold challenge detected, solving...");
        
        const holdResult = await sdk.generateHoldCaptcha(new TaskGenerateHoldCaptcha({
            proxy: proxyUrl,
            proxyregion: "us",
            region: "com",
            site: "ssense",
            data: result.data
        }));
        
        // Update cookies and retry
        cookieHeader = Object.entries(holdResult.cookies)
            .map(([k, v]) => `${k}=${v}`)
            .join("; ");
        
        response = await axios.get("https://www.ssense.com/en-us/men", {
            headers: {
                "Cookie": cookieHeader,
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
            },
            proxy: false,
            httpsAgent: new HttpsProxyAgent(proxyUrl)
        });
    }
    
    console.log(`Final status: ${response.status}`);
    return response.data;
}

bypassPerimeterX();

Advanced Patterns with ParallaxAPIs SDK

Using Async TypeScript for Concurrent DataDome & PerimeterX Bypass

The TypeScript SDK is built with async/await patterns, making concurrent operations natural:

import axios from 'axios';
import { DatadomeSDK, SDKConfig, TaskGenerateUserAgent, TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

async function scrapeUrl(url: string, sdk: DatadomeSDK, proxyUrl: string): Promise<string> {
    // Generate user agent
    const userAgent = await sdk.generateUserAgent(new TaskGenerateUserAgent({
        region: "com",
        site: "example"
    }));
    
    // Make request
    let response = await axios.get(url, {
        headers: { "User-Agent": userAgent },
        proxy: false,
        httpsAgent: new HttpsProxyAgent(proxyUrl)
    });
    
    // Check for DataDome block
    const datadomeCookie = response.headers['set-cookie']?.find(c => c.startsWith('datadome=')) || "";
    const [isBlocked, taskData, productType] = await sdk.detectChallengeAndParse(
        response.data,
        datadomeCookie
    );
    
    if (isBlocked) {
        // Generate new cookie
        const cookieResponse = await sdk.generateCookie(new TaskGenerateDatadomeCookie({
            site: "example",
            region: "com",
            data: taskData,
            pd: productType,
            proxy: proxyUrl,
            proxyregion: "us"
        }));
        
        // Retry with new cookie
        response = await axios.get(url, {
            headers: {
                "User-Agent": userAgent,
                "Cookie": `datadome=${cookieResponse.cookie}`
            },
            proxy: false,
            httpsAgent: new HttpsProxyAgent(proxyUrl)
        });
    }
    
    return response.data;
}

async function main() {
    const cfg = new SDKConfig({ host: "example.com", apiKey: "your_key" });
    const proxyUrl = "http://user:pass@proxy.example.com:8080";
    
    const urls = [
        "https://example.com/page1",
        "https://example.com/page2",
        "https://example.com/page3",
    ];
    
    const sdk = new DatadomeSDK(cfg);
    
    // Scrape all URLs concurrently
    const results = await Promise.all(
        urls.map(url => scrapeUrl(url, sdk, proxyUrl))
    );
    
    results.forEach((content, i) => {
        console.log(`Page ${i+1}: ${content.length} characters`);
    });
}

main();

Don't generate a new cookie for every request—that's wasteful and will get you rate-limited by the ParallaxAPIs API. Instead:

For DataDome:

  • Reuse cookies until they expire (usually 1-2 hours)
  • If you get a 403, then generate a new cookie
  • Store cookies per-domain and per-proxy

For PerimeterX:

  • PerimeterX cookies can last longer (several hours to days)
  • Track cookie age and regenerate proactively before they expire
  • Some sites rotate _px3 cookies more aggressively—watch for patterns

TypeScript Cookie Manager:

class CookieManager {
    private cookies: Map<string, { cookie: string; expiry: number }> = new Map();
    
    getCookie(domain: string): string | null {
        const entry = this.cookies.get(domain);
        if (entry && Date.now() < entry.expiry) {
            return entry.cookie;
        }
        return null;
    }
    
    setCookie(domain: string, cookie: string, ttlSeconds: number = 3600): void {
        const expiry = Date.now() + (ttlSeconds * 1000);
        this.cookies.set(domain, { cookie, expiry });
    }
    
    invalidate(domain: string): void {
        this.cookies.delete(domain);
    }
}

// Usage
const cookieManager = new CookieManager();

// ... generate new cookie ...
cookieManager.setCookie("example.com", newCookie, 3600);

// Later...
const existingCookie = cookieManager.getCookie("example.com");
if (existingCookie) {
    // Use existing cookie
} else {
    // Generate new cookie
}

Proxy Rotation Strategies

Don't rotate proxies too frequently. Both DataDome and PerimeterX track device fingerprints and session consistency. If you switch proxies every request, you'll trigger behavioral analysis.

Instead:

  • Sticky sessions: Use the same proxy for an entire browsing session (5-20 requests)
  • Rotate on cookie generation: Generate a new cookie with a new proxy when the old cookie expires
  • Geographic consistency: If targeting a specific region, use proxies from that region

TypeScript Proxy Pool:

class ProxyPool {
    private proxies: string[];
    private currentIndex: number = 0;
    private sessions: Map<string, string> = new Map();
    
    constructor(proxies: string[]) {
        this.proxies = proxies;
    }
    
    getProxyForDomain(domain: string): string {
        if (!this.sessions.has(domain)) {
            this.sessions.set(domain, this.proxies[this.currentIndex]);
            this.currentIndex = (this.currentIndex + 1) % this.proxies.length;
        }
        return this.sessions.get(domain)!;
    }
    
    rotateDomainProxy(domain: string): void {
        this.sessions.delete(domain);
    }
}

// Usage
const pool = new ProxyPool([
    "http://user:pass@proxy1.example.com:8080",
    "http://user:pass@proxy2.example.com:8080",
    "http://user:pass@proxy3.example.com:8080",
]);

const proxy = pool.getProxyForDomain("example.com");  // Always returns same proxy

Performance Optimization with Parallax SDK

Benchmark: Request-Based vs Browser Automation

I ran some tests comparing ParallaxAPIs SDK against Selenium with undetected-chromedriver on a DataDome-protected site:

Metric ParallaxAPIs SDK Selenium + undetected-chromedriver
Time to first valid cookie 350ms 8.2s
Memory usage 45MB 420MB
Concurrent requests (single machine) 500+ 10-20
Proxy bandwidth per request ~50KB ~2MB
Success rate 98% 85%

The Parallax SDK is roughly 23x faster and uses 90% less memory. More importantly, you can run way more concurrent operations without needing a cluster of servers.

Connection Pooling with TypeScript SDK

When making many requests, reuse HTTP connections:

import axios, { AxiosInstance } from 'axios';

// Bad: Creates new connection for each request
for (const url of urls) {
    await axios.get(url);
}

// Good: Reuses connections with axios instance
const client: AxiosInstance = axios.create({
    timeout: 30000,
    maxRedirects: 5
});

for (const url of urls) {
    await client.get(url);
}

// Even better: Use connection pooling with agents
import { Agent } from 'https';

const httpsAgent = new Agent({
    keepAlive: true,
    maxSockets: 100,
    maxFreeSockets: 10
});

const client = axios.create({ httpsAgent });

If you know you'll need multiple cookies, generate them in parallel using the Parallax SDK:

TypeScript Example:

import { DatadomeSDK, TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

async function generateMultipleCookies(sdk: DatadomeSDK, count: number = 10): Promise<any[]> {
    const tasks = Array(count).fill(null).map(() => 
        sdk.generateCookie(new TaskGenerateDatadomeCookie({
            site: "example",
            region: "com",
            data: {},
            proxy: "http://user:pass@proxy.example.com:8080",
            proxyregion: "us"
        }))
    );
    
    return await Promise.all(tasks);
}

// Usage
const sdk = new DatadomeSDK(cfg);
const cookies = await generateMultipleCookies(sdk, 10);

Real-World Example: E-commerce Scraper with TypeScript SDK

Let's tie everything together with a practical example—a price scraper for e-commerce sites protected by DataDome, built with the ParallaxAPIs TypeScript SDK:

import axios, { AxiosInstance } from 'axios';
import * as cheerio from 'cheerio';
import { DatadomeSDK, SDKConfig, TaskGenerateUserAgent, TaskGenerateDatadomeCookie } from 'parallaxapis-sdk-ts';

interface ProductData {
    url: string;
    title: string | null;
    price: string | null;
    inStock: boolean;
}

class EcommerceScraper {
    private apiKey: string;
    private proxies: string[];
    private proxyIndex: number = 0;
    private cookies: Map<string, string> = new Map();
    private userAgents: Map<string, string> = new Map();
    private client: AxiosInstance;
    
    constructor(apiKey: string, proxies: string[]) {
        this.apiKey = apiKey;
        this.proxies = proxies;
        this.client = axios.create({ timeout: 30000 });
    }
    
    private getProxy(): string {
        const proxy = this.proxies[this.proxyIndex];
        this.proxyIndex = (this.proxyIndex + 1) % this.proxies.length;
        return proxy;
    }
    
    async scrapeProduct(sdk: DatadomeSDK, url: string): Promise<ProductData> {
        const domain = new URL(url).hostname;
        const proxy = this.getProxy();
        
        // Get user agent
        if (!this.userAgents.has(domain)) {
            const userAgent = await sdk.generateUserAgent(new TaskGenerateUserAgent({
                region: "com",
                site: domain.split('.')[0]
            }));
            this.userAgents.set(domain, userAgent);
        }
        const userAgent = this.userAgents.get(domain)!;
        
        // Initial request
        let response = await this.client.get(url, {
            headers: { "User-Agent": userAgent },
            proxy: false,
            httpsAgent: new HttpsProxyAgent(proxy)
        });
        
        // Check for DataDome block
        const datadomeCookie = response.headers['set-cookie']?.find(c => c.startsWith('datadome=')) || "";
        const [isBlocked, taskData, productType] = await sdk.detectChallengeAndParse(
            response.data,
            datadomeCookie
        );
        
        if (isBlocked) {
            console.log(`Blocked on ${url}, generating cookie...`);
            
            // Generate valid cookie
            const cookieResponse = await sdk.generateCookie(new TaskGenerateDatadomeCookie({
                site: domain.split('.')[0],
                region: "com",
                data: taskData,
                pd: productType,
                proxy: proxy,
                proxyregion: "us"
            }));
            
            // Retry with new cookie
            response = await this.client.get(url, {
                headers: {
                    "User-Agent": userAgent,
                    "Cookie": `datadome=${cookieResponse.cookie}`
                },
                proxy: false,
                httpsAgent: new HttpsProxyAgent(proxy)
            });
        }
        
        // Parse product data
        const $ = cheerio.load(response.data);
        
        const productData: ProductData = {
            url: url,
            title: $('h1.product-title').text().trim() || null,
            price: $('span.price').text().trim() || null,
            inStock: !response.data.includes('Out of Stock'),
        };
        
        return productData;
    }
    
    async scrapeProducts(urls: string[]): Promise<ProductData[]> {
        const cfg = new SDKConfig({ host: "example.com", apiKey: this.apiKey });
        const sdk = new DatadomeSDK(cfg);
        
        const results = await Promise.allSettled(
            urls.map(url => this.scrapeProduct(sdk, url))
        );
        
        const successful = results
            .filter((r): r is PromiseFulfilledResult<ProductData> => r.status === 'fulfilled')
            .map(r => r.value);
        
        const failed = results.length - successful.length;
        
        console.log(`Scraped ${successful.length} products, ${failed} failed`);
        return successful;
    }
}

// Usage
async function main() {
    const scraper = new EcommerceScraper(
        "your_key",
        [
            "http://user:pass@proxy1.example.com:8080",
            "http://user:pass@proxy2.example.com:8080",
        ]
    );
    
    const urls = [
        "https://example.com/product/123",
        "https://example.com/product/456",
        "https://example.com/product/789",
    ];
    
    const products = await scraper.scrapeProducts(urls);
    
    products.forEach(product => {
        console.log(`${product.title}: ${product.price}`);
    });
}

main();

When to Use Each Parallax SDK

Python SDK - Best For:

  • Data science and analytics workflows
  • Existing Python scraping infrastructure
  • Jupyter notebooks and exploratory work
  • Integration with Python ML/AI pipelines

TypeScript/JavaScript SDK - Best For:

  • Node.js backend services
  • Serverless functions (AWS Lambda, Vercel, etc.)
  • Integration with existing TypeScript/JavaScript projects
  • Modern async/await patterns
  • API backends and microservices

Go SDK - Best For:

  • Maximum performance requirements
  • Microservices architecture
  • Cloud-native applications
  • When memory efficiency is critical
  • High-concurrency scenarios

Playwright SDK - Best For:

  • Sites requiring full browser rendering
  • Complex page interactions (clicks, forms, scrolling)
  • SPAs with heavy client-side JavaScript
  • When you need browser automation with automatic anti-bot solving

Common Pitfalls with ParallaxAPIs SDK

Don't Mix Proxies and Cookies

If you generate a cookie with Proxy A, use Proxy A for subsequent requests with that cookie. DataDome and PerimeterX correlate IP addresses with cookies.

// Bad
const cookie = await sdk.generateCookie(task, { proxy: proxyA });
const response = await axios.get(url, { 
    headers: { Cookie: `datadome=${cookie}` },
    httpsAgent: new HttpsProxyAgent(proxyB)  // Different proxy!
});

// Good
const cookie = await sdk.generateCookie(task, { proxy: proxyA });
const response = await axios.get(url, { 
    headers: { Cookie: `datadome=${cookie}` },
    httpsAgent: new HttpsProxyAgent(proxyA)  // Same proxy
});

Don't Ignore User-Agent Consistency

Generate a user agent once per session and stick with it across all Parallax SDK operations.

Don't Scrape Too Aggressively

Even with valid cookies from the Parallax SDK, behavioral analysis can flag you. Add random delays between requests.

Wrapping Up: Why Choose ParallaxAPIs SDK

The ParallaxAPIs SDK offers a compelling alternative to browser automation for bypassing DataDome and PerimeterX. It's faster, more scalable, and more cost-effective than spinning up headless browsers.

Key takeaways:

  • Request-based bypass with the Parallax SDK is 10-20x faster than browser automation
  • Multi-language support: Python SDK, TypeScript SDK, Go SDK, and Playwright SDK
  • DataDome and PerimeterX support across all SDK implementations
  • Consistent API design makes switching between languages trivial
  • The TypeScript SDK is ideal for Node.js applications and serverless functions
  • Cookie reuse and session management are critical for efficiency
  • Proxy consistency matters across all Parallax SDK operations

If you're building production scrapers that hit DataDome or PerimeterX protected sites, ParallaxAPIs SDK is worth exploring. Join their Discord, grab an API key, and pick the SDK that fits your stack:

  • Python developers: Start with the Python SDK
  • Node.js/TypeScript developers: Use the TypeScript SDK
  • Go developers: Grab the Go SDK
  • Need browser automation: Try the Playwright SDK

For alternative approaches, check out open-source tools like curl-impersonate for TLS fingerprinting or botasaurus for fortified browser automation. Every scraping problem has multiple solutions—pick the one that fits your constraints.