@builde2e/sdk
v1.6.9
Published
Official BuildE2E SDK - Extract data from any website with a single API call
Downloads
171
Maintainers
Readme

@builde2e/sdk
Official Node.js/Browser SDK for the BuildE2E API. Extract data from any website with a single API call.
Installation
npm install @builde2e/sdkOr with yarn:
yarn add @builde2e/sdkQuick Start
import BuildE2E from '@builde2e/sdk';
// Set your API key (get one at https://builde2e.com)
BuildE2E.setApiKey('uc-your-api-key');
// Fetch a webpage
const result = await BuildE2E.fetch({
url: 'https://example.com',
type: 'markdown'
});
console.log(result.markdown);Usage
Setting API Key
The API key must be set before making any requests:
import BuildE2E from '@builde2e/sdk';
BuildE2E.setApiKey('uc-your-api-key');Or using named imports:
import { setApiKey } from '@builde2e/sdk';
setApiKey('uc-your-api-key');Fetching a Single URL
import BuildE2E from '@builde2e/sdk';
BuildE2E.setApiKey('uc-your-api-key');
const result = await BuildE2E.fetch({
url: 'https://example.com',
type: 'markdown', // 'markdown' or 'html'
onlyMainContent: true, // Remove nav, ads, footers
extractMetadata: true // Get title, description, etc.
});
console.log(result.markdown);
console.log(result.metadata?.title);Batch Fetching
Fetch multiple URLs in a single request:
const result = await BuildE2E.batchFetch({
urls: [
'https://example.com/page1',
'https://example.com/page2',
// You can also pass detailed options per URL:
{ url: 'https://example.com/page3', type: 'html' }
],
type: 'markdown'
});
console.log(`Fetched ${result.successful} of ${result.total} pages`);
result.results.forEach(page => {
if (page.success) {
console.log(`${page.url}: ${page.markdown?.length} chars`);
} else {
console.log(`${page.url}: Failed - ${page.error}`);
}
});Generate PDF from HTML
Generate a PDF from HTML content:
const result = await BuildE2E.generatePdf({
html: '<html><body><h1>Invoice</h1><p>Total: $500</p></body></html>',
title: 'invoice-123',
pageSize: 'A4',
printBackground: true,
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' }
});
console.log(result.url); // Download URL for the PDFGenerate PDF from URL
Generate a PDF from any webpage:
const result = await BuildE2E.generatePdfFromUrl({
url: 'https://example.com/report',
title: 'report',
pageSize: 'Letter',
landscape: true
});
console.log(result.url); // Download URL for the PDFExecute Code
Run code in an isolated sandbox environment:
const result = await BuildE2E.executeCode({
code: 'print("Hello, World!")',
language: 'python'
});
console.log(result.stdout); // "Hello, World!\n"
console.log(result.exitCode); // 0
console.log(result.executionTimeMs); // 95.23
console.log(result.memoryUsageMb); // 8.45Each execution runs in its own isolated subprocess inside a Kata micro-VM with no network access. Code is cleaned up immediately after execution.
// Multi-line code with imports
const result = await BuildE2E.executeCode({
code: `
import json
data = {"name": "BuildE2E", "version": 1}
print(json.dumps(data, indent=2))
`,
language: 'python'
});
console.log(result.stdout);
// {
// "name": "BuildE2E",
// "version": 1
// }Screenshot
Capture a screenshot of any web page:
const result = await BuildE2E.screenshot({
url: 'https://example.com',
fullPage: true, // Capture full page (default) or viewport only
width: 1920, // Viewport width (320-3840, default 1920)
height: 1080, // Viewport height (240-2160, default 1080)
waitFor: 2000, // Extra wait in ms after page load (0-30000)
});
console.log(result.url); // URL to the uploaded screenshot imageCapture a specific element or execute actions before screenshotting:
const result = await BuildE2E.screenshot({
url: 'https://example.com/dashboard',
selector: '.chart-container', // Screenshot only this element
actions: [
{ type: 'click', selector: '.load-data' },
{ type: 'wait', milliseconds: 3000 },
],
});Map (URL Discovery)
Discover all URLs on a website via sitemaps, robots.txt, and HTML link extraction:
const result = await BuildE2E.map({
url: 'https://example.com',
limit: 200, // Max URLs to return (1-5000, default 100)
includeSubdomains: false, // Include subdomain URLs (default false)
ignoreQueryParameters: true, // Strip query params for dedup (default true)
});
console.log(result.links); // ["https://example.com/page1", "https://example.com/page2", ...]
console.log(result.total); // 142Optionally rank URLs by relevance using a keyword:
const result = await BuildE2E.map({
url: 'https://example.com',
search: 'pricing', // URLs matching "pricing" are ranked first
limit: 50,
});Extract (Structured Data)
Extract structured data from one or more web pages using AI:
const result = await BuildE2E.extract({
urls: ['https://example.com/product-1', 'https://example.com/product-2'],
schema: {
type: 'object',
properties: {
name: { type: 'string' },
price: { type: 'number' },
rating: { type: 'number' },
},
required: ['name', 'price'],
},
prompt: 'Extract product name, price in USD, and star rating',
type: 'markdown', // Content format fed to the LLM (default "markdown")
});
console.log(result.data); // { name: "Widget Pro", price: 29.99, rating: 4.5 }
console.log(result.sources); // ["https://example.com/product-1", "https://example.com/product-2"]You can also pass a Zod schema directly — the SDK auto-converts it to JSON Schema:
import { z } from 'zod';
const result = await BuildE2E.extract({
urls: ['https://example.com/product-1'],
schema: z.object({
name: z.string(),
price: z.number(),
rating: z.number(),
}),
prompt: 'Extract product name, price in USD, and star rating',
});Crawl
Recursively crawl a website following links, with depth and path control:
const result = await BuildE2E.crawl({
url: 'https://example.com/blog',
limit: 20, // Max pages to crawl (1-100, default 10)
maxDepth: 2, // Max link depth from start URL (1-10, default 3)
includePaths: ['^/blog/'], // Regex — only crawl matching paths
excludePaths: ['/admin/'], // Regex — skip matching paths
allowSubdomains: false, // Follow subdomain links (default false)
type: 'markdown', // Output format (default "markdown")
onlyMainContent: true, // Strip nav, ads, footers (default true)
});
console.log(`Crawled ${result.completed}/${result.total} pages`);
result.data.forEach(page => {
if (page.success) {
console.log(`[depth ${page.depth}] ${page.url}: ${page.markdown?.length} chars`);
}
});Browser Sessions
Create and manage remote browser sessions for automation with Playwright or Puppeteer:
import BuildE2E from '@builde2e/sdk';
import { chromium } from 'playwright-core';
BuildE2E.setApiKey('uc-your-api-key');
// Create a browser session
const session = await BuildE2E.browser.create({
width: 1280,
height: 720,
headless: false
});
// Connect with Playwright
const browser = await chromium.connectOverCDP(session.wsEndpoint);
const page = browser.contexts()[0].pages()[0];
await page.goto('https://example.com');Check session status and cost:
const details = await BuildE2E.browser.get(session.sessionId);
console.log(details.status); // "active"
console.log(details.totalCost); // 0.02 (visible) or 0.004 (headless)Close a session (browser state is saved automatically):
await BuildE2E.browser.close(session.sessionId);Resume a previously closed session with saved cookies and localStorage:
const resumed = await BuildE2E.browser.resume(session.sessionId);
const browser2 = await chromium.connectOverCDP(resumed.wsEndpoint);
// Browser state (cookies, localStorage) is restoredAsync Batch Fetch
Submit a batch of URLs for asynchronous processing. Returns immediately with a job ID — results are processed in the background.
// Start an async batch job
const job = await BuildE2E.asyncBatchFetch({
urls: [
'https://example.com/page1',
'https://example.com/page2',
{ url: 'https://example.com/page3', type: 'html', summary: { query: 'Extract pricing' } }
],
type: 'markdown'
});
console.log(job.id); // "abc123..."
console.log(job.url); // URL to check statusAsync Single Fetch
Submit a single URL for async processing (useful for long-running scrapes with actions):
const job = await BuildE2E.asyncFetch({
url: 'https://example.com',
type: 'markdown',
actions: [
{ type: 'click', selector: '.load-more' },
{ type: 'wait', milliseconds: 2000 }
]
});Async Sequence
Submit a multi-step sequence for async processing:
const job = await BuildE2E.asyncSequence({
startUrl: 'https://example.com/login',
steps: [
{ type: 'type', selector: '#email', text: '[email protected]' },
{ type: 'click', selector: '#submit' },
{ type: 'wait', milliseconds: 2000 },
{ type: 'scrape' }
]
});Async Sequence Batch
Fan out multiple independent sequences:
const job = await BuildE2E.asyncSequenceBatch({
sequences: [
{ startUrl: 'https://site-a.com', steps: [{ type: 'scrape' }] },
{ startUrl: 'https://site-b.com', steps: [{ type: 'scrape' }] },
]
});Polling Job Status
Check the status and retrieve results of an async job:
const status = await BuildE2E.getJobStatus(job.id);
console.log(status.status); // "pending" | "processing" | "completed" | "failed" | "cancelled"
console.log(status.total); // Total items in the job
console.log(status.completed); // Items completed so far
console.log(status.data); // Array of results (populated as items complete)Wait for Completion
Block until a job reaches a terminal state:
const result = await BuildE2E.waitForJob(job.id, {
pollIntervalMs: 3000, // Check every 3 seconds (default: 2000)
timeoutMs: 300000 // Give up after 5 minutes (default: 600000)
});
console.log(result.status); // "completed" | "failed" | "cancelled"
console.log(result.data); // All resultsList Jobs
List all async jobs for the authenticated user:
const jobs = await BuildE2E.listJobs({
page: 1,
limit: 20,
type: 'scrape-batch' // Filter: "scrape-batch" | "sequence" | etc.
});
console.log(jobs.total); // Total number of jobs
jobs.jobs.forEach(j => {
console.log(`${j.id} — ${j.type} — ${j.status} — ${j.completed}/${j.total}`);
});Cancel a Job
Cancel a running or pending async job:
await BuildE2E.cancelJob(job.id);LLM Summarization
Ask the API to summarize fetched content:
const result = await BuildE2E.fetch({
url: 'https://example.com/product',
type: 'markdown',
summary: {
query: 'Extract the product name, price, and key features in JSON format'
}
});
console.log(result.content); // Summarized contentLLM Tool Definitions
The SDK includes pre-built tool definitions that you can pass directly to LLMs. Available in two formats:
- Vercel AI SDK — works with
generateText,streamTextfrom theaipackage - OpenAI — works with
chat.completions.createfrom theopenaipackage
Install the peer dependency for whichever format you need:
npm install @builde2e/sdk ai # for Vercel AI SDK
npm install @builde2e/sdk openai # for OpenAIVercel AI SDK
import BuildE2E from '@builde2e/sdk';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
BuildE2E.setApiKey('uc-your-api-key');
// Pass all tools
const { text } = await generateText({
model: openai('gpt-4.1'),
tools: BuildE2E.tools.aiSdk.all,
prompt: 'Fetch the YC top companies page and extract pricing info',
});
// Or pick specific ones
const { text: text2 } = await generateText({
model: openai('gpt-4.1'),
tools: {
fetch: BuildE2E.tools.aiSdk.fetch,
executeCode: BuildE2E.tools.aiSdk.executeCode,
},
prompt: 'Fetch the page and analyze the results',
});OpenAI
import BuildE2E from '@builde2e/sdk';
import OpenAI from 'openai';
BuildE2E.setApiKey('uc-your-api-key');
const client = new OpenAI();
// Pass all tool definitions
const response = await client.chat.completions.create({
model: 'gpt-4.1',
messages: [{ role: 'user', content: 'Fetch the latest AI trends page' }],
tools: BuildE2E.tools.openai.all,
});
// Handle tool calls
for (const toolCall of response.choices[0].message.tool_calls ?? []) {
const result = await BuildE2E.tools.openai.execute(
toolCall.function.name,
JSON.parse(toolCall.function.arguments),
);
console.log(result);
}Available Tools
| Tool | Description |
|------|-------------|
| fetch | Fetch a URL and get clean markdown or HTML content |
| executeCode | Execute Python or JavaScript code in an isolated sandbox |
| screenshot | Capture a screenshot of a web page and get a URL to the image |
| extract | Extract structured data from web pages using AI (returns JSON) |
| map | Discover all URLs on a website via sitemaps and link extraction |
| crawl | Recursively crawl a website following links and return page content |
Configuration
Custom Base URL
For self-hosted instances or testing:
BuildE2E.setBaseUrl('https://your-instance.com/v1');Request Timeout
Set a custom timeout (in milliseconds):
BuildE2E.setTimeout(60000); // 60 secondsConfigure Multiple Options
BuildE2E.configure({
apiKey: 'uc-your-api-key',
baseUrl: 'https://api.builde2e.com/api/v1',
timeout: 120000
});Error Handling
The SDK throws SdkError for API errors:
import BuildE2E, { SdkError } from '@builde2e/sdk';
try {
const result = await BuildE2E.fetch({ url: 'https://example.com' });
} catch (error) {
if (error instanceof SdkError) {
console.error(`Error ${error.status}: ${error.message}`);
console.error(`Code: ${error.code}`);
}
}Common error codes:
| Status | Code | Description |
|--------|------|-------------|
| 401 | UNAUTHORIZED | Invalid or missing API key |
| 403 | FORBIDDEN | Access forbidden |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests |
| 500 | INTERNAL_ERROR | Server error |
TypeScript Support
The SDK includes full TypeScript definitions:
import BuildE2E, {
FetchOptions,
FetchResponse,
// WebSearchOptions, // temporarily removed
// WebSearchResponse, // temporarily removed
BatchFetchOptions,
BatchFetchResponse,
GeneratePdfOptions,
PdfResponse,
ExecuteCodeOptions,
ExecuteCodeResponse,
CreateBrowserSessionOptions,
BrowserSession,
BrowserSessionDetails,
AsyncJobStartResponse,
AsyncJobStatusResponse,
AsyncJobCancelResponse,
AsyncJobListResponse,
AsyncJobSummary,
// AsyncSearchBatchOptions, // temporarily removed
AsyncSequenceBatchOptions,
ScreenshotOptions,
ScreenshotResponse,
MapOptions,
MapResponse,
ExtractOptions,
ExtractResponse,
CrawlOptions,
CrawlPageResult,
CrawlResponse,
} from '@builde2e/sdk';
const options: FetchOptions = {
url: 'https://example.com',
type: 'markdown'
};
const result: FetchResponse = await BuildE2E.fetch(options);Zod Schemas
Every type has a corresponding Zod schema exported for runtime validation:
import {
FetchOptionsSchema,
FetchResponseSchema,
// WebSearchOptionsSchema, // temporarily removed
// WebSearchResponseSchema, // temporarily removed
BatchFetchOptionsSchema,
BatchFetchResponseSchema,
ExecuteCodeOptionsSchema,
ExecuteCodeResponseSchema,
CreateBrowserSessionOptionsSchema,
BrowserSessionSchema,
BrowserSessionDetailsSchema,
ScreenshotOptionsSchema,
ScreenshotResponseSchema,
MapOptionsSchema,
MapResponseSchema,
ExtractOptionsSchema,
ExtractResponseSchema,
CrawlOptionsSchema,
CrawlPageResultSchema,
CrawlResponseSchema,
// ... and more
} from '@builde2e/sdk';
// Validate user input at runtime
const parsed = FetchOptionsSchema.parse(userInput);API Reference
Methods
| Method | Description |
|--------|-------------|
| BuildE2E.setApiKey(key) | Set the API key globally |
| BuildE2E.setBaseUrl(url) | Set custom base URL |
| BuildE2E.setTimeout(ms) | Set request timeout |
| BuildE2E.configure(config) | Configure multiple options at once |
| BuildE2E.getConfig() | Get current config ({ apiKeySet, baseUrl, timeout }) |
| BuildE2E.resetConfig() | Reset configuration to defaults |
| BuildE2E.fetch(options) | Fetch content from a single URL |
| BuildE2E.batchFetch(options) | Fetch content from multiple URLs |
| BuildE2E.generatePdf(options) | Generate PDF from HTML |
| BuildE2E.generatePdfFromUrl(options) | Generate PDF from a URL |
| BuildE2E.executeCode(options) | Execute code in an isolated Code Sandbox |
| BuildE2E.screenshot(options) | Capture a screenshot of a web page |
| BuildE2E.map(options) | Discover URLs from a website (sitemaps + link extraction) |
| BuildE2E.extract(options) | Extract structured data from web pages using AI |
| BuildE2E.crawl(options) | Recursively crawl a website following links |
| BuildE2E.asyncFetch(options) | Start an async single fetch job |
| BuildE2E.asyncBatchFetch(options) | Start an async batch fetch job |
| BuildE2E.asyncSequence(options) | Start an async sequence job |
| BuildE2E.asyncSequenceBatch(options) | Start an async sequence batch job |
| BuildE2E.listJobs(options) | List async jobs (paginated, filterable by type) |
| BuildE2E.getJobStatus(jobId, options) | Get job status and results |
| BuildE2E.cancelJob(jobId) | Cancel a pending or running job |
| BuildE2E.waitForJob(jobId, options) | Poll until job reaches terminal state |
| BuildE2E.browser.create(options) | Create a remote Browser Sandbox session |
| BuildE2E.browser.get(sessionId) | Get Browser Sandbox session details (status, cost) |
| BuildE2E.browser.close(sessionId) | Close a Browser Sandbox session |
| BuildE2E.browser.resume(sessionId) | Resume a closed Browser Sandbox session with saved state |
SdkConfig
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| apiKey | string | No | Your API key |
| baseUrl | string | No | Custom API base URL |
| timeout | number | No | Request timeout in milliseconds |
SummaryQuery
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| query | string | Yes | Query/instruction for content summarization |
FetchOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| url | string | Yes | URL to scrape (required) |
| type | "html" | "markdown" | No | Output format: html or markdown. Defaults to "markdown" |
| onlyMainContent | boolean | No | Extract only main content (removes nav, ads, footers). Defaults to true |
| extractMetadata | boolean | No | Whether to extract page metadata |
| summary | object | No | Summary query for LLM summarization |
| actions | object | object | object | object | object | object | object | object | object | object[] | No | Sequence of browser actions to execute after page load, before content extraction. When provided, lightweight HTTP fetching is skipped. |
| pdfStrategy | "ocr" | "local" | "auto" | No | PDF extraction strategy: ocr (vision-based OCR), local (pdf-parse only), auto (pdf-parse first, OCR if needed). Defaults to "ocr" |
| proxy | object | No | Proxy configuration for geo-targeted requests. Routes through a residential proxy in the specified country. |
FetchMetadata
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| title | string | No | |
| description | string | No | |
| canonicalUrl | string | No | |
| finalUrl | string | No | |
| contentType | string | No | |
| contentLength | number | No | |
FetchResponse
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| url | string | Yes | Original URL that was fetched |
| html | string | null | No | Rendered HTML content (when type is html) |
| markdown | string | null | No | Content converted to Markdown (when type is markdown) |
| statusCode | number | null | Yes | HTTP status code |
| success | boolean | Yes | Whether fetching was successful |
| error | string | No | Error message if fetching failed |
| timestamp | string | Yes | ISO timestamp when fetching completed |
| metadata | object | No | Additional page metadata |
| cost | number | No | Cost in USD for this fetch operation |
| content | string | null | No | Content after summarization (when summary query provided) |
BatchFetchOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| urls | string | object[] | Yes | Array of URLs to fetch (strings or detailed request objects) |
| type | "html" | "markdown" | No | Output format: html or markdown |
| onlyMainContent | boolean | No | Extract only main content (removes nav, ads, footers) |
| summary | object | No | Summary query for LLM summarization |
| pdfStrategy | "ocr" | "local" | "auto" | No | PDF extraction strategy applied to all URLs: ocr (vision-based OCR), local (pdf-parse only), auto (pdf-parse first, OCR if needed). Defaults to "ocr" |
| proxy | object | No | Proxy configuration for geo-targeted requests. Applied to all URLs unless overridden per-URL. |
BatchFetchResponse
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| results | object[] | Yes | Array of fetch results |
| total | number | Yes | Total number of URLs processed |
| successful | number | Yes | Number of successful fetches |
| failed | number | Yes | Number of failed fetches |
| timestamp | string | Yes | Timestamp when batch operation completed |
| cost | number | No | Total cost in USD for all fetch operations |
PdfMargin
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| top | string | No | |
| right | string | No | |
| bottom | string | No | |
| left | string | No | |
GeneratePdfOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| html | string | Yes | Complete HTML content to convert to PDF (required) |
| title | string | No | Title used for the exported filename |
| pageSize | "A4" | "Letter" | "Legal" | No | Page size. Defaults to "A4" |
| landscape | boolean | No | Landscape orientation. Defaults to false |
| margin | object | No | Page margins (e.g., { top: "20mm", right: "20mm", bottom: "20mm", left: "20mm" }) |
| printBackground | boolean | No | Print background graphics and colors. Defaults to true |
| timeoutMs | number | No | Timeout in milliseconds (5000-120000). Defaults to 30000 |
GeneratePdfFromUrlOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| url | string | Yes | URL to navigate to and convert to PDF (required) |
| title | string | No | Title used for the exported filename |
| pageSize | "A4" | "Letter" | "Legal" | No | Page size. Defaults to "A4" |
| landscape | boolean | No | Landscape orientation. Defaults to false |
| margin | object | No | Page margins |
| printBackground | boolean | No | Print background graphics and colors. Defaults to true |
| timeoutMs | number | No | Timeout in milliseconds (5000-120000). Defaults to 30000 |
PdfResponse
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| success | boolean | Yes | Whether PDF generation succeeded |
| url | string | No | Public URL of the generated PDF |
| filename | string | No | Generated filename |
| blobName | string | No | Azure blob path |
| error | string | No | Error message on failure |
| durationMs | number | Yes | Total time taken in milliseconds |
| cost | number | Yes | Cost in USD |
ExecuteCodeOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| code | string | Yes | Code to execute (required) |
| language | "python" | "javascript" | Yes | Language runtime (required) |
ExecuteCodeResponse
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| stdout | string | Yes | Standard output from the executed code |
| stderr | string | Yes | Standard error from the executed code |
| exitCode | number | Yes | Process exit code (0 = success, 124 = timeout) |
| executionTimeMs | number | Yes | Execution time in milliseconds |
| timedOut | boolean | Yes | Whether execution was killed due to timeout |
| memoryUsageMb | number | No | Peak memory usage in megabytes |
| error | string | No | Error message if execution infrastructure failed |
| cost | number | No | Cost in USD for this execution |
ErrorResponse
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| error | object | Yes | |
| statusCode | number | No | |
CreateBrowserSessionOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| width | number | No | Browser viewport width (800-3840). Defaults to 1280 |
| height | number | No | Browser viewport height (600-2160). Defaults to 720 |
| headless | boolean | No | Run browser in headless mode. Defaults to true |
| browser | "camoufox" | "lightpanda" | No | Browser engine. camoufox: full Firefox with VNC support. lightpanda: lightweight CDP headless browser. Defaults to camoufox |
| proxy | boolean | No | Enable residential proxy rotation. Defaults to true |
BrowserSession
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| sessionId | string | Yes | Unique session identifier |
| wsEndpoint | string | Yes | WebSocket URL for connecting with Playwright/Puppeteer |
| liveViewUrl | string | null | Yes | Live view URL for watching the browser in real time (if available) |
| browser | "camoufox" | "lightpanda" | No | Browser engine used for this session |
| affinityCookie | string | No | Affinity cookie for sticky session routing (format: SCRAPER_AFFINITY=xxx) - extracted from response headers |
| createdAt | string | Yes | Session creation timestamp (ISO string) |
| width | number | Yes | Browser viewport width |
| height | number | Yes | Browser viewport height |
| costPerMin | number | No | Cost per minute in USD. Headless: $0.002/min. Visible: $0.01/min. |
License
MIT
