Residential Proxies

Setting Up Residential Proxies in cURL and Postman

Both tools handle proxies well, and both have a setting that quietly breaks things. Here is the working configuration for each, and how to debug the rest.

Chris Collins

Chris Collins

August 31, 2026 · 6 min read

Before a proxy goes anywhere near application code, it is worth proving it works from a tool you can inspect. cURL and Postman are the two that most developers reach for, and both handle proxies well once configured, but each has a setting that produces confusing behaviour if you miss it. Here is the working setup for both, the debugging flags that matter, and the traps.

The connection details are the same everywhere: host p.shifter.io, port 443, and a username that carries your targeting. The format reference is in how to connect to a residential proxy.

cURL

The whole configuration is one flag.

curl -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json

-x and --proxy are the same thing. Run that twice and the address should differ, which confirms both credentials and rotation in one step.

Targeting goes in the username, so nothing else about the command changes:

# German exit
curl -x customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://ipinfo.io/json

# sticky session, ten minutes
curl -x customer-USERNAME-country-de-sid-abc123-ttl-600:PASSWORD@p.shifter.io:443 https://ipinfo.io/json

Keeping credentials out of your shell history

Embedding a password in the URL puts it in your history and in any process listing. Two better options:

# credentials passed separately
curl -x p.shifter.io:443 -U customer-USERNAME-country-de:PASSWORD https://ipinfo.io/json

# or from the environment
export PROXY_USER="customer-USERNAME-country-de"
export PROXY_PASS="..."
curl -x p.shifter.io:443 -U "$PROXY_USER:$PROXY_PASS" https://ipinfo.io/json

Note that -U is proxy credentials and -u is credentials for the target site. Confusing the two is a common cause of a 407 with a perfectly good password.

Debugging flags worth knowing

# see the proxy handshake and whether auth succeeded
curl -v -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json

# timing breakdown: where the latency actually goes
curl -o /dev/null -s -w "connect: %{time_connect}s  ttfb: %{time_starttransfer}s  total: %{time_total}s\n" \
  -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com

That second one is the quickest way to separate a slow proxy connection from a slow target, which is the first fork in why requests time out and the starting point for reducing latency.

SOCKS5 in cURL, and the trap

If you use SOCKS5 rather than HTTP, the scheme matters more than it looks:

# leaks DNS: your machine resolves the hostname
curl -x socks5://customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com

# correct: the proxy resolves it
curl -x socks5h://customer-USERNAME:PASSWORD@p.shifter.io:443 https://example.com

The h is the entire difference, and getting it wrong means your DNS queries go out from your own location, which can return regionally wrong results. Details in preventing DNS leaks.

One flag never to ship

--proxy-insecure disables certificate verification on the proxy leg. It is occasionally useful to confirm that a TLS error is a certificate problem rather than something else, and it must never appear in anything permanent.

Postman

Postman’s proxy support is solid, but it is configured in application settings rather than per request, which surprises people who expect it on the request itself.

Configuring it

Open Settings, then the Proxy tab. Turn off the system proxy option and enable the custom proxy configuration. Set the proxy server to p.shifter.io and the port to 443, tick both HTTP and HTTPS, then enable proxy authentication and enter your username, including any targeting flags, and your password.

That configuration is global to the Postman app, which is the thing to keep in mind: once set, every request in every collection goes through the proxy until you turn it off. If you are also testing internal services, they will be routed too, which is usually not what you want.

The setting that breaks things

In Settings then General, there is SSL certificate verification. If you hit certificate errors through the proxy and turn it off, remember that you have disabled verification for everything Postman does, not just the proxied request. Turn it back on afterwards. If you are seeing certificate errors at all, that is worth understanding rather than switching off.

Switching targeting without retyping

Because targeting lives in the username, changing country means editing one field. Postman variables make that less tedious: define an environment with a variable for the proxy username, then swap environments to swap markets. The proxy settings dialog accepts the variable syntax, so customer-USERNAME-country-{{market}} lets you change country by changing the active environment rather than by opening settings each time.

Verifying it works

Send a GET to https://ipinfo.io/json and read the response. It should report an address in the country you targeted, not your own. Send it twice with no sid in the username and the address should change.

If the address is your own, the proxy is not being applied at all: check that the custom proxy configuration is actually enabled and that both HTTP and HTTPS are ticked.

The Collection Runner

For testing at slightly larger volume, the Collection Runner will run a collection repeatedly through the same proxy configuration. Add a delay between iterations rather than running flat out, since a burst of identical requests is the fastest way to get a target to stop answering, per rate limiting and throttling.

When something fails

Four responses cover nearly everything, and each points somewhere specific.

407 means credentials were rejected, or a flag in the username is malformed, since an unrecognised value makes the whole username unparseable. Test the bare username with no flags first; if that works, add them back one at a time. Full path in fixing 407 errors.

502 means your credentials were fine but nothing matched your filter at that moment. Broaden it, or drop from city to country.

509 means plan bandwidth is exhausted with overage disabled.

Connection refused or a hang means you never reached the gateway. Check nc -vz p.shifter.io 443 before assuming a proxy problem, and confirm you are not pointing at a legacy host.

The wider index is in common residential proxy errors.

Moving from tools to code

Once both tools work, the same four values transfer directly into whatever you are building, and the client-side patterns are in using residential proxies with Python. One thing that does not transfer: in application code, connection reuse means requests sent down an existing tunnel keep the same exit address, which looks exactly like rotation failing. That surprise is covered in IP not rotating.

The bottom line

In cURL the whole thing is -x, with -U to keep credentials out of the URL, -v to see the handshake, and -w to find out whether slowness is the proxy or the target; if you use SOCKS5, use socks5h so DNS resolves at the proxy. In Postman the configuration lives in application settings rather than on the request, so it applies globally until you disable it, and the SSL verification toggle is app-wide rather than request-specific. In both, targeting lives in the username, so switching country never means changing host, port, or anything else. Prove it works in a tool you can inspect before putting it in code, and read the failures by status code.

The gateway behind all of this is residential proxies, one host and one credential pair across every country and session mode, billed per GB so testing costs only the bandwidth it uses.

Ready to get started?

Try Shifter's residential proxies, 205M+ IPs, 195+ countries, from $0.75/GB.

Get Started