spicrawl-com Browser API

Drive a hosted browser over a DevTools Protocol (CDP) WebSocket.

Operations 2

GET /v1/browser Coming soon. Open a DevTools Protocol (CDP) WebSocket to a cloud browser #
POST /v1/browser/token Coming soon. Mint a single-use connect URL for /v1/browser #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/spicrawl-com:spicrawl-com-browser-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

spicrawl-com-browser-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Spicrawl Com Browser API
  version: 1.0.0
  contact:
    name: Spicrawl support
    url: https://docs.spicrawl.com
  description: 'Operations tagged Browser across 2 of this provider''s published API definitions: spicrawl-openapi.yaml, spicrawl-com-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.spicrawl.com
  description: Production
- url: http://localhost:8080
  description: Local development
security:
- bearerAuth: []
tags:
- name: Browser
  description: Drive a hosted browser over a DevTools Protocol (CDP) WebSocket.
paths:
  /v1/browser:
    get:
      tags:
      - Browser
      operationId: browserConnect
      summary: Coming soon. Open a DevTools Protocol (CDP) WebSocket to a cloud browser
      description: 'Coming soon.

        A WebSocket upgrade, not a JSON endpoint. Connect with any CDP client, using the URL as its browser WebSocket endpoint. Authenticate with, in order of preference: `Authorization: Bearer `

        on the upgrade; a single-use `token` from `POST /v1/browser/token` (60 s, one connection, bound to its

        options — the URL the CLI and MCP return); or the `apikey` query parameter (`api_key` alias), kept for

        ZenRows-style URLs. When `token` is present it is the only credential consulted. Requires the

        `browser` scope.


        Every refusal happens before the upgrade and is an RFC 7807 problem. After the 101 there is no HTTP

        response left; the session ends by closing the TCP connection, never with a close frame or error

        message.


        Why a session ends (recorded server-side, not sent to you):

        `client_closed` (you disconnected, or stopped answering WebSocket pings: the API pings every 15 s and

        closes after 2 unanswered, so a half-open client frees its slot within about 30 s),

        `ttl_expired` (`session_ttl` elapsed; a hard wall, not idle),

        `idle_timeout` (no CDP messages in either direction for the deployment idle timeout, 2 minutes by

        default, measured from the last message; pings and pongs do not count),

        `byte_limit` (the deployment''s per-session traffic cap was reached, if configured),

        `upstream_closed` (the browser went away).


        Pricing: a session costs 8 credits per started minute, the same as one full-browser-rendered page. At

        admission the session HOLDS the price of its whole `session_ttl` against the monthly credit

        allowance (default `session_ttl` 180 s = 24 credits; 60–900 s range = 8–120 credits). At close it

        is charged for the minutes it actually held (rounded up, capped at `session_ttl`''s minutes) and

        the unused part of the hold is returned immediately. A session the platform ends (upstream closed,

        or API shutdown) costs 0; a session that never opens costs 0 and returns its hold.

        While the operator has switched billing off, sessions hold and cost 0.


        Admission, before the upgrade, in this order:

        - Rate limit on session opens per key: 429 `ERR::LIMIT::RATE_LIMITED`, with `X-RateLimit-*` and `Retry-After`.

        - Monthly credit allowance cannot cover the whole `session_ttl` hold: 402 `ERR::LIMIT::QUOTA_EXCEEDED`,

        refused before any browser is leased. A shorter `session_ttl` may fit.

        - Simultaneous sessions per organization (`browser_concurrency`, default 2): 429

        `ERR::LIMIT::CONCURRENCY_EXCEEDED`, `Retry-After: 5`, `Concurrency-Limit`/`Concurrency-Remaining: 0`.

        The slot is held until the socket closes, so always close your browser.

        - If the limiter store is unreachable the session is refused (fail closed): 503

        `ERR::INTERNAL::UNAVAILABLE`, `Retry-After: 10`.

        - No CDP backend on this deployment: 501 `ERR::ENGINE::UNAVAILABLE`, `retryable: false`. Do not retry.


        Rate and concurrency headers appear only on refusals; the 101 is the browser backend''s handshake

        forwarded verbatim.'
      security:
      - bearerAuth: []
      - apiKeyQuery: []
      x-spicrawl-scope: browser
      parameters:
      - name: token
        in: query
        description: A single-use browser token from `POST /v1/browser/token`. Consumed on arrival, whatever happens next; expires 60 s after issue; revoked with the key that minted it. The session options are the ones bound into the token; an option in the URL that differs from (or was not part of) the binding is refused with 400 `ERR::REQUEST::INVALID_PARAMETER`. A used, expired or unknown token is 401 `ERR::AUTH::INVALID_KEY`.
        schema:
          type: string
          examples:
          - wbt_Q2hhbmdlTWVJbkEtVGVzdC1Ub2tlbi1FeGFtcGxlLVZhbHVlMDE
      - name: apikey
        in: query
        description: The API key, for WebSocket clients that cannot set headers. `api_key` is accepted as an alias. Ignored when an `Authorization` Bearer header is present. Keep the URL out of logs you do not control.
        schema:
          type: string
          examples:
          - spicrawl_live_…
      - name: api_key
        in: query
        description: Alias for `apikey`, consulted only when `apikey` is absent or blank.
        schema:
          type: string
      - name: engine
        in: query
        description: Optional. The rendering tier of the cloud browser - `browser` (default; full browser, full protocol) or `js` (lighter JavaScript rendering with a smaller protocol surface). `fetch` runs no browser and is refused with 400. A tier the plan does not include is 403 `ERR::AUTH::ENGINE_NOT_ENTITLED`; one the deployment lacks is 501 `ERR::ENGINE::UNAVAILABLE`.
        schema:
          type: string
          enum:
          - browser
          - js
          default: browser
      - name: proxy_region
        in: query
        description: Broad exit region such as `eu`. Case-insensitive. `global` means no constraint and is the same as omitting it. Cannot be combined with `proxy_country`.
        schema:
          type: string
          default: global
          examples:
          - eu
      - name: proxy_country
        in: query
        description: Exit country as a two-letter ISO 3166-1 alpha-2 code (case-insensitive, normalised to lowercase). Combining it with a non-`global` `proxy_region` is refused with 400 `ERR::REQUEST::INCOMPATIBLE_FLAGS`.
        schema:
          type: string
          pattern: ^[A-Za-z]{2}$
          examples:
          - de
      - name: session_ttl
        in: query
        description: Hard session lifetime in whole seconds. Out-of-range values are refused, not clamped. When it elapses the socket is closed even mid-command.
        schema:
          type: integer
          minimum: 60
          maximum: 900
          default: 180
      - name: headless
        in: query
        description: Optional and legacy. The display mode is chosen automatically; leave it out. If sent, it is `true`/`1` or `false`/`0` (case-insensitive); anything else is 400.
        schema:
          type: string
          enum:
          - 'true'
          - 'false'
          - '1'
          - '0'
      - name: sticky_key
        in: query
        description: Pins the exit for the session. 2-64 letters, digits and hyphens; no underscores. Omitted means the exit rotates, the opposite of `/v1/sessions`.
        schema:
          type: string
          minLength: 2
          maxLength: 64
          pattern: ^[A-Za-z0-9-]{2,64}$
      - name: Upgrade
        in: header
        required: true
        description: Must be `websocket` (case-insensitive). A plain HTTP GET is refused with 400 `ERR::REQUEST::INVALID`.
        schema:
          type: string
          const: websocket
      - name: Connection
        in: header
        required: true
        description: Must contain the token `Upgrade`.
        schema:
          type: string
          examples:
          - Upgrade
      - name: Sec-WebSocket-Key
        in: header
        required: true
        description: Forwarded to the browser backend unchanged; the returned `Sec-WebSocket-Accept` is computed from it. Your WebSocket library sets it.
        schema:
          type: string
      - name: Sec-WebSocket-Version
        in: header
        required: true
        description: Forwarded unchanged. Normally `13`.
        schema:
          type: string
          examples:
          - '13'
      responses:
        '101':
          description: Switching Protocols. The socket now carries raw CDP JSON messages in both directions, spliced to the browser without inspection.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
        '501':
          $ref: '#/components/responses/NotImplemented'
        '502':
          description: 'The browser backend could not be reached or refused the session (`ERR::UPSTREAM::ERROR`), or the

            worker reported another upstream-class code. Not caused by your request; retry with backoff and

            quote the `request_id` if it persists.

            '
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    servers:
    - url: https://api.spicrawl.com
      description: Production
    - url: http://localhost:8080
      description: Local development
  /v1/browser/token:
    post:
      tags:
      - Browser
      operationId: browserToken
      summary: Coming soon. Mint a single-use connect URL for /v1/browser
      description: 'Coming soon.

        Returns a `/v1/browser` URL that carries a short-lived token instead of the API key, for CDP clients

        that accept only a URL. The key goes in the `Authorization` header of THIS request only (a query key

        is refused). The token is single-use, expires after 60 s, and is bound to the options in the body:

        connect with the URL unchanged. `path` is authoritative: the URL relative to the API base. `url` is

        built from the deployment''s SPICRAWL_BROWSER_PUBLIC_URL when set, otherwise from this request''s scheme and

        Host header (caller-controlled, a convenience only). The token is

        never logged and never stored in plaintext. Requires the `browser` scope.'
      security:
      - bearerAuth: []
      x-spicrawl-scope: browser
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              description: The options `GET /v1/browser` accepts, validated the same way. All optional.
              properties:
                engine:
                  type: string
                  enum:
                  - browser
                  - js
                  default: browser
                proxy_country:
                  type: string
                  pattern: ^[a-z]{2}$
                proxy_region:
                  type: string
                sticky_key:
                  type: string
                  pattern: ^[A-Za-z0-9-]{2,64}$
                session_ttl:
                  type: integer
                  minimum: 60
                  maximum: 900
                headless:
                  type: boolean
      responses:
        '200':
          description: The connect URL, sent with Cache-Control no-store.
          content:
            application/json:
              schema:
                type: object
                required:
                - url
                - path
                - expires_at
                - expires_in
                - single_use
                properties:
                  url:
                    type: string
                    examples:
                    - wss://api.spicrawl.com/v1/browser?proxy_country=de&token=wbt_Q2hhbmdlTWVJbkEtVGVzdC1Ub2tlbi1FeGFtcGxlLVZhbHVlMDE
                  path:
                    type: string
                  expires_at:
                    type: string
                    format: date-time
                  expires_in:
                    type: integer
                    examples:
                    - 60
                  single_use:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    servers:
    - url: https://api.spicrawl.com
      description: Production
    - url: http://localhost:8080
      description: Local development
components:
  responses:
    RateLimited:
      description: Rate, concurrency or live-session limit reached. Retryable after `Retry-After`.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: Missing, invalid, revoked or expired key. Not retryable with the same key.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    ServiceUnavailable:
      description: No proxy exit or engine capacity was available. Retryable after `Retry-After`; 0 credits.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Forbidden:
      description: The key lacks the scope this route requires (`ERR::AUTH::INSUFFICIENT_SCOPE`), or the action is not permitted.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    BadRequest:
      description: The request is invalid. Not retryable; fix the request using `code` and `diagnostics.hint`.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PaymentRequired:
      description: '`ERR::LIMIT::QUOTA_EXCEEDED`: the organization is out of credits. Not retryable until credits are added.'
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        X-Credits-Remaining:
          description: '`/v1/scrape` only: whole credits left in the monthly allowance when the request was refused. Can be above 0: less than this request needed.'
          schema:
            type: integer
            minimum: 0
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    ServerError:
      description: Internal error. Retryable when `retryable` is true.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotImplemented:
      description: The capability is not deployed on this host. Not retryable.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  headers:
    X-RateLimit-Reset:
      description: Seconds until the bucket has one request available again. Only sent when the limiter imposed a wait.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in that bucket. Never above `X-RateLimit-Limit`.
      schema:
        type: integer
    X-Request-Id:
      description: ULID of this request. Quote it in support requests and use it with `GET /v1/requests/{id}`.
      schema:
        type: string
    X-RateLimit-Limit:
      description: Size of the key's rate-limit bucket, the most requests that can be sent back to back.
      schema:
        type: integer
    Retry-After:
      description: Seconds to wait before retrying. Present on retryable errors.
      schema:
        type: integer
        minimum: 0
  schemas:
    Problem:
      type: object
      description: 'RFC 7807 error body, served as `application/problem+json`. Switch on `code`;

        retry only when `retryable` is true, after `retry_after_seconds`.

        '
      required:
      - type
      - title
      - status
      - code
      - retryable
      - doc_url
      - target_status
      properties:
        type:
          type: string
          format: uri
          description: Link to this code's entry in the error reference.
        title:
          type: string
          description: Short fixed summary of the code. Do not parse it.
        status:
          type: integer
          description: The platform's HTTP status for this response. Not the target site's.
        code:
          $ref: '#/components/schemas/ErrorCode'
        detail:
          type: string
          description: What happened on this occurrence, in prose. Useful to show a human; do not parse it.
        retryable:
          type: boolean
          description: The server's own verdict on whether the same request can succeed on retry. Prefer it to guessing from `status`.
        doc_url:
          type: string
          format: uri
          description: Documentation for this code, including how to fix it.
        request_id:
          type: string
          description: ULID of the failed request. Pass it to `GET /v1/requests/{id}` for the full trace.
        instance:
          type: string
          description: Request path that produced the error.
        target_status:
          type:
          - integer
          - 'null'
          description: The target site's HTTP status when the failure came from the site, otherwise null.
        retry_after_seconds:
          type: integer
          minimum: 0
          description: Mirrors the `Retry-After` header for clients that read only the body.
        warnings:
          type: array
          items:
            type: string
          description: Non-fatal decisions the platform made for you, such as a flag ignored by proxy precedence.
        diagnostics:
          $ref: '#/components/schemas/ProblemDiagnostics'
    ProblemDiagnostics:
      type: object
      description: Where the request failed and whether the platform, the proxy or the target was at fault.
      properties:
        failed_at:
          type: string
          description: Name of the stage that failed; always the last row of `timeline`.
        timeline:
          type: array
          description: Stages in order, stopping at the failure.
          items:
            type: object
            required:
            - stage
            - ms
            - ok
            properties:
              stage:
                type: string
                description: Stage name.
              ms:
                type: integer
                description: Time spent in the stage in milliseconds.
              ok:
                type: boolean
                description: False only on the failing stage.
              detail:
                type: string
                description: What happened in the stage.
        attempts:
          type: array
          description: Each execution attempt. Under `mode=auto` these span the escalation ladder.
          items:
            type: object
            required:
            - n
            - outcome
            - ms
            properties:
              n:
                type: integer
                description: Attempt number, from 1.
              engine:
                type: string
                enum:
                - fetch
                - js
                - browser
                description: Rendering tier this attempt used (`fetch`, `js` for JavaScript rendering, `browser` for full-browser rendering).
              proxy:
                type: string
                description: Redacted exit label or proxy scheme and host. Never contains credentials.
              outcome:
                type: string
                description: How the attempt ended.
              ms:
                type: integer
                description: Attempt duration in milliseconds.
              error_code:
                $ref: '#/components/schemas/ErrorCode'
        budget_ms:
          type: integer
          description: Time budget the request had, in milliseconds. Compare with `elapsed_ms` to tell a timeout from a refusal.
        elapsed_ms:
          type: integer
          description: Time actually spent, in milliseconds.
        engine:
          type: string
          enum:
          - fetch
          - js
          - browser
          description: Rendering tier that served the final attempt.
        proxy:
          type: object
          description: Redacted description of the exit used.
          required:
          - source
          properties:
            source:
              type: string
              description: 'Where the exit came from: `pool`, `custom` or `direct`.'
            endpoint:
              type: string
              description: Exit identifier. Not the exit IP.
            country:
              type: string
              description: Exit country, ISO 3166-1 alpha-2 lowercase.
        hint:
          type: string
          description: The next thing to try, naming the parameter to change. Act on it before retrying the same request.
    ErrorCode:
      type: string
      description: 'Stable machine-readable error code, `ERR::FAMILY::NAME`. Switch on this, not on

        `title` or `detail`. `x-spicrawl-errors` lists each code''s HTTP status and

        whether it is retryable.

        '
      enum:
      - ERR::AUTH::MISSING_KEY
      - ERR::AUTH::INVALID_KEY
      - ERR::AUTH::REVOKED_KEY
      - ERR::AUTH::EXPIRED_KEY
      - ERR::AUTH::FORBIDDEN
      - ERR::AUTH::INSUFFICIENT_SCOPE
      - ERR::AUTH::INVALID_TOKEN
      - ERR::AUTH::INVALID_CREDENTIALS
      - ERR::AUTH::ENGINE_NOT_ENTITLED
      - ERR::REQUEST::INVALID
      - ERR::REQUEST::MISSING_PARAMETER
      - ERR::REQUEST::INVALID_PARAMETER
      - ERR::REQUEST::INCOMPATIBLE_FLAGS
      - ERR::REQUEST::NOT_FOUND
      - ERR::REQUEST::BEYOND_RETENTION
      - ERR::REQUEST::CONFLICT
      - ERR::REQUEST::PAYLOAD_TOO_LARGE
      - ERR::SECURITY::SSRF_BLOCKED
      - ERR::SECURITY::URL_BLOCKED
      - ERR::SECURITY::INVALID_URL
      - ERR::SESSION::NOT_FOUND
      - ERR::SESSION::EXPIRED
      - ERR::SESSION::RELEASED
      - ERR::SESSION::BUSY
      - ERR::SESSION::STATE_CORRUPT
      - ERR::LIMIT::RATE_LIMITED
      - ERR::LIMIT::CONCURRENCY_EXCEEDED
      - ERR::LIMIT::QUOTA_EXCEEDED
      - ERR::LIMIT::MAX_COST_EXCEEDED
      - ERR::LIMIT::SESSIONS_EXCEEDED
      - ERR::UPSTREAM::TIMEOUT
      - ERR::UPSTREAM::DNS_FAILED
      - ERR::UPSTREAM::TLS_FAILED
      - ERR::UPSTREAM::CONNECTION_RESET
      - ERR::UPSTREAM::TOO_MANY_REDIRECTS
      - ERR::UPSTREAM::ERROR
      - ERR::UPSTREAM::CHALLENGE
      - ERR::PROXY::EXHAUSTED
      - ERR::PROXY::UNREACHABLE
      - ERR::PROXY::AUTH_FAILED
      - ERR::PROXY::RATE_LIMITED
      - ERR::ENGINE::RENDER_FAILED
      - ERR::ENGINE::UNAVAILABLE
      - ERR::EXTRACT::FAILED
      - ERR::EXTRACT::INVALID_RULES
      - ERR::INTERNAL::ERROR
      - ERR::INTERNAL::UNAVAILABLE
      x-spicrawl-errors:
        ERR::AUTH::MISSING_KEY:
          status: 401
          retryable: false
          title: No API key supplied
        ERR::AUTH::INVALID_KEY:
          status: 401
          retryable: false
          title: API key not recognised
        ERR::AUTH::REVOKED_KEY:
          status: 401
          retryable: false
          title: API key has been revoked
        ERR::AUTH::EXPIRED_KEY:
          status: 401
          retryable: false
          title: API key has expired
        ERR::AUTH::FORBIDDEN:
          status: 403
          retryable: false
          title: Not permitted for this organization
        ERR::AUTH::INSUFFICIENT_SCOPE:
          status: 403
          retryable: false
          title: API key lacks the required scope
        ERR::AUTH::INVALID_TOKEN:
          status: 401
          retryable: false
          title: Session token is invalid or expired
        ERR::AUTH::INVALID_CREDENTIALS:
          status: 401
          retryable: false
          title: Email or password is incorrect
        ERR::AUTH::ENGINE_NOT_ENTITLED:
          status: 403
          retryable: false
          title: The organization's plan does not include this engine
        ERR::REQUEST::INVALID:
          status: 400
          retryable: false
          title: Request could not be understood
        ERR::REQUEST::MISSING_PARAMETER:
          status: 400
          retryable: false
          title: A required parameter is missing
        ERR::REQUEST::INVALID_PARAMETER:
          status: 400
          retryable: false
          title: A parameter has an invalid value
        ERR::REQUEST::INCOMPATIBLE_FLAGS:
          status: 400
          retryable: false
          title: Incompatible flag combination
        ERR::REQUEST::NOT_FOUND:
          status: 404
          retryable: false
          title: Resource not found
        ERR::REQUEST::BEYOND_RETENTION:
          status: 410
          retryable: false
          title: Beyond the request-log retention window
        ERR::REQUEST::CONFLICT:
          status: 409
          retryable: false
          title: Resource already exists
        ERR::REQUEST::PAYLOAD_TOO_LARGE:
          status: 413
          retryable: false
          title: Request body is too large
        ERR::REQUEST::CAPABILITY_UNSUPPORTED:
          status: 400
          retryable: false
          title: The request needs a capability that is not available
        ERR::SECURITY::SSRF_BLOCKED:
          status: 400
          retryable: false
          title: Target resolves to a private address
        ERR::SECURITY::URL_BLOCKED:
          status: 400
          retryable: false
          title: Target URL is blocked by policy
        ERR::SECURITY::INVALID_URL:
          status: 400
          retryable: false
          title: Target URL is not a valid http(s) URL
        ERR::SESSION::NOT_FOUND:
          status: 404
          retryable: false
          title: No such session
        ERR::SESSION::EXPIRED:
          status: 410
          retryable: false
          title: Session has expired and its context was purged
        ERR::SESSION::RELEASED:
          status: 410
          retryable: false
          title: Session was released and its context was purged
        ERR::SESSION::BUSY:
          status: 409
          retryable: true
          title: Session is in use by a running task
        ERR::SESSION::STATE_CORRUPT:
          status: 500
          retryable: false
          title: Stored session context could not be read
        ERR::LIMIT::RATE_LIMITED:
          status: 429
          retryable: true
          title: Rate limit exceeded
        ERR::LIMIT::CONCURRENCY_EXCEEDED:
          status: 429
          retryable: true
          title: Concurrency limit exceeded
        ERR::LIMIT::QUOTA_EXCEEDED:
          status: 402
          retryable: false
          title: Credit quota exhausted
        ERR::LIMIT::MAX_COST_EXCEEDED:
          status: 400
          retryable: false
          title: Request would exceed max_cost
        ERR::LIMIT::SESSIONS_EXCEEDED:
          status: 429
          retryable: true
          title: Too many live sessions
        ERR::UPSTREAM::TIMEOUT:
          status: 504
          retryable: true
          title: Target did not respond in time
        ERR::UPSTREAM::DNS_FAILED:
          status: 502
          retryable: true
          title: Target hostname could not be resolved
        ERR::UPSTREAM::TLS_FAILED:
          status: 502
          retryable: true
          title: TLS handshake with the target failed
        ERR::UPSTREAM::CONNECTION_RESET:
          status: 502
          retryable: true
          title: Target closed the connection
        ERR::UPSTREAM::TOO_MANY_REDIRECTS:
          status: 502
          retryable: false
          title: Too many redirects
        ERR::UPSTREAM::ERROR:
          status: 502
          retryable: true
          title: Target request failed
        ERR::UPSTREAM::CHALLENGE:
          status: 502
          retryable: true
          title: Target served a bot challenge
        ERR::PROXY::EXHAUSTED:
          status: 503
          retryable: true
          title: No healthy proxy exit available
        ERR::PROXY::UNREACHABLE:
          status: 502
          retryable: false
          title: Supplied proxy is unreachable
        ERR::PROXY::AUTH_FAILED:
          status: 502
          retryable: false
          title: Proxy rejected the credentials
        ERR::PROXY::RATE_LIMITED:
          status: 502
          retryable: true
          title: Proxy exit is rate limited
        ERR::ENGINE::RENDER_FAILED:
          status: 502
          retryable: true
          title: The page could not be rendered
        ERR::ENGINE::UNAVAILABLE:
          status: 503
          retryable: true
          title: No engine capacity available
        ERR::EXTRACT::FAILED:
          status: 502
          retryable: false
          title: The document could not be extracted
        ERR::EXTRACT::INVALID_RULES:
          status: 400
          retryable: false
          title: The extraction rules are invalid
        ERR::INTERNAL::ERROR:
          status: 500
          retryable: true
          title: Internal error
        ERR::INTERNAL::UNAVAILABLE:
          status: 503
          retryable: true
          title: Service temporarily unavailable
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: spicrawl_live_… | spicrawl_test_…
      description: '`Authorization: Bearer <key>`. Read the key from the `SPICRAWL_API_KEY` environment

        variable; never hard-code or log it. `spicrawl_test_…` keys can never spend live

        credits. Scopes: `scrape`, `batch`, `sessions` (granted by default), `browser`

        and `read` (granted deliberately). A missing scope is `403

        ERR::AUTH::INSUFFICIENT_SCOPE` naming the scope.

        '
    apiKeyQuery:
      type: apiKey
      in: query
      name: apikey
      description: 'The key as a query parameter. Only for clients that cannot set headers, such as

        a WebSocket upgrade from a browser-automation library. Prefer `bearerAuth` everywhere

        else, because URLs end up in logs.

        '
externalDocs:
  description: Guides and error reference
  url: https://docs.spicrawl.com
x-refined-from:
- spicrawl-openapi.yaml
- spicrawl-com-openapi.yaml