> ## 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.

# Zenrows SDK Overview

> Official Zenrows SDKs for Python, Node.js, and Go. Pick your language and start scraping in minutes.

The Zenrows SDKs are lightweight, official clients for [Fetch](/fetch/setup). Each one wraps the same `https://api.zenrows.com/v1` endpoint, adding authentication, retries, and concurrency control so you write less boilerplate and spend more time on what you're actually building.

<Info>
  All three SDKs are open source and MIT licensed. You can inspect the source, report bugs, or contribute on [GitHub](https://github.com/ZenRows).
</Info>

## Pick your language

<CardGroup cols={3}>
  <Card title="Python" icon="brand-python" href="/fetch/sdk/python/introduction">
    Built on `requests`. Returns `requests.Response`. Supports `async`/`await` via `asyncio`. GET, POST, and PUT.
  </Card>

  <Card title="Node.js" icon="brand-nodejs" href="/fetch/sdk/nodejs/introduction">
    Built on native `fetch`. Returns a standard `Response`. Every method is already a `Promise`. GET and POST.
  </Card>

  <Card title="Go" icon="golang" href="/fetch/sdk/go/introduction">
    Built on `net/http` via `go-resty`. Typed `RequestParameters` struct. Takes `context.Context`. GET, POST, and PUT.
  </Card>
</CardGroup>

## What every SDK gives you

All three SDKs share the same core behavior. You set your API key once in the client constructor, and every call handles the rest.

<AccordionGroup>
  <Accordion title="Authentication" icon="key">
    Your API key is passed once to the client constructor. Every subsequent request is authenticated automatically; you never repeat it per call.

    <Tabs>
      <Tab title="Python">
        ```python theme={null} theme={"dark"}
        from zenrows import ZenRowsClient

        client = ZenRowsClient("YOUR_ZENROWS_API_KEY")
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null} theme={"dark"}
        const { ZenRows } = require("zenrows");

        const client = new ZenRows("YOUR_ZENROWS_API_KEY");
        ```
      </Tab>

      <Tab title="Go">
        ```go theme={null} theme={"dark"}
        import scraperapi "github.com/zenrows/zenrows-go-sdk/service/api"

        client := scraperapi.NewClient(
            scraperapi.WithAPIKey("YOUR_ZENROWS_API_KEY"),
        )
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="Automatic retries" icon="refresh">
    Retries are off by default (`0`). Set a retry count in the constructor and the SDK retries failed requests with exponential backoff automatically. Only successful responses are billed; failed retries are free.

    <Tabs>
      <Tab title="Python">
        ```python theme={null} theme={"dark"}
        client = ZenRowsClient("YOUR_ZENROWS_API_KEY", retries=2)
        ```

        Retries on: `422`, `429`, `500`, `502`, `503`, `504`
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null} theme={"dark"}
        const client = new ZenRows("YOUR_ZENROWS_API_KEY", { retries: 2 });
        ```

        Retries on: `422`, `503`, `504`, and network errors
      </Tab>

      <Tab title="Go">
        ```go theme={null} theme={"dark"}
        client := scraperapi.NewClient(
            scraperapi.WithAPIKey("YOUR_ZENROWS_API_KEY"),
            scraperapi.WithMaxRetryCount(2),
        )
        ```

        Retries on: `422`, `429`, `500`, and network errors
      </Tab>
    </Tabs>

    <Warning>
      The retry status code list differs between SDKs. If you need consistent retry behavior across languages, check each SDK's [Error Handling and Retries](/fetch/sdk/python/error-handling-and-retries) page for the exact list.
    </Warning>
  </Accordion>

  <Accordion title="Concurrency control" icon="bolt">
    All three SDKs cap parallel requests via an internal queue or semaphore. The default concurrency limit is `5`. Set it to match your Zenrows plan.

    <Tabs>
      <Tab title="Python">
        ```python theme={null} theme={"dark"}
        client = ZenRowsClient("YOUR_ZENROWS_API_KEY", concurrency=5)
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null} theme={"dark"}
        const client = new ZenRows("YOUR_ZENROWS_API_KEY", { concurrency: 5 });
        ```
      </Tab>

      <Tab title="Go">
        ```go theme={null} theme={"dark"}
        client := scraperapi.NewClient(
            scraperapi.WithAPIKey("YOUR_ZENROWS_API_KEY"),
            scraperapi.WithMaxConcurrentRequests(5),
        )
        ```
      </Tab>
    </Tabs>

    <Note>
      Each client instance enforces its own concurrency limit. Two scripts using the same API key don't share limits, so running both at once can trigger `429 Too Many Requests` errors. See the [Concurrency](/fetch/features/concurrency) guide for plan-level limits.
    </Note>
  </Accordion>

  <Accordion title="Request parameters" icon="table">
    Every Fetch parameter (`js_render`, `premium_proxy`, `css_extractor`, and so on) is available through each SDK. Only the syntax differs.

    <Tabs>
      <Tab title="Python">
        ```python theme={null} theme={"dark"}
        response = client.get(url, params={
            "js_render": True,
            "premium_proxy": True,
            "proxy_country": "us",
        })
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null} theme={"dark"}
        const response = await client.get(url, {
          js_render: true,
          premium_proxy: true,
          proxy_country: "us",
        });
        ```
      </Tab>

      <Tab title="Go">
        ```go theme={null} theme={"dark"}
        response, err := client.Get(ctx, url, &scraperapi.RequestParameters{
            JSRender:          true,
            UsePremiumProxies: true,
            ProxyCountry:      "us",
        })
        ```
      </Tab>
    </Tabs>

    For the full parameter list, see the [Fetch setup guide](/fetch/setup).
  </Accordion>

  <Accordion title="Response headers" icon="code">
    Every response includes Zenrows monitoring headers. The two most useful for tracking usage are:

    | Header | Contains |
    | - | - |
    | `X-Request-Cost` | Dollar cost of the request (e.g. `0.001`) |
    | `X-Request-Credits` | Number of credits consumed |
    | `X-Key-Credits-Remaining` | Lowest remaining credits across the API key's [credit caps](/first-steps/api-key-credit-caps). Sent only for keys with at least one cap |
    | `X-Request-Id` | Unique request ID. Include this when contacting support |
    | `Concurrency-Remaining` | Concurrency slots remaining on your plan |
    | `Zr-Final-Url` | Final URL after any redirects |

    Headers from the target website are prefixed with `Zr-` to avoid collisions with Zenrows' own headers.
  </Accordion>
</AccordionGroup>

## SDK comparison

<Note>
  All SDKs target the same Fetch endpoint. The differences below are language-level constraints, not API-level ones.
</Note>

| Feature | Python | Node.js | Go |
| - | - | - | - |
| Install | `pip install zenrows` | `npm install zenrows` | `go get github.com/zenrows/zenrows-go-sdk/service/api` |
| Min version | Python 3.6+ | Node.js 20+ | Go 1.23+ |
| Response type | `requests.Response` | Fetch `Response` | `*scraperapi.Response` |
| GET | Yes | Yes | Yes |
| POST | Yes | Yes | Yes |
| PUT | Yes | No (use raw `fetch`) | Yes |
| Async / parallel | `get_async` + `asyncio` | Every method is a `Promise` | Goroutines + semaphore |
| Default concurrency | 5 | 5 | 5 |
| Retried status codes | `422`, `429`, `500`, `502`, `503`, `504` | `422`, `503`, `504` | `422`, `429`, `500` |
| Typed parameters | No (dict / object) | No (dict / object) | Yes (`RequestParameters` struct) |
| GitHub | <a href="https://github.com/ZenRows/zenrows-python-sdk" target="_blank" rel="noopener noreferrer">zenrows-python-sdk</a> | <a href="https://github.com/ZenRows/zenrows-node-sdk" target="_blank" rel="noopener noreferrer">zenrows-node-sdk</a> | <a href="https://github.com/ZenRows/zenrows-go-sdk" target="_blank" rel="noopener noreferrer">zenrows-go-sdk</a> |

## Pricing

Cost is determined by the parameters you send per request, not by which SDK you use. Retried attempts that fail are not billed.

| Configuration | Credits per request |
| - | - |
| Basic request | 1 |
| `js_render=True` / `js_render: true` / `JSRender: true` | 5 |
| `premium_proxy=True` / `premium_proxy: true` / `UsePremiumProxies: true` | 10 |
| JS render + Premium Proxy | 25 |

See [Zenrows Pricing](/first-steps/pricing) for plan-specific rates and concurrency limits.

## Get started

<Steps>
  <Step title="Pick your SDK">
    Choose the SDK that matches your language. All three share the same API key and request parameters.
  </Step>

  <Step title="Install it">
    Follow the installation guide for your language: [Python](/fetch/sdk/python/installation), [Node.js](/fetch/sdk/nodejs/installation), or [Go](/fetch/sdk/go/installation).
  </Step>

  <Step title="Make your first request">
    Each SDK has a quickstart that gets you to a working response in under 10 lines of code: [Python](/fetch/sdk/python/quickstart), [Node.js](/fetch/sdk/nodejs/quickstart), [Go](/fetch/sdk/go/quickstart).
  </Step>

  <Step title="Scale up">
    Once the basics work, add retries and concurrency to match your production requirements. Each SDK's [Error Handling](/fetch/sdk/python/error-handling-and-retries) and [Concurrency](/fetch/sdk/python/async-concurrency) pages walk through the options.
  </Step>
</Steps>

<Card title="Need help?" icon="help-circle" href="mailto:success@zenrows.com">
  Check the [API Error Codes](/api-error-codes) reference for error details, or contact support with your `X-Request-Id` header value for faster triage.
</Card>


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