As of October 7, 2026, Shifter has the largest pool of live US IPs, more than Oxylabs and Bright Data, at a fraction of the cost.Shifter now has the largest pool of live US IPs

See benchmarks
Integration

Use Shifter with Go

Drop Shifter's residential and ISP proxies into Go in minutes. Works with the standard net/http, Resty, GoQuery, Colly, and any client that consumes a *url.URL — no SDK required.

Quick Start

Install

go get github.com/go-resty/resty/v2

Basic Usage

package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
)

func main() {
	proxyURL, _ := url.Parse(
		"customer-USERNAME-country-us-sid-123ABC:PASSWORD@p.shifter.io:443",
	)

	client := &http.Client{
		Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
	}

	resp, _ := client.Get("http://ip-info.com/json")
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
	// {"ip": "154.16.xxx.xxx", "city": "New York", "country": "US", ...}
}

Features

Drop-in support for net/http, Resty, GoQuery, Colly, fasthttp, and any client that accepts a proxy *url.URL
Per-request rotation by default, with `sid` for sticky sessions and `ttl-N` for timed pins of N seconds
Headless browser support via chromedp and Rod for JavaScript-rendered targets
HTTP, HTTPS, and SOCKS5 protocols on the same gateway endpoint
Geo-targeting in 195+ countries via username parameters — no extra SDK required
Compatible with every Go release from 1.18 onwards, including modules, go-workspaces, and CGO-free builds

Examples

Standard net/http with Sticky Session

The zero-dependency option. Build a *http.Transport with a proxy URL — the same client can be reused across goroutines safely.

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"time"
)

func newClient(country, city string) *http.Client {
	sidBytes := make([]byte, 4)
	rand.Read(sidBytes)
	sid := hex.EncodeToString(sidBytes)

	proxyURL, _ := url.Parse(fmt.Sprintf(
		"customer-USERNAME-country-%s-city-%s-sid-%s-ttl-300:PASSWORD@p.shifter.io:443",
		country, city, sid,
	))

	return &http.Client{
		Timeout: 30 * time.Second,
		Transport: &http.Transport{
			Proxy:                 http.ProxyURL(proxyURL),
			MaxIdleConnsPerHost:   16,
			IdleConnTimeout:       90 * time.Second,
			TLSHandshakeTimeout:   10 * time.Second,
			ResponseHeaderTimeout: 20 * time.Second,
		},
	}
}

func main() {
	c := newClient("uk", "london")

	for _, path := range []string{"/login", "/dashboard", "/orders"} {
		req, _ := http.NewRequest("GET", "https://example.co.uk"+path, nil)
		req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

		resp, err := c.Do(req)
		if err != nil {
			fmt.Println("error:", err)
			continue
		}
		body, _ := io.ReadAll(resp.Body)
		resp.Body.Close()
		fmt.Println(path, resp.StatusCode, len(body), "bytes")
	}
}

Resty (more ergonomic)

Resty wraps net/http with a fluent builder, auto-retry, and response binding. Worth it for scraping pipelines that need clean error handling.

package main

import (
	"fmt"

	"github.com/go-resty/resty/v2"
)

type Product struct {
	ID    int     `json:"id"`
	Name  string  `json:"name"`
	Price float64 `json:"price"`
}

func main() {
	client := resty.New().
		SetProxy("customer-USERNAME-country-de-sid-456DEF:PASSWORD@p.shifter.io:443").
		SetRetryCount(3).
		SetRetryWaitTime(2_000_000_000). // 2s in ns
		SetHeader("User-Agent", "Mozilla/5.0 (Macintosh) AppleWebKit/537.36")

	var products []Product
	resp, err := client.R().
		SetResult(&products).
		Get("https://api.example.de/products")

	if err != nil || !resp.IsSuccess() {
		fmt.Println("error:", err, resp.Status())
		return
	}

	for _, p := range products {
		fmt.Printf("%d %s — %.2f EUR\n", p.ID, p.Name, p.Price)
	}
}

Colly (scraping framework)

Colly is the de-facto Go scraping library. Configure the proxy with SetProxy() — every request the spider makes will route through Shifter.

package main

import (
	"fmt"
	"log"

	"github.com/gocolly/colly/v2"
)

func main() {
	c := colly.NewCollector(
		colly.AllowedDomains("example.com"),
		colly.UserAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"),
	)

	if err := c.SetProxy(
		"customer-USERNAME-country-fr-city-paris-sid-789GHI:PASSWORD@p.shifter.io:443",
	); err != nil {
		log.Fatal(err)
	}

	c.OnHTML("article.post", func(e *colly.HTMLElement) {
		fmt.Println(e.ChildText("h2"), "->", e.ChildAttr("a", "href"))
	})

	c.OnError(func(r *colly.Response, err error) {
		fmt.Printf("error %d: %v\n", r.StatusCode, err)
	})

	c.Visit("https://example.com/blog")
}

chromedp (headless Chromium)

Drive a real Chromium instance through Shifter for JavaScript-rendered targets. chromedp uses Chrome's CDP protocol — no Selenium dependency.

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/chromedp/chromedp"
)

func main() {
	opts := append(chromedp.DefaultExecAllocatorOptions[:],
		chromedp.ProxyServer("http://p.shifter.io:443"),
		chromedp.Flag("headless", true),
	)

	allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
	defer cancel()

	ctx, cancel := chromedp.NewContext(allocCtx)
	defer cancel()

	ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	var html string
	err := chromedp.Run(ctx,
		// chromedp doesn't natively prompt for proxy auth — use a Chrome
		// extension or run a sidecar that injects credentials, or use
		// Shifter's IP-whitelist auth instead of user/pass.
		chromedp.Navigate("https://example.com"),
		chromedp.WaitVisible("body", chromedp.ByQuery),
		chromedp.OuterHTML("html", &html),
	)

	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(len(html), "bytes")
}
FAQ

Frequently asked questions

Common questions about using Shifter with Go.

Parse the proxy URL with url.Parse, then pass it to a *http.Transport via http.ProxyURL(proxyURL). Use that transport on a *http.Client. The client is safe to share across goroutines and reuses connections automatically.

Call resty.New().SetProxy(proxyURL). Resty handles the underlying transport for you. The proxy URL format is `http://USER:PASS@p.shifter.io:443`. You can also chain SetRetryCount and SetTimeout for production-grade scraping.

Yes. Call c.SetProxy(proxyURL) on your collector — Colly will route every request through Shifter. Use SetProxyFunc for round-robin across multiple sessions, or pass a Shifter URL with a unique sid per spider for parallel scrapes.

Add a session ID to the proxy username — for example `customer-USERNAME-country-us-sid-123ABC`. Every Go request that uses the same proxy URL will reuse the same residential IP. Add `ttl-N` to pin that IP for up to N seconds.

Yes. Use chromedp with chromedp.ProxyServer in your ExecAllocator options. For username-password auth, pair this with Shifter's IP whitelist — Chrome doesn't prompt for proxy credentials in headless mode without a sidecar extension.

No SDK is required. Shifter speaks plain HTTP and SOCKS5 — point your existing transport at `p.shifter.io:443`. This keeps your go.mod free of vendor lock-in and works with any HTTP client in the ecosystem.

Get started

Start Using Shifter with Go

Add Shifter's 205M+ residential and ISP proxies to your Go services in under 5 minutes. Works with net/http, Resty, Colly, and chromedp.

Try Shifter for FreeSet up in minutes. Cancel anytime.