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

# Custom Headers with the Node.js SDK

> Send custom headers to the target website through the ZenRows Node.js SDK.

By default, ZenRows sends an optimized set of headers to the target site on your behalf. If you need to forward specific headers instead, like a `Referer` or a session `Cookie`, pass a `headers` object as part of the third argument to `get` or `post`.

```javascript theme={null} theme={null}
const { ZenRows } = require("zenrows");

const client = new ZenRows("YOUR_ZENROWS_API_KEY");
const url = "https://www.scrapingcourse.com/ecommerce/";

const response = await client.get(url, {}, {
  headers: {
    Referer: "https://www.google.com",
  },
});

console.log(await response.text());
```

## What happens when you pass headers

As soon as you pass a non-empty `headers` object, the SDK automatically sets `custom_headers=true` on the request for you, so you don't need to add that yourself. This enables your custom headers for the target request while ZenRows continues to manage browser-fingerprinting headers automatically.

## Headers you can and can't override

Not every header can be customized. ZenRows always manages browser-fingerprinting headers itself to keep success rates high and avoid anti-bot detection, even when `custom_headers` is enabled:

| Header                                                                 | Customizable?                          |
| ---------------------------------------------------------------------- | -------------------------------------- |
| `Referer`                                                              | Yes                                    |
| `Cookie`                                                               | Yes                                    |
| `Authorization`                                                        | Yes                                    |
| Most other headers                                                     | Yes, once `custom_headers=true` is set |
| `User-Agent`                                                           | No, always managed by ZenRows          |
| `Sec-Ch-Ua`, `Sec-Ch-Ua-Mobile`, `Sec-Ch-Ua-Platform`                  | No                                     |
| `Accept-Encoding`, `Accept-Language`                                   | No                                     |
| `Sec-Fetch-Mode`, `Sec-Fetch-Site`, `Sec-Fetch-User`, `Sec-Fetch-Dest` | No                                     |
| `Connection`, `Upgrade-Insecure-Requests`, `Cache-Control`             | No                                     |

<Warning>
  Passing a `User-Agent` (or any other browser-fingerprinting header from the table above) in the `headers` object has no effect on the request sent to the target site. ZenRows ignores it and keeps using its own managed value to maintain a consistent, realistic browser fingerprint. See [Custom Headers](https://docs.zenrows.com/universal-scraper-api/features/headers) in the Universal Scraper API docs for the full explanation.
</Warning>

<Note>
  The SDK does send its own `User-Agent` (`zenrows/<version> node`) as part of the HTTP request it makes to ZenRows' API endpoint. This identifies the request as coming from the Node.js SDK for ZenRows' own logging, it is not the header ZenRows sends to the target website. If you pass a `User-Agent` key in `headers`, it replaces this value on the request to ZenRows' API, but that still has no bearing on what the target site receives.
</Note>

## Combining with request parameters

The config object and `headers` are independent arguments, so you can use both together:

```javascript theme={null} theme={null}
const response = await client.get(
  url,
  { premium_proxy: true },
  { headers: { Referer: "https://www.google.com" } },
);
```

<Note>
  If a request keeps failing after you add custom headers, try removing them first to confirm whether they're the cause. ZenRows' defaults are usually the safer starting point.
</Note>

## Troubleshooting

* **Success rate drops after adding custom headers**: Remove your custom `headers` first to confirm whether they're the cause; ZenRows' defaults are usually the safer starting point.
* **Header doesn't seem to reach the target site**: Confirm you're using the `headers` argument (forwarded to the target) and not accidentally modifying the config object meant for ZenRows itself.
* **Cookies aren't persisting across requests**: Each SDK call is a separate, stateless request. Pass the `Cookie` header explicitly on every call if you need to maintain a session.
* **`custom_headers` shows up unexpectedly in requests**: This is set automatically whenever you pass a non-empty `headers` object; it's not something you need to remove.

## Pricing

Custom headers don't change the cost multiplier on their own. Cost still depends on `js_render` and `premium_proxy`:

| Configuration                             | Cost multiplier vs. basic |
| ----------------------------------------- | ------------------------- |
| Basic request                             | 1x                        |
| `js_render: true`                         | 5x                        |
| `premium_proxy: true`                     | 10x                       |
| `js_render: true` + `premium_proxy: true` | 25x                       |

See [ZenRows Pricing](/first-steps/pricing).

## FAQ (Frequently Asked Questions)

<AccordionGroup>
  <Accordion title="Do I need to set custom_headers myself?">
    No. Passing a non-empty `headers` object to `get` or `post` sets `custom_headers=true` automatically.
  </Accordion>

  <Accordion title="Can I override the User-Agent sent to the target site?">
    No. `User-Agent` is one of several browser-fingerprinting headers ZenRows always manages for the request to the target, regardless of what you pass in `headers`. See the table above for the full list.
  </Accordion>

  <Accordion title="Can I set headers meant for ZenRows itself (like an API version header)?">
    No. `headers` is forwarded to the target website, not to ZenRows' API. ZenRows-specific options belong in the config object (the second argument).
  </Accordion>
</AccordionGroup>
