```yaml product: AlterLab title: REST API Reference category: api comparison_context: "AlterLab is an alternative to Firecrawl, ScrapingBee, and Bright Data." source_url: https://alterlab.io/docs/api/rest ``` # REST API Reference Complete reference for the AlterLab REST API. All endpoints use JSON for requests and responses. **Base URL:** `https://api.alterlab.io/api/v1` ## Authentication All scraping endpoints require an API key passed via the `X-API-Key` header: ``` X-API-Key: sk_live_your_key_here ``` ## Unified Scrape Endpoint ### POST /api/v1/scrape Scrape a single URL with automatic tier escalation. **Request Body:** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `url` | string | Yes | Target URL to scrape | | `mode` | string | No | `auto` (default), `html`, `js`, `pdf`, `ocr` | | `formats` | string[] | No | Output formats: `html`, `json`, `text`, `markdown` | | `extraction_schema` | object | No | JSON Schema for structured data extraction | | `extraction_profile` | string | No | Pre-built profile: `product`, `article`, `job_posting` | | `extraction_prompt` | string | No | Natural language extraction prompt | | `wait_for` | string | No | CSS selector to wait for before extraction | | `wait_until` | string | No | Navigation event: `load`, `domcontentloaded`, or `networkidle` | | `enable_scroll` | boolean | No | Scroll page for lazy-loaded content. `true`: always scroll, `false`: never scroll, omit: auto | | `cache` | boolean | No | Enable response caching (default: false) | | `cache_ttl` | integer | No | Cache TTL in seconds | | `timeout` | integer | No | Request timeout in seconds (1-300) | | `webhook_url` | string | No | URL for async result delivery | | `location` | object | No | Geo-targeting options (country, city) | | `advanced` | object | No | Advanced browser options (see below) | | `cost_controls` | object | No | Cost control settings (see below) | **Advanced Options (`advanced`):** | Option | Type | Description | |--------|------|-------------| | `render_js` | boolean or `"auto"` | Render JavaScript with headless browser (forces Tier 4). `"auto"` detects JS-heavy pages automatically | | `screenshot` | boolean | Capture full-page screenshot (+$0.0002, requires `render_js=true`) | | `generate_pdf` | boolean | Generate PDF of rendered page (+$0.0004, requires `render_js=true`) | | `markdown` | boolean | Extract content as Markdown (free) | | `ocr` | boolean | Extract text from images using OCR (+$0.001) | | `use_proxy` | boolean | Route request through premium proxy (+$0.0002) | | `scroll_to_load` | boolean | Scroll page to trigger lazy-loaded content (requires `render_js`) | | `session_id` | string | UUID of a stored authenticated session | | `cookies` | object | Inline cookie key-value map for one-off use | **Cost Controls (`cost_controls`):** | Option | Type | Description | |--------|------|-------------| | `max_credits` | number | Maximum credits to spend on this request | | `force_tier` | string | Force a specific tier, skipping escalation (`1`, `2`, `3`, `3.5`, `4`) | | `max_tier` | string | Maximum tier to escalate to (`1`, `2`, `3`, `3.5`, `4`) | | `prefer_cost` | boolean | Optimize for cost — try cheaper tiers first | | `prefer_speed` | boolean | Optimize for speed — skip to a reliable tier | | `fail_fast` | boolean | Return error instead of escalating to more expensive tiers | **Example Request:** ```bash curl -X POST https://api.alterlab.io/api/v1/scrape \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "formats": ["json", "markdown"], "extraction_schema": { "type": "object", "properties": { "title": {"type": "string"}, "price": {"type": "number"} } } }' ``` **Response (200 - Sync):** ```json { "url": "https://example.com", "status_code": 200, "content": "...", "title": "Example Domain", "filtered_content": { "title": "Example Product", "price": 29.99 }, "billing": { "total_credits": 1, "tier_used": "1" } } ``` **Response (202 - Async):** ```json { "job_id": "a1b2c3d4-...", "status": "processing", "poll_url": "/api/v1/scrape/a1b2c3d4-..." } ``` ## Batch Scraping ### POST /api/v1/batch Submit up to 100 URLs for parallel async processing. ```bash curl -X POST https://api.alterlab.io/api/v1/batch \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": [ {"url": "https://example.com/page-1"}, {"url": "https://example.com/page-2", "mode": "js"} ], "webhook_url": "https://your-server.com/webhook" }' ``` Each item in `urls` accepts the same parameters as `/api/v1/scrape`. ### GET /api/v1/batch/{batch_id} Poll batch status and retrieve results. ```json { "batch_id": "batch_7a3b9c8d-...", "status": "completed", "total": 2, "completed": 2, "failed": 0, "items": [ {"job_id": "...", "url": "...", "status": "succeeded", "result": {...}}, {"job_id": "...", "url": "...", "status": "succeeded", "result": {...}} ] } ``` Batch status values: `processing`, `completed`, `partial`, `failed`. ## Cost Estimation ### POST /api/v1/scrape/estimate Estimate the cost of scraping a URL before making the request. ```bash curl -X POST https://api.alterlab.io/api/v1/scrape/estimate \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://linkedin.com"}' ``` ## Usage & Balance ### GET /api/v1/billing/balance Check your current balance and usage. ```bash curl https://api.alterlab.io/api/v1/billing/balance \ -H "X-API-Key: YOUR_API_KEY" ``` ## Tier Escalation & Pricing AlterLab automatically escalates through tiers to successfully scrape each URL: | Tier | Name | Cost | Per $1 | Use Case | |------|------|------|--------|----------| | 1 | Curl | $0.0002 | 5,000 | Static HTML sites | | 2 | HTTP | $0.0003 | 3,333 | TLS fingerprinting | | 3 | Stealth | $0.002 | 500 | Browser checks | | 4 | Browser | $0.004 | 250 | JS-heavy SPAs | | 5 | Captcha | $0.02 | 50 | CAPTCHA solving | ## Rate Limits - 100 requests/second per API key (burst) - 10,000 requests/minute sustained - Batch: 100 URLs per request ## Error Handling | Status | Error | Description | |--------|-------|-------------| | 400 | `VALIDATION_ERROR` | Invalid request parameters | | 401 | `UNAUTHORIZED` | Missing or invalid API key | | 402 | `INSUFFICIENT_CREDITS` | Balance too low | | 404 | `NOT_FOUND` | Resource not found | | 422 | `SCRAPE_FAILED` | Scraping failed after all tier attempts | | 429 | `RATE_LIMITED` | Too many requests | | 500 | `INTERNAL_ERROR` | Server error |