> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenrows.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> The Zenrows API (Fetch, Extract, Crawl and Batch) is described in OpenAPI 3.1 at https://www.zenrows.com/openapi.json and listed in the RFC 9727 API catalog at https://www.zenrows.com/.well-known/api-catalog. Every endpoint also has its own page under /api-reference with its schema. Use the spec for exact parameter names and types. To call Zenrows from an agent, connect the MCP server at https://mcp.zenrows.com/mcp. To search these docs from an agent, connect the docs MCP server at https://docs.zenrows.com/mcp. Agent skills for Zenrows are published at https://github.com/ZenRows/cli and install with `npx skills add ZenRows/cli`.

# Start a crawl

> Start a crawl from one URL and return at once with `202 Accepted`, the crawl in the body and its path in the `Location` header. Each page it opens is one Fetch request with Adaptive Stealth Mode, billed 1 to 25 credits; failed pages are not billed. Documented at https://docs.zenrows.com/crawl/endpoints#start-a-crawl.



## OpenAPI

````yaml /api-reference/openapi.json post /crawls
openapi: 3.1.0
info:
  title: Zenrows API
  version: 1.0.0
  summary: >-
    Reach any page, including the protected web, and return it as HTML,
    Markdown, plaintext, PDF or structured JSON.
  description: >-
    Zenrows is web data infrastructure for agents and applications. Three HTTP
    surfaces are described here:


    - **Fetch and Extract**: one synchronous request per page, at
    `https://api.zenrows.com/v1/`. Authentication is the `apikey` query
    parameter.

    - **Crawl**: collect the URLs behind one start page, at
    `https://api.zenrows.com/v1/crawls`. Authentication is the `X-API-Key`
    header or the `apikey` query parameter.

    - **Batch**: asynchronous jobs of up to 100,000 URLs, at
    `https://async.api.zenrows.com/v1`. Authentication is the `X-API-Key`
    header.


    **Browser** is not described here because it is not HTTP: you connect
    Puppeteer or Playwright to a WebSocket endpoint. See
    https://docs.zenrows.com/browser-sessions/introduction.


    **Cost.** A request costs 1 credit, 5 with JavaScript rendering, 10 with
    premium proxies, 25 with both, and 1 to 25 under `mode=auto`. Failed
    requests are never charged. The free tier is 5,000 credits a month, no card.


    **Versioning and deprecation.** The version is in the URL path (`/v1`, the
    only version so far). Inside a version Zenrows only adds: new endpoints,
    optional parameters, response fields and headers. Nothing is removed or
    changed. Retiring a version is announced at least twelve months ahead, and
    every response from a deprecated version carries the `Deprecation` (RFC
    9745) and `Sunset` (RFC 8594) headers. Policy:
    https://docs.zenrows.com/api-versioning.


    **Getting a key without a human.** `POST
    https://app.zenrows.com/api/agent/signup` returns a usable key; the spec is
    at https://www.zenrows.com/auth.md and a setup playbook at
    https://www.zenrows.com/SKILL.md.
  termsOfService: https://www.zenrows.com/legal/terms-of-use
  contact:
    name: Zenrows support
    email: support@zenrows.com
    url: https://www.zenrows.com/contact
  license:
    name: Proprietary
    url: https://www.zenrows.com/legal/terms-of-use
servers:
  - url: https://api.zenrows.com/v1
    description: Fetch and Extract (synchronous)
security:
  - apiKeyQuery: []
tags:
  - name: Fetch
    description: Retrieve one page, optionally rendered, proxied, converted or extracted.
  - name: Extract
    description: Which domains Extract serves, and getting a new one prepared.
  - name: Crawl
    description: Collect the URLs behind one start page, and each page's HTML when asked.
  - name: Batch
    description: Submit many URLs as one job and collect the results.
  - name: Account
    description: Plan, credits and concurrency for the calling key.
  - name: Onboarding
    description: Get a working key with no human in the loop.
externalDocs:
  description: Zenrows documentation
  url: https://docs.zenrows.com
paths:
  /crawls:
    post:
      tags:
        - Crawl
      summary: Start a crawl
      description: >-
        Start a crawl from one URL and return at once with `202 Accepted`, the
        crawl in the body and its path in the `Location` header. Each page it
        opens is one Fetch request with Adaptive Stealth Mode, billed 1 to 25
        credits; failed pages are not billed. Documented at
        https://docs.zenrows.com/crawl/endpoints#start-a-crawl.
      operationId: startCrawl
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
            maxLength: 255
          description: >-
            Makes a retry safe: a retry with the same key and body returns the
            same crawl and starts no second one. The same key with a different
            body is `422 idempotency_key_reused`.
          example: catalog-2026-10-09
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              additionalProperties: false
              properties:
                url:
                  type: string
                  format: uri
                  maxLength: 2048
                  description: >-
                    The start URL: a public `http` or `https` URL. The crawl
                    starts on this exact URL and stays on its domain, subdomains
                    included.
                depth:
                  type: integer
                  minimum: 1
                  maximum: 100000
                  description: >-
                    How many link steps to follow from the start URL. At `1`,
                    the links on the start page. Omit it to follow links until
                    `max_items` or `max_pages` stops the crawl.
                max_items:
                  type: integer
                  minimum: 1
                  maximum: 100000
                  default: 100
                  description: Stop after keeping this many URLs.
                max_pages:
                  type: integer
                  minimum: 1
                  maximum: 100000
                  default: 100
                  description: >-
                    Stop after fetching this many pages. Caps what the crawl
                    costs. If both limits are reached together, `stop_reason` is
                    `max_pages`.
                include_patterns:
                  type: array
                  items:
                    type: string
                  description: >-
                    Keep, and open, only URLs that contain at least one of these
                    texts, such as `/product/`. The start URL is never returned.
                exclude_patterns:
                  type: array
                  items:
                    type: string
                  description: >-
                    Drop URLs that contain any of these texts, even when they
                    match an include pattern.
                output_format:
                  type: string
                  enum:
                    - html
                  description: >-
                    `html` also returns the HTML of each kept page. Omit it to
                    get URLs only.
            example:
              url: https://www.scrapingcourse.com/ecommerce/
              max_pages: 10
              include_patterns:
                - /product/
      responses:
        '202':
          description: The crawl started.
          headers:
            Location:
              description: The crawl's path.
              schema:
                type: string
                example: /v1/crawls/c_01M3XP7RZD4JT88F7PNPGBFRAF
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Crawl'
              example:
                crawl_id: c_01M3XP7RZD4JT88F7PNPGBFRAF
                status: running
                url: https://www.scrapingcourse.com/ecommerce/
                max_items: 100
                max_pages: 10
                include_patterns:
                  - /product/
                exclude_patterns: []
                discovery:
                  - links
                coverage:
                  pages_fetched: 0
                  pages_failed: 0
                  items_found: 0
                duplicates_removed: 0
                created_at: '2026-10-09T09:00:12Z'
                results: []
                next_cursor: cur_Y18wMU0zWFA3UlpENEpUODhGN1BOUEdCRlJBRjow
        '400':
          description: >-
            `invalid_request` (the body is not valid JSON, or the
            `Idempotency-Key` is over 255 characters), `unknown_parameter`
            (`detail` names it) or `invalid_parameter`. Documented at
            https://docs.zenrows.com/crawl/endpoints#errors.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: unknown_parameter
                title: Unknown parameter
                detail: >-
                  The request has a parameter this endpoint does not accept:
                  max_depth.
                status: 400
                instance: urn:zenrows:request:9ac5b40be6127c8809b91babda784059
        '401':
          description: The API key is missing or invalid.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: AUTH002
                detail: Invalid API key.
                instance: /v1
                status: 401
                title: Invalid apikey provided (AUTH002)
                type: https://docs.zenrows.com/api-error-codes#AUTH002
        '402':
          description: >-
            The account is out of credits, or the plan does not include this
            capability.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: AUTH004
                detail: >-
                  This account has used all its credits for the period. Upgrade
                  or add credits to continue.
                instance: /v1
                status: 402
                title: Usage exceeded (AUTH004)
                type: https://docs.zenrows.com/api-error-codes#AUTH004
        '409':
          description: >-
            `idempotency_request_in_flight`: a request with this
            `Idempotency-Key` is still in progress. Retry when it ends.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: idempotency_request_in_flight
                title: Request in flight
                detail: >-
                  A request with this Idempotency-Key is still in progress.
                  Retry when it ends.
                status: 409
                instance: urn:zenrows:request:9ac5b40be6127c8809b91babda784059
        '422':
          description: >-
            `invalid_start_url` (the host is an IP address or a private address,
            or the URL is over 2,048 characters), `invalid_parameter` or
            `idempotency_key_reused`.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: invalid_start_url
                title: Invalid start URL
                detail: The start URL must be a public http or https URL.
                status: 422
                instance: urn:zenrows:request:9ac5b40be6127c8809b91babda784059
        '429':
          description: >-
            `too_many_crawls`: the account already runs its active jobs (3 by
            default, shared with Batch). Wait for one to end; the response
            carries `Retry-After: 30`.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: too_many_crawls
                title: Too many active crawls
                detail: >-
                  Your account already runs 3 active jobs. Wait for one to end,
                  then start the crawl again.
                status: 429
                instance: urn:zenrows:request:9ac5b40be6127c8809b91babda784059
        '500':
          description: '`internal_error`: something failed on our side. Retry later.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                code: internal_error
                title: Internal error
                detail: Something failed on our side. Retry later.
                status: 500
                instance: urn:zenrows:request:9ac5b40be6127c8809b91babda784059
      security:
        - apiKeyHeader: []
        - apiKeyQuery: []
components:
  schemas:
    Crawl:
      type: object
      description: A crawl, its coverage so far and one page of results.
      properties:
        crawl_id:
          type: string
        status:
          type: string
          enum:
            - running
            - completed
            - stopped
            - failed
          description: >-
            `completed`: nothing was left to open, or a limit was reached (see
            `stop_reason`). `stopped`: you stopped it. `failed`: see `error`.
        stop_reason:
          type: string
          enum:
            - max_items
            - max_pages
            - user
          description: >-
            Why the crawl ended early. Absent when nothing was left to open, and
            when the crawl failed.
        error:
          type: object
          description: >-
            Present only when `status` is `failed`. Older crawls can carry
            `domain_not_allowed` (the domain was not prepared for Extract).
          properties:
            code:
              type: string
              enum:
                - seed_unreachable
                - no_items_found
                - insufficient_credits
                - internal_error
                - domain_not_allowed
            detail:
              type: string
        url:
          type: string
          format: uri
          maxLength: 2048
          description: >-
            The start URL: a public `http` or `https` URL. The crawl starts on
            this exact URL and stays on its domain, subdomains included.
        depth:
          type: integer
          minimum: 1
          maximum: 100000
          description: >-
            How many link steps to follow from the start URL. At `1`, the links
            on the start page. Omit it to follow links until `max_items` or
            `max_pages` stops the crawl.
        max_items:
          type: integer
          minimum: 1
          maximum: 100000
          default: 100
          description: Stop after keeping this many URLs.
        max_pages:
          type: integer
          minimum: 1
          maximum: 100000
          default: 100
          description: >-
            Stop after fetching this many pages. Caps what the crawl costs. If
            both limits are reached together, `stop_reason` is `max_pages`.
        include_patterns:
          type: array
          items:
            type: string
          description: >-
            Keep, and open, only URLs that contain at least one of these texts,
            such as `/product/`. The start URL is never returned.
        exclude_patterns:
          type: array
          items:
            type: string
          description: >-
            Drop URLs that contain any of these texts, even when they match an
            include pattern.
        output_format:
          type: string
          enum:
            - html
          description: >-
            `html` also returns the HTML of each kept page. Omit it to get URLs
            only.
        discovery:
          type: array
          items:
            type: string
            enum:
              - links
              - pagination
          description: >-
            `["links"]`: the crawl follows the links in each page's HTML. Older
            crawls can also list `pagination`.
        coverage:
          type: object
          properties:
            pages_fetched:
              type: integer
              description: Pages fetched so far, successful or not, at most `max_pages`.
            pages_failed:
              type: integer
              description: Pages that failed to load.
            items_found:
              type: integer
              description: >-
                URLs returned so far, after duplicates and patterns. At most
                `max_items`.
        duplicates_removed:
          type: integer
          description: Links met again and dropped. Results never hold a duplicate.
        created_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
          description: Absent while the crawl runs.
        results:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
                format: uri
                description: >-
                  A URL the crawl found, normalized: scheme, `www.` and a
                  trailing slash do not make two URLs, and tracking parameters
                  such as `utm_*` are removed.
              content_status:
                type: string
                enum:
                  - pending
                  - fetched
                  - failed
                description: With `output_format` only.
              content_url:
                type: string
                description: >-
                  With `output_format` only, once fetched: the path to read the
                  page.
        next_cursor:
          type:
            - string
            - 'null'
          description: >-
            Send it as `cursor` on the next read. Never `null` while the crawl
            runs; `null` once it has ended and its last results were read.
    Error:
      type: object
      description: >-
        Zenrows error envelope, sent as `application/problem+json` (RFC 9457
        problem details). `code` is the stable identifier to branch on; `type`
        links to its entry in the catalogue at
        https://docs.zenrows.com/api-error-codes. Read back from live responses.
      properties:
        code:
          type: string
          example: AUTH002
        status:
          type: integer
          example: 401
        title:
          type: string
          example: Invalid apikey provided (AUTH002)
        detail:
          type: string
          example: Invalid API key.
        type:
          type: string
          format: uri
          example: https://docs.zenrows.com/api-error-codes#AUTH002
        instance:
          type: string
          description: >-
            The request path or a request URN. Quote it when reporting a
            problem.
          example: /v1
  headers:
    XRequestId:
      description: Identifier for this request. Quote it when reporting a problem.
      schema:
        type: string
        example: 67fa4e35647515d8ad61bb3ee041e1bb
  securitySchemes:
    apiKeyQuery:
      type: apiKey
      in: query
      name: apikey
      description: >-
        Fetch, Extract, Crawl and the account endpoint accept the key as the
        `apikey` query parameter. Keys are per account and self-serve: create
        one in the Zenrows dashboard (app.zenrows.com), or, for an agent with no
        human present, `POST https://app.zenrows.com/api/agent/signup`.
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        Batch, Crawl, the Extract endpoints and the account endpoint read the
        same key from the `X-API-Key` header.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.