Skip to main content
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, set the CustomHeaders field on RequestParameters.
package main

import (
    "context"
    "fmt"
    "log"
    "net/http"

    scraperapi "github.com/zenrows/zenrows-go-sdk/service/api"
)

func main() {
    client := scraperapi.NewClient(
        scraperapi.WithAPIKey("YOUR_ZENROWS_API_KEY"),
    )

    response, err := client.Get(
        context.Background(),
        "https://www.scrapingcourse.com/ecommerce/",
        &scraperapi.RequestParameters{
            CustomHeaders: http.Header{
                "Referer": []string{"https://www.google.com"},
            },
        },
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(response.String())
}

What happens when you set CustomHeaders

As soon as CustomHeaders is non-empty, the SDK automatically sets custom_headers=true as a query parameter 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:
HeaderCustomizable?
RefererYes
CookieYes
AuthorizationYes
Most other headersYes, once custom_headers=true is set
User-AgentNo, always managed by ZenRows
Sec-Ch-Ua, Sec-Ch-Ua-Mobile, Sec-Ch-Ua-PlatformNo
Accept-Encoding, Accept-LanguageNo
Sec-Fetch-Mode, Sec-Fetch-Site, Sec-Fetch-User, Sec-Fetch-DestNo
Connection, Upgrade-Insecure-Requests, Cache-ControlNo
Setting a User-Agent (or any other browser-fingerprinting header from the table above) in CustomHeaders 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 in the Universal Scraper API docs for the full explanation.
The SDK does send its own User-Agent (zenrows-go/<version>) as part of the HTTP request it makes to ZenRows’ API endpoint. This identifies the request as coming from the Go SDK for ZenRows’ own logging, it is not the header ZenRows sends to the target website.

Combining with other parameters

CustomHeaders is just one field on RequestParameters, so it combines naturally with everything else:
response, err := client.Get(
    context.Background(),
    url,
    &scraperapi.RequestParameters{
        UsePremiumProxies: true,
        CustomHeaders: http.Header{
            "Referer": []string{"https://www.google.com"},
        },
    },
)
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.

Troubleshooting

  • Success rate drops after adding custom headers: This is expected per the warning above. Remove CustomHeaders first to confirm whether it’s the cause; ZenRows’ defaults are usually the safer starting point.
  • Header doesn’t seem to reach the target site: Confirm you’re setting CustomHeaders on RequestParameters (forwarded to the target), not adding it somewhere else, like a header on the outgoing request to ZenRows’ own API.
  • Cookies aren’t persisting across requests: Each SDK call is a separate, stateless request. Set the Cookie header explicitly in CustomHeaders on every call if you need to maintain a session.
  • custom_headers=true shows up unexpectedly in logs: This is set automatically whenever CustomHeaders is non-empty, it’s not something you need to remove.

Pricing

Custom headers don’t change the cost multiplier on their own. Cost still depends on JSRender and UsePremiumProxies:
ConfigurationCost multiplier vs. basic
Basic request1x
JSRender: true5x
UsePremiumProxies: true10x
JSRender: true + UsePremiumProxies: true25x
See ZenRows Pricing.

FAQ (Frequently Asked Questions)

No. Setting a non-empty CustomHeaders field on RequestParameters sets custom_headers=true automatically.
Non-fingerprinting headers like Referer, Cookie, and Authorization are forwarded exactly as you set them. Browser-fingerprinting headers like User-Agent are never forwarded as sent, ZenRows always manages those regardless of what you pass. This is why overriding headers you can customize can still lower success rates on protected sites, since you lose ZenRows’ tuned defaults for that request.
No. CustomHeaders is forwarded to the target website, not to ZenRows’ API. ZenRows-specific options belong in the other RequestParameters fields, or in CustomParams for anything not yet exposed as a typed field.