Skip to main content

Proxies

Surfsky offers three ways to handle proxies for your browser automation needs. This guide covers each option and helps you choose the right approach for your use case.

Quick Start

Default Behavior

When you don't specify a proxy parameter, Surfsky assigns one from a tier your account has (see Choosing the tier) - Surfsky proxies when your account has them, otherwise shared. Shared proxies are convenient for quick testing but have limitations for production use.

# No proxy specified = a proxy from your account's default tier is assigned
curl -X POST 'https://api-public.surfsky.io/profiles/one_time' \
-H 'X-Cloud-Api-Token: YOUR_API_TOKEN' \
-d '{"fingerprint": {"os": "win"}}'

Using Your Own Proxy

For better control and performance, provide your own proxy URL:

curl -X POST 'https://api-public.surfsky.io/profiles/one_time' \
-H 'X-Cloud-Api-Token: YOUR_API_TOKEN' \
-d '{
"fingerprint": {"os": "win"},
"proxy": "socks5://user:[email protected]:1080"
}'

Using Surfsky Proxies

After setting up Surfsky proxy access (contact support), use geolocation-based selection:

curl -X POST 'https://api-public.surfsky.io/profiles/one_time' \
-H 'X-Cloud-Api-Token: YOUR_API_TOKEN' \
-d '{
"fingerprint": {"os": "win"},
"proxy": {
"country": "us",
"region": "california"
}
}'

Proxy Options Comparison

OptionBest ForSetup RequiredCost
Shared proxiesQuick tests, developmentNoneFree (included)
Your wwn proxiesFull control, existing infrastructureProxy credentialsBrowser time only
Surfsky proxiesProduction, geo-targetingContact supportBrowser time + proxy traffic

Choosing the tier

There are 2 tiers: shared and premium (Surfsky proxies). Which ones your account has comes from your plan, and each can be switched off for an individual account. You may have both, one, or neither.

proxy.tier picks between the tiers you have:

{ "proxy": { "tier": "shared", "country": "us" } }
{ "proxy": { "tier": "premium", "country": "us", "region": "texas" } }

Leave tier out and premium is used when your account has it, otherwise shared. Either way one tier is never substituted for the other - a request is served from the tier you expect or it fails:

  • tier: "premium", or no tier on a premium account, fails with premium_pool_unavailable when your Surfsky proxies account is missing. It does not quietly fall back to shared.
  • tier: "shared" when your plan excludes shared proxies fails with shared_pool_unavailable.
  • With no tier on the account at all, any request fails with proxy_pool_unavailable.

The rest of the proxy object is geo targeting inside the chosen tier:

  • On shared, only country applies, and it is optional. A country with no healthy shared proxies fails immediately with shared_pool_country_unavailable. Sending region, city, pool, type, asn or coordinates alongside tier: "shared" is a 422.
  • On premium, country/region/city, asn, pool, lat/lon and type all apply, and country is optional too - an unset one gets any location from the pool. See Proxy Geolocation Parameters for which of them combine.

Note that pool is a geographic region (europe, sea, western, ...), not a tier. It draws an IP from anywhere in that region, so it replaces country/region/city instead of narrowing them. pool previously selected the tier and accepted "shared" / "premium"; those values now return 422 - use tier.

Omitting proxy entirely uses your default tier with no targeting. The one exception is POST /profiles/{uuid}/start with no proxy in the body at all - the pod keeps using the profile's stored proxy instead of picking a new one, since the profile's fingerprint is bound to that proxy's country. Pass proxy explicitly on a start to override it.

Every API error carries a machine-readable code next to the human msg (see Errors); the proxy-related codes:

CodeStatusMeaning
shared_pool_unavailable403Plan or account settings exclude shared proxies
premium_pool_unavailable403No Surfsky proxies credentials on the account
shared_pool_country_unavailable400No healthy shared proxies in the requested country
shared_traffic_limit_reached42930-day shared traffic budget is used up
premium_traffic_limit_reached429Premium traffic quota is used up
proxy_pool_unavailable400No tier is available for the account

Shared Proxies (Default)

When the shared tier is selected (see Choosing the tier) and no proxy is specified, Surfsky assigns a shared proxy from our pool.

Country targeting

You can request a shared proxy in a specific country by passing only the country field:

{
"proxy": {
"country": "us"
}
}

Shared proxies support country-level targeting only. If no matching proxy is available for the requested country, the request fails - pick another country or omit proxy to accept any location. Add "tier": "shared" to pin a request to this tier when your account also has premium (see Choosing the tier). For region targeting, use Surfsky proxies (the premium tier is required). The list of currently available countries is served by GET /proxies/shared/countries - see Get Shared Proxy Countries.

Depending on your plan, shared proxy traffic may be limited per 30-day window. Check your remaining traffic with GET /proxies/shared/quota - see Get Shared Traffic Quota.

Limitations:

  • Multiple users may share the same IP
  • Rate limits apply across all users
  • Not recommended for sites with strict anti-bot measures
  • IP reputation may vary

Good for:

  • Development and testing
  • Low-volume scraping
  • Learning the API

Using Your Own Proxies

Bring your existing proxy infrastructure to Surfsky. Simply provide the proxy URL when creating or starting a profile.

Supported Formats

# SOCKS5
"proxy": "socks5://username:[email protected]:1080"

# HTTP/HTTPS
"proxy": "http://username:[email protected]:8080"

# SSH
"proxy": "ssh://user:[email protected]:22"

# Shadowsocks
"proxy": "ss://method:[email protected]:8388"
# Example: ss://chacha20-ietf-poly1305:[email protected]:8388

Shadowsocks Methods

Supported encryption methods for Shadowsocks:

  • chacha20-ietf-poly1305 (recommended)
  • aes-256-gcm
  • aes-128-gcm
  • 2022-blake3-aes-128-gcm
  • 2022-blake3-aes-256-gcm
  • 2022-blake3-chacha20-poly1305

OpenVPN Configuration

For OpenVPN, use the open_vpn parameter instead:

{
"open_vpn": {
"config": "client\ndev tun\nproto udp\nremote vpn.example.com 1194\n...",
"username": "vpn_user",
"password": "vpn_pass"
}
}

WireGuard Configuration

For WireGuard VPN connections, use the wireguard parameter:

{
"wireguard": {
"private_key": "your_base64_private_key",
"address": ["10.0.0.2/32"],
"peers": [
{
"public_key": "server_base64_public_key",
"endpoint": "vpn.example.com:51820",
"allowed_ips": ["0.0.0.0/0", "::/0"]
}
]
}
}

WireGuard Parameters

ParameterRequiredTypeDescription
private_keyYesstringBase64-encoded WireGuard private key
addressYesarrayList of IP addresses for the interface (e.g., ["10.0.0.2/32"])
peersYesarrayList of WireGuard peer configurations
mtuNointegerMTU size (default: 1408)

Peer Parameters

ParameterRequiredTypeDescription
public_keyYesstringBase64-encoded peer public key
endpointYesstringPeer endpoint in host:port format
allowed_ipsNoarrayAllowed IP ranges (default: ["0.0.0.0/0", "::/0"])
pre_shared_keyNostringOptional pre-shared key for additional security
persistent_keepalive_intervalNointegerKeepalive interval in seconds

Generating WireGuard Keys

# Generate private key
wg genkey

# Generate public key from private key
echo "private_key" | wg pubkey

Note: You can only use one of proxy, open_vpn, or wireguard at a time.

Surfsky proxies

Managed proxy infrastructure with geo-targeting. Built for production workloads that need reliable, rotating IPs.

Setup Process

  1. Contact Support - Email [email protected] to enable proxy access
  2. Get Credentials - Receive your proxy provider credentials
  3. Start Using - Use geolocation parameters instead of proxy URLs

How It Works

Instead of managing proxy URLs, simply specify the location:

{
"proxy": {
"type": "residential", // Optional: "residential" (default) or "mobile"
"country": "us", // Optional: 2-letter country code
"region": "texas", // Optional: region/state name, requires country
"city": "dallas" // Optional: city name, requires region
}
}

Instead of country/region/city you can target a whole region with pool, or the nearest peer to a point with lat/lon:

{ "proxy": { "pool": "europe" } }
{ "proxy": { "lat": 48.8584, "lon": 2.2945 } }

And asn narrows a country to one ISP or mobile carrier:

{ "proxy": { "country": "us", "asn": 21928, "type": "mobile" } }

The system automatically:

  • Selects an appropriate proxy from the pool
  • Handles rotation and session management
  • Ensures IP quality and availability

Available Locations

Check available locations using our API:

# Get countries
GET /proxies/countries

# Get regions/states of a country
GET /proxies/regions/{country}

# Get cities of a region
GET /proxies/cities/{country}/{region}

# Get ISPs/carriers of a country
GET /proxies/asns/{country}

# Get regional pools and their countries
GET /proxies/pools

See Proxies API Reference for complete documentation.

Monitor Usage

Track your paid provider balance:

GET /proxies/quota
{
"success": true,
"data": {
"remaining_bytes": 10737418240,
"remaining_gb": 10.0
}
}

Once it runs out, starting a profile on the premium tier returns premium_traffic_limit_reached instead of a proxy error.

And your shared pool budget separately:

GET /proxies/shared/quota
{
"success": true,
"data": {
"limit_gb": 10,
"limit_bytes": 10000000000,
"used_bytes": 3000000000,
"remaining_bytes": 7000000000,
"remaining_gb": 7.0,
"reset_time": 1721822400
}
}

See Get Premium Quota and Get Shared Traffic Quota for the full field reference.

Proxy Features

Residential IPs

  • 50M+ IP pool across 190+ countries
  • Authentic residential connections
  • High trust scores on target sites

Rotation Control

  • Session duration: 1-60 minutes
  • Sticky sessions for consistent IPs
  • Automatic rotation on failure

Performance Metrics

  • 95%+ success rate
  • 200-500ms average latency
  • 5-15 Mbps typical bandwidth

Pricing

For proxy pricing and volume discounts, contact sales.