How to Use a Proxy with cURL (2026 Guide)

By Marcus Reiner · 2026-05-23 · 11 min read · Engineering

#curl#command line#code

cURL + proxy in 30 seconds, or curl-impersonate for true browser fingerprint mimicry. Here's both.

EDITOR'S TOP PICK
IPRoyal
Pay-as-you-go residential with no expiry
From $1.75/GB · 4.6/5 stars · Trust Score 91/100
Visit IPRoyal → Read full review

The short answer: one flag and one credential string

To send a curl request through a proxy you need exactly two things: the -x (or --proxy) flag with your gateway host and port, and a username:password pair passed either inline or with -U. Everything else in this guide is about making that connection reliable, debuggable and safe to put in production.

The canonical form looks like this: curl -x http://USER:[email protected]:7000 https://httpbin.org/ip. If the response shows an IP that is not your own, the proxy is working. If it hangs, returns 407, or shows your real IP, the causes are almost always one of five things covered in the troubleshooting section below.

We test curl-based proxy setups against every provider we review, and IPRoyal remains the easiest to get running from a cold start: pay-as-you-go credit, a gateway that accepts standard username:password auth, and no dashboard gymnastics before your first successful request.

Basic HTTP and HTTPS proxy commands

curl treats the proxy protocol and the target protocol separately. The -x value describes how to reach the proxy; the URL describes what you are fetching through it. A plain HTTP proxy can still tunnel HTTPS traffic via CONNECT, which is why http:// in the proxy string with an https:// target is normal and correct.

Use --proxy-insecure only when your provider terminates TLS with a self-signed certificate on the proxy hop itself. It does not weaken the TLS session to the target site, but it should still be a deliberate choice rather than a reflex when something fails.

socks5 vs socks5h: the difference that breaks scrapers

With socks5://, curl resolves the hostname locally and sends an IP address to the proxy. With socks5h://, the hostname is sent to the proxy and resolved there. For proxy work you almost always want socks5h, because local DNS resolution leaks your real location to your resolver and can send you to a CDN edge node near you rather than near the exit IP.

This single character explains a large share of the cases where a geo-targeted proxy returns content for the wrong country. If your German residential IP keeps returning US pricing, check the scheme before you blame the pool.

Sticky sessions and rotation from the command line

Rotating gateways give you a new exit IP on every request by default. That is correct for stateless work like fetching product pages, and wrong for anything with session state: a login, a paginated dashboard, a multi-step checkout.

Providers expose stickiness through the username string rather than a separate host. Common patterns are user-session-abc123, user-sessid-abc123 or user-sticky-1 with a TTL between 1 and 30 minutes depending on the vendor. Generate the session token yourself so you can reuse it across the requests that belong to one logical flow, then discard it.

Country and city targeting works the same way: user-country-de-city-berlin. Because it is all inside the username, curl needs no extra flags, which makes the pattern trivial to script.

Keeping credentials out of your shell history

Inline credentials end up in ~/.bash_history, in ps output while the command runs, and in CI logs. For anything beyond a one-off test, move them into a .netrc file or environment variables.

Create ~/.netrc with a machine entry for your gateway host, chmod 600 it, then run curl --netrc -x http://gate.example.com:7000 https://example.com. curl reads the credentials without them ever appearing on the command line. Alternatively export http_proxy and https_proxy so every curl call in the shell uses the proxy with no flags at all - useful for quick debugging sessions, dangerous if you forget you set it.

In CI, use the platform secret store and inject at run time. Rotating a leaked proxy credential is cheap; explaining a month of unexpected bandwidth on someone else's scraping run is not.

Reading curl output when something fails

Verbose mode is the whole diagnostic toolkit. curl -v prints the CONNECT request to the proxy, the proxy response line, the TLS handshake with the target, and the final HTTP status. The layer that fails tells you where the problem is: a failed CONNECT is a proxy or credential issue, a failed handshake is TLS or fingerprinting, a 403 after a successful handshake is the target site blocking the exit IP.

Add -w with timing variables to separate slow proxies from slow targets. If time_connect is 1.8s and time_total is 2.0s, the proxy hop is your bottleneck and a closer gateway region will fix it. If time_connect is 90ms and time_total is 6s, the target is slow or you are being tarpitted.

Common curl proxy errors and what actually causes them

Most failures fall into a handful of buckets, and the fix is usually configuration rather than provider quality. Work through them in order before opening a support ticket.

Making requests look human

A clean residential IP with a default curl fingerprint still gets blocked, because curl announces itself in the User-Agent and presents a TLS fingerprint no browser produces. At minimum set a current browser User-Agent, an Accept-Language header, and Accept-Encoding, and let curl follow redirects with -L.

For targets behind Cloudflare, DataDome or PerimeterX, header hygiene is not enough - the JA3 TLS hash gives you away regardless of headers. Either move to a build of curl compiled against a browser TLS profile, or use a managed unblocking endpoint where the vendor maintains the fingerprint for you. That is the trade we describe in our Cloudflare bypass guide, and it is why teams with hard targets end up on a scraping API instead of raw proxies.

A production-ready wrapper script

Once the single command works, wrap it. A useful wrapper does four things: reads credentials from the environment, generates a session token per logical flow, retries on 429 and 5xx with exponential backoff, and logs the exit IP alongside the status so you can correlate failures with specific subnets.

Cap retries at three and add jitter. Hammering a target that just rate-limited you is the fastest way to escalate from a soft 429 to a hard IP ban, and on a rotating pool that damage is shared with every other customer using those IPs.

Cost reality check

curl is bandwidth-billed like everything else. A residential GB in 2026 runs roughly $1.75 at the budget end to $8-15 at the enterprise end, and 1 GB covers approximately 5,000-10,000 lightweight HTML fetches or 1,500-3,000 image-heavy product pages.

Two habits cut spend materially: request compression (Accept-Encoding: gzip, which curl handles with --compressed) and skipping assets you do not parse. If you only need prices, do not download images. Teams routinely halve their bill with those two changes before touching provider pricing.

For learning and low-volume work, pay-as-you-go beats a subscription. IPRoyal and Webshare both let you start with a few dollars of credit, which is the right way to validate a target before committing to a plan.

Where to go from here

Once curl works end to end, port the same credential and session pattern into your language of choice - the gateway semantics are identical in Python requests, Node fetch and Go. Our proxy authentication explainer covers the IP-allowlist alternative to username:password, and our proxy error codes reference maps every status you will meet in production to a specific fix.

If your target sits behind serious bot management, read the JavaScript rendering guide next: at that point the question stops being which proxy and starts being which rendering layer.

Quick Comparison Top Providers
1
Bright Data
From $8/GB · 4.9/5
2
Oxylabs
From $8/GB · 4.8/5
3
Decodo
From $2/GB · 4.7/5
Compare all providers side by side →
EDITOR'S TOP PICK
IPRoyal
Pay-as-you-go residential with no expiry
From $1.75/GB · 4.6/5 stars · Trust Score 91/100
Visit IPRoyal → Read full review

Frequently Asked Questions

How do I use curl with a proxy that needs a username and password?

Pass them inline as curl -x http://user:pass@host:port https://example.com, or keep them off the command line with -U user:pass or a chmod 600 ~/.netrc file plus --netrc.

Why does curl still show my real IP?

Usually the -x value was single-quoted so shell variables never expanded, the target matched your no_proxy list, or the request failed and curl fell back to a direct connection. Run curl -v and confirm a CONNECT line appears.

What is the difference between socks5 and socks5h in curl?

socks5 resolves DNS locally and leaks your real location to your resolver; socks5h resolves at the proxy. Use socks5h for any geo-targeted work.

How do I keep the same IP across several curl requests?

Add a session token to the username, for example user-session-abc123, and reuse that exact username for every request in the flow. Most providers hold the IP for 1 to 30 minutes.

What does 407 Proxy Authentication Required mean?

The proxy rejected your credentials. Either the username or password is wrong, or your account uses IP allowlisting and the machine making the request is not on the list. It is never a transient error, so do not retry it.

Can curl bypass Cloudflare with a good proxy?

Not on its own. A clean residential IP helps, but curl's TLS fingerprint is identifiable. You need a browser-matched TLS build or a managed unblocking endpoint for protected targets.

Which proxy provider is easiest to test with curl?

IPRoyal for pay-as-you-go credit and standard gateway auth, Webshare if you want a free tier to confirm your command syntax before spending anything.

Related Resources on ToptierProxy