Skip to content
NextProxyNextProxyDocs

cURL

A complete command reference for verifying the proxy, debugging options, and reading timing data with curl.

curl is the most useful debugging tool here because it hides nothing — what you see is what happened. Get your options working with curl before wiring up any other language.

The basic form

shell
curl -x 'http://USERNAME-country-US:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org

Protocol variants

shell
# HTTP proxy, HTTPS site (via a CONNECT tunnel)
curl -x 'http://USER:PASS@GATEWAY_HOST:58971' https://example.com

# HTTP proxy, HTTP site (forward mode)
curl -x 'http://USER:PASS@GATEWAY_HOST:58971' http://example.com

# SOCKS5, proxy resolves the hostname (recommended)
curl -x 'socks5h://USER:PASS@GATEWAY_HOST:58971' https://example.com

# SOCKS5, local resolution (leaks your local DNS)
curl -x 'socks5://USER:PASS@GATEWAY_HOST:58971' https://example.com

Keeping credentials out of the URL

Use -U when you'd rather not embed them:

shell
curl -x 'http://GATEWAY_HOST:58971' \
  -U 'USERNAME-country-US-session-job1-time-30:PASSWORD' \
  https://api.ipify.org

Or read from environment variables to keep them out of shell history:

shell
export NP_USER='USERNAME'
export NP_PASS='PASSWORD'
export NP_GW='GATEWAY_HOST:58971'

curl -x "http://${NP_USER}-country-US:${NP_PASS}@${NP_GW}" https://api.ipify.org

A shell function to compose options

Retyping the whole URL while tuning options invites mistakes. Use a function:

shell
# Usage: np -country-US-session-a1-time-10 https://api.ipify.org
np() {
  local suffix="$1"; shift
  curl -x "http://${NP_USER}${suffix}:${NP_PASS}@${NP_GW}" "$@"
}

np '-country-US' https://api.ipify.org
np '-country-DE-session-de1-time-15' https://ipinfo.io/json
np '' https://api.ipify.org   # no options at all

Seeing where the time goes

shell
curl -s -o /dev/null \
  -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' \
  -w 'dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s ttfb=%{time_starttransfer}s total=%{time_total}s\n' \
  https://example.com

How to read the numbers:

FieldIf it's high
time_namelookupResolving the gateway hostname is slow; nothing to do with the proxy
time_connectNetwork trouble between you and the gateway; try a closer node
time_appconnectSlow TLS handshake, usually on the exit-to-target leg
time_starttransferThe target site is generating the response

Watching the full protocol exchange

-v shows the proxy negotiation:

shell
curl -v -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' https://api.ipify.org 2>&1 | head -40

The lines that matter look like this:

text
* CONNECT tunnel: HTTP/1.1 negotiated
> CONNECT api.ipify.org:443 HTTP/1.1
> Proxy-Authorization: Basic dXNlcjpwYXNz
< HTTP/1.1 200 Connection Established
* CONNECT phase completed
* TLSv1.3 (OUT), TLS handshake, Client hello (1):

Seeing 200 Connection Established means everything on the proxy side worked; anything after that is between you and the target site.

Mapping the common errors

shell
# 407: missing credentials, malformed Basic / Base64, or incorrect username/password
curl -v -x 'http://GATEWAY_HOST:58971' https://api.ipify.org

# 400 invalid_proxy_parameters: invalid username option syntax
curl -v -x 'http://USER-country-us:PASS@GATEWAY_HOST:58971' https://api.ipify.org
#                              ^^ lowercase → 400

# 503 service_unavailable: valid options but no eligible route currently matched
curl -v -x 'http://USER-country-ZZ:PASS@GATEWAY_HOST:58971' https://api.ipify.org
#                              ^^ valid shape, no eligible route → 503

The full mapping is in the error reference.

Forcing new connections to change IP

Each curl invocation is a new process and connection, so a loop naturally re-routes:

shell
for _ in $(seq 1 5); do
  curl -s -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' https://api.ipify.org
  echo
done

But if you request several URLs in one curl command, curl reuses the connection and the exit stays the same:

shell
# Both requests share one tunnel and one IP
curl -s -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' \
  https://api.ipify.org https://api.ipify.org

Passwordless ports

Ports obtained from the Extract API need no credentials:

shell
curl -x http://1.2.3.4:20001 https://api.ipify.org

Downloading large files

shell
curl -x 'http://USER-country-US-session-dl1-time-120:PASS@GATEWAY_HOST:58971' \
  --retry 3 --retry-delay 2 \
  -C - -o dataset.tar.gz \
  https://example.com/dataset.tar.gz
  • -C - resumes, so a dropped connection can pick up where it left off
  • Adding session keeps retries on the same exit; many sites validate the IP on range requests
  • time-120 is the maximum — give long downloads plenty

Timeout configuration

Relevant gateway-side timeouts: 5s to first byte, 10s for the full handshake, 8s for the exit TCP connect, 30s for the exit handshake, 5 minutes idle, 24 hours maximum per connection.

Set client-side timeouts slightly wider than the gateway's, so it's clear which side timed out:

shell
curl -x 'http://USER-country-US:PASS@GATEWAY_HOST:58971' \
  --connect-timeout 15 \
  --max-time 120 \
  https://example.com

The full list is in Limits and quotas.

Don't reach for --proxy-insecure

The gateway does no inbound TLS, so there is no TLS on the proxy leg and --proxy-insecure is meaningless here.

If you see certificate errors, they come from the target site, not the proxy. Skipping verification with -k is only appropriate for temporary diagnosis when you already know why.

Did this page solve your problem?