AlterLabAlterLab
PricingComparePlaygroundBlogDocsChangelog
    AlterLabAlterLab
    PricingComparePlaygroundBlogDocsChangelog
    IntroductionQuickstartInstallationYour First Request
    REST APICrawl APIMap APISearch APIExtract APIJob PollingAPI KeysSessions APINew
    OverviewPythonNode.js
    JavaScript RenderingOutput FormatsPDF & OCRCachingWebhooksJSON Schema FilteringWebSocket Real-TimeBring Your Own ProxyProAuthenticated ScrapingNewHTTP Methods & BodiesNewStructured ExtractionAIWeb SearchSite MappingWeb CrawlingBatch ScrapingSchedulerChange DetectionCloud Storage ExportSpend LimitsOrganizations & TeamsAlerts & NotificationsOAuth2 Machine-to-MachineSupport & Tickets
    Structured ExtractionAIE-commerce ScrapingNews MonitoringPrice MonitoringMulti-Page CrawlingMonitoring DashboardAI Agent / MCPMCPAI Research AgentAISite CrawlingData Pipeline to Cloud
    PricingRate LimitsError CodesChangelogVersioning
    From FirecrawlFrom ApifyFrom ScrapingBee / ScraperAPIFrom Crawl4AIFrom SpiderFirecrawl v0 API ReferenceLegacy
    PlaygroundPricingStatus
    Guide

    OAuth2 Machine-to-Machine Authentication

    Connect third-party automation tools to AlterLab using the OAuth2 Authorization Code flow. Designed for server-to-server integrations where a tool needs to act on behalf of a user without storing their password.

    Prerequisites

    You need an AlterLab account with an active session (NextAuth JWT). OAuth2 is pre-configured for the n8n and Zapier integrations. For custom integrations, contact support to request a client_id and client_secret.

    OAuth2 vs API Keys

    AlterLab supports two ways for third-party tools to authenticate: direct API keys and OAuth2. Choose based on your use case.

    AspectDirect API KeyOAuth2
    SetupCopy from dashboard, paste into toolOne-time browser flow — no copy/paste
    Credential exposureKey is visible in tool settingsKey is issued only to the server, never shown in the browser
    Key rotationManualAutomatic on each re-authorization
    Best forScripts, CI/CD, personal automationIntegrations installed by end users (n8n, Zapier, custom apps)

    Access Token = API Key

    The access_token returned by the OAuth2 token endpoint is a real AlterLab API key (sk_live_*). It works identically to a manually created key and can be used with the X-API-Key header on all scraping endpoints.

    How It Works

    AlterLab implements the standard OAuth2 Authorization Code flow in two steps.

    1

    Web app requests an authorization code

    The AlterLab web app calls POST /api/v1/oauth/authorize with the authenticated user's session JWT. AlterLab generates a short-lived (5-minute) authorization code and stores it in Redis.

    2

    Web app redirects to the third-party callback

    The web app appends ?code=...&state=... to the third-party's redirect_uri and navigates the user there. The third-party receives the code in its callback handler.

    3

    Third-party exchanges code for an API key

    The third-party's backend calls POST /api/v1/oauth/token with the code plus its client_id and client_secret. AlterLab validates the code, issues a new API key, and returns it as the access_token. The code is consumed atomically — it cannot be replayed.

    4

    Third-party uses the API key

    The returned access_token is a permanent API key. The third-party stores it and uses it with the X-API-Key header on all subsequent scraping requests.

    Quick Start

    The following examples show the raw API calls. In practice, n8n and Zapier handle steps 1–3 automatically through their credential setup wizard.

    Step 1: Get an Authorization Code

    The web app calls this endpoint with the user's NextAuth session JWT in the Authorization header. No third-party credentials are needed here.

    POST
    /api/v1/oauth/authorize
    Bash
    curl -X POST https://api.alterlab.io/api/v1/oauth/authorize \
      -H "Authorization: Bearer YOUR_NEXTAUTH_JWT" \
      -H "Content-Type: application/json" \
      -d '{
        "client_id": "n8n",
        "redirect_uri": "https://your-n8n.example.com/oauth/callback",
        "state": "random-csrf-token-1234",
        "scope": "scrape",
        "source": "n8n"
      }'

    Response:

    JSON
    {
      "code": "abc123xyz789...",
      "state": "random-csrf-token-1234"
    }
    ParameterRequiredDescription
    client_idYesIdentifier for the third-party app (e.g. n8n)
    redirect_uriYesWhere to redirect after authorization. Must be on the allowed-list (*.alterlab.io or configured redirect URIs).
    stateYesCSRF protection token. Returned unchanged — verify it matches.
    scopeNoPermission scope (default: scrape). Only scrape is currently supported.
    sourceNoHuman-readable label for the integration (used in API key name).

    Step 2: Exchange for an API Key

    The third-party backend calls this endpoint — no user session required. Uses client_id and client_secret for authentication.

    POST
    /api/v1/oauth/token
    Bash
    curl -X POST https://api.alterlab.io/api/v1/oauth/token \
      -H "Content-Type: application/json" \
      -d '{
        "grant_type": "authorization_code",
        "code": "abc123xyz789...",
        "client_id": "n8n",
        "client_secret": "YOUR_CLIENT_SECRET",
        "redirect_uri": "https://your-n8n.example.com/oauth/callback"
      }'

    Response:

    JSON
    {
      "access_token": "sk_live_abc123...",
      "token_type": "bearer",
      "scope": "scrape"
    }

    Codes are single-use

    Authorization codes are consumed atomically on first use and cannot be replayed. If the token exchange fails after the code was consumed, start the authorize flow again to get a fresh code. Codes expire after 5 minutes if not used.

    Step 3: Use the API Key

    The access_token is a standard AlterLab API key. Use it with the X-API-Key header on any scraping endpoint.

    Bash
    curl -X POST https://api.alterlab.io/api/v1/scrape \
      -H "X-API-Key: sk_live_abc123..." \
      -H "Content-Type: application/json" \
      -d '{"url": "https://example.com"}'

    Token Rotation

    AlterLab automatically rotates API keys on each OAuth2 token exchange. When a new token is issued for an integration that already has a key, the previous key is immediately revoked.

    Automatic

    No manual action needed. Re-authorizing the integration (repeating the OAuth2 flow) issues a fresh key and revokes the old one.

    Prevents replay attacks

    A single intercepted exchange cannot compromise a permanent key because the key changes on each authorization.

    No expiry

    The issued API key does not expire. It remains valid until the integration is re-authorized or the key is manually revoked in the dashboard.

    Key naming

    Keys issued via OAuth2 are named automatically: n8n integrations receive the name n8n Integration; other sources receive OAuth (source). You can see them in your dashboard under API Keys.

    Scopes

    Only one scope is currently supported:

    ScopeAccess
    scrapeFull access to all scraping endpoints (scrape, crawl, search, map, extract). Same permissions as a manually created API key.

    Client Configuration

    To register a new OAuth2 client (custom integration), contact [email protected]. You will receive a client_id and client_secret, and your redirect_uri(s) will be added to the allowlist.

    Allowed redirect_uri patterns

    • *.alterlab.io — always allowed
    • localhost and 127.0.0.1 — allowed in non-production environments only
    • Custom domains — must be explicitly added to the allowlist

    Redirect URI validation

    The redirect_uri in the token exchange must exactly match the redirect_uri used in the authorize step. A mismatch returns an invalid_grant error.

    Error Reference

    ErrorHTTPCause
    invalid_client401client_id or client_secret is wrong
    invalid_grant400Authorization code is invalid, expired (5-min TTL), or already used
    unsupported_grant_type400grant_type is not authorization_code
    invalid_grant400redirect_uri in token request does not match the one used in authorize
    OAuth integration is not configured503Server-side OAuth credentials are missing (contact support)
    Alerts & NotificationsSupport & Tickets
    Last updated: March 2026

    On this page