AlterLabAlterLab
PricingComparePlaygroundBlogDocsChangelog
    AlterLabAlterLab
    PricingComparePlaygroundBlogDocsChangelog
    IntroductionQuickstartInstallationYour First Request
    REST APICrawl APIMap APISearch APISERP APINewExtract APIAIJob PollingAPI KeysSessions APINewEnterprise APIEnterprise
    AccountAutoAlertsAutoAuthAutoBillingAutoCrawlAutoExtractAutoIntegrationsAutoKeysAutoMapAutoMonitorsAutoOrganizationsAutoSchedulesAutoScrapeAutoSearchAutoSessionsAutoUser WebhooksAutoV1 EndpointsAutoWebhooksAuto
    OverviewPythonNode.js
    JavaScript RenderingBrowser ActionsOutput FormatsPDF & OCRCachingWebhooksJSON Schema FilteringWebSocket Real-TimeBring Your Own ProxyProSticky SessionsProAuthenticated ScrapingNewHTTP Methods & BodiesNewStructured ExtractionAIWeb SearchSite MappingWeb CrawlingBatch ScrapingSchedulerChange DetectionCloud Storage ExportSpend LimitsOrganizations & TeamsAlerts & NotificationsExtraction ProfilesAIBYOK ExtractionAIOAuth2 Machine-to-MachineSupport & TicketsUnsupported Targets
    Structured ExtractionAIE-commerce ScrapingNews MonitoringPrice MonitoringMulti-Page CrawlingMonitoring DashboardAI Agent / MCPMCPAI Research AgentAISite CrawlingData Pipeline to Cloud
    E-commerceLead GenerationChange MonitoringRAG & AI PipelinesAIResearch
    PricingRate LimitsError CodesChangelogVersioning
    From FirecrawlFrom ApifyFrom ScrapingBee / ScraperAPIFrom Crawl4AIFrom SpiderFirecrawl v0 API ReferenceLegacy
    OverviewMCP ServerAIn8n NodeLangChainAICrewAIAILlamaIndexAISupabaseChrome ExtensionSoon
    PlaygroundPricingStatus

    Up to 5,000 free requests · No credit card

    Reference

    Rate Limits & Quotas

    Understand AlterLab's rate limits, concurrency caps, and payload restrictions to optimize your integration.

    Rate Limits

    Rate limits are applied per account and scale with your account balance. All API keys on the same account share one limit, so adding keys does not raise it:

    TierBalanceRequests/MinuteBurst After Idle
    Free$0 - $53030
    Basic$5 - $506060
    Growth$50 - $200100100
    Scale$200 - $500300300
    High Volume$500+500500
    EnterpriseCustomup to 10,00010,000

    Bursts

    Limits use a token bucket that holds one minute of requests and refills continuously at your plan's rate. After an idle period you can send a full minute's allowance at once, and capacity keeps refilling as you go, so the first minute after idle can admit up to about twice the per-minute number. Sustained traffic is held to the per-minute rate; requests beyond it receive a 429 with an exact Retry-After.

    Enterprise Access

    Enterprise tier (10,000 RPM / 500 concurrent) is granted by request — it is not unlocked by balance alone. Email support@alterlab.io with your use case and expected request volume to get the is_enterprise flag enabled on your account.

    POST Rate Limits

    Scrapes whose target request uses POST, PUT, PATCH or DELETE (the method you ask AlterLab to send to the target site) are metered by a separate per-account bucket at half your tier's rate. GET scrapes are not charged against it, so submitting a GET scrape with POST /v1/scrape counts against the GET limit. In a batch, each item counts against the bucket for its own target method. SERP and batch search queries are metered by the POST bucket, one token per query.

    TierGET Target (RPM)POST/PUT/PATCH/DELETE Target (RPM)
    Free3015
    Basic6030
    Growth10050
    Scale300150
    High Volume500250
    Enterprise10,0005,000

    Polling Has Its Own Allowance

    Job status and polling endpoints use a separate per-account read allowance of 6× your tier's per-minute rate (at least 120 per minute), so polling never uses up the requests you need to submit work.

    Auth Rate Limits

    Authentication and account management endpoints are protected by stricter per-IP limits to prevent abuse, independent of your API key tier:

    EndpointLimitWindow
    POST /auth/register3 requests1 hour
    POST /auth/login5 requests15 minutes
    POST /auth/forgot-password3 requests1 hour
    POST /scrape/demo10 requests1 hour

    Per-IP Enforcement

    Auth rate limits are enforced per source IP address, not per API key. Exceeding these limits returns a 429 with a Retry-After header indicating when the window resets.

    Concurrency Limits

    Maximum number of requests that can be processed simultaneously. Add funds to instantly unlock higher limits:

    Account BalanceTierConcurrent RequestsRequests/Minute
    $0 - $5Free330
    $5 - $50Basic1060
    $50 - $200Growth15100
    $200 - $500Scale25300
    $500+High Volume50500
    EnterpriseEnterpriseup to 500up to 10,000

    Instant Upgrades

    Tier upgrades are instant. Add funds to your account and immediately get higher concurrency limits—no waiting period.

    Payload Limits

    Limit TypeValueNotes
    Request Body Size1 MBMaximum size of JSON request
    Response Size50 MBMaximum scraped content size
    URL Length8,192 charsMaximum URL length
    Headers Size32 KBTotal custom headers size
    Extraction Schema64 KBMaximum JSON schema size
    Extraction Prompt4,000 charsMaximum prompt length

    Timeout Limits

    OperationDefaultMaximum
    Sync Request85 seconds85 seconds
    Sync Polling (internal)85 seconds85 seconds
    Async Job300 seconds600 seconds
    Wait for Selector30 seconds60 seconds
    PDF/OCR Processing120 seconds300 seconds

    Long-Running Jobs

    For operations that may exceed 85 seconds, use sync: false to get a job ID and poll for results.

    Batch Limits

    LimitValue
    URLs per batch request1,000
    Concurrent batches5
    Batch result retention24 hours

    Scrape Dispatch Limits

    Scrape, crawl, batch, scheduled, and workflow dispatch all use the same balance tier as request-rate limiting. Adding funds updates the tier immediately; no subscription is required. Dispatch concurrency matches the account concurrency entitlement, and new jobs are admitted at your tier's requests-per-minute rate.

    Account TierJobs/MinuteMax In-Flight
    Free303
    Basic6010
    Growth10015
    Scale30025
    High Volume50050
    Enterprise10,000500

    One canonical account policy

    Concurrency against a single target domain is bounded only by your account concurrency limit. A platform safety rail exists as an operational backstop, but it is never lower than your tier's limit. Target pacing adapts on our side and does not reject your requests.

    429 Response When Over a Limit

    Every rate limit (request rate, concurrency, crawl slots, extraction, dispatch entitlement) returns an HTTP 429 with the same structured body describing exactly which limit was hit. Limit-specific fields (such as in_flight) are added inside detail:

    429 Response Body
    JSON
    {
      "error": "rate_limit_exceeded",
      "message": "You have reached your account tier's concurrent job limit.",
      "detail": {
        "scope": "global_concurrent",
        "domain": null,
        "limit": 15,
        "in_flight": 15,
        "requested": 1,
        "accepted": 0,
        "account_tier": "growth",
        "retry_after_seconds": 5
      },
      "docs_url": "https://alterlab.io/docs/reference/limits"
    }

    Every dispatch response also carries headroom headers so you can track your entitlement without waiting for a 429:

    Bash
    X-Dispatch-Entitlement-Limit: 15
    X-Dispatch-Entitlement-Remaining: 4
    X-Dispatch-Entitlement-Reset: 5
    Retry-After: 5  # Only on 429 responses

    Batch requests (POST /v1/batch) accept and reject items individually: a batch that partially exceeds entitlement still returns HTTP 202 with the accepted URLs dispatched and the rejected ones listed with a per-item reason — you are never charged for a rejected item.

    Rate Limit Headers

    Requests checked against a per-account request bucket (scrape, batch, crawl and other job submissions) return your remaining headroom on success. Every 429 carries the headers of the limit that was hit:

    Response Headers
    Bash
    RateLimit-Limit: 60
    RateLimit-Remaining: 45
    RateLimit-Reset: 12
    X-RateLimit-Limit: 60        # 429 responses
    X-RateLimit-Window: 60       # Only on 429 responses
    X-RateLimit-Scope: account   # Only on 429 responses
    Retry-After: 12              # Only on 429 responses
    X-Concurrency-Limit: 10
    X-Concurrency-Remaining: 8   # Successful scrapes
    X-Concurrency-Current: 10    # Concurrency 429s
    RateLimit-LimitMaximum requests per minute (X-RateLimit-Limit is kept for compatibility). Sent only for request-rate limits; spend, concurrency, crawl-slot and dispatch limits report their value in the error body (detail.limit) and X-Limit-Type, X-Concurrency-* or X-Dispatch-Entitlement-* headers instead
    RateLimit-RemainingRequests you can send right now before being limited (request-rate limits only)
    RateLimit-ResetOn a 429, seconds until a retry can succeed (equals Retry-After). On a successful response, seconds until the request quota is fully replenished. Spend-limit resets are in detail.reset_at
    Retry-AfterWhole seconds to wait before retrying, computed from the real reset time (429 only)
    X-RateLimit-ScopeWhich limit was hit, for example account, org or ip (429 only)

    Handling Rate Limits

    1. Check Headers

    Monitor RateLimit-Remaining and slow down before hitting the limit.

    2. Implement Exponential Backoff

    On 429 errors, wait and retry with increasing delays: 1s, 2s, 4s, 8s...

    Python
    import time
    
    def scrape_with_retry(url, max_retries=5):
        for attempt in range(max_retries):
            response = requests.post(...)
            if response.status_code == 429:
                # Prefer the server's exact wait; fall back to exponential backoff
                wait = int(response.headers.get("Retry-After", 2 ** attempt))
                time.sleep(wait)
                continue
            return response
        raise Exception("Max retries exceeded")

    3. Use Batching

    A batch replaces many HTTP round trips with one call. Each item still counts against your per-minute limit, so size batches to fit your tier's rate.

    4. Queue Requests

    Use a job queue (Redis, RabbitMQ) to throttle requests and handle retries gracefully.

    Increasing Limits

    Add Funds

    Your limits automatically increase as your account balance grows. See the tier tables above.

    Enterprise Plans

    For custom limits, dedicated infrastructure, or SLA guarantees, contact our sales team.

    Need Higher Limits?

    Email support@alterlab.io with your use case and we'll work with you on custom limits.
    PricingError Codes
    Last updated: June 2026

    On this page