๐ŸŽ‰ Premium Proxies ยท 24-Hour Free TrialClaim Now
Guides

How to Use a Proxy for Only One Application

Route one browser, scraper or CLI tool through a proxy while the rest of the machine stays direct: app settings, launch flags, env vars, proxychains, Proxifier.

S SparkProxy 9 22 min read
Share

To use a proxy for only one application, you have to stop thinking about "the proxy setting" and start asking how that one program opens its sockets. A system-wide proxy is easy to switch on, but it drags your mail client, your updater and your video calls through the same exit IP. This guide ranks five per-app methods from the gentlest to the most forceful, gives a working SparkProxy example for each, and ends every one with a leak check you can run in under a minute.

Pick the Lightest Method That Reaches Your App

Every method below works by putting the proxy address somewhere that only one program reads. The further down the list you go, the less the app has to cooperate, and the more ways the setup can fail quietly. Start at the top and only move down when the app gives you no hook at that level.

MethodScopeApp must cooperate?Can carry user:pass?Platforms
1. App's own settingThat app, or one session object in codeYes, needs a proxy field or APIUsually yesAll
2. Launch flagOne launched instanceYes, must parse the flagChromium and Electron: noAll
3. Per-process env varsOne process and its childrenYes, must read the variablesYes, in the URLAll
4. proxychains-ngOne process tree, hooked at libcNo, but must be dynamically linkedYes, in the configLinux, BSD, macOS
5. Proxifier rulesMatched executables, system driverNoYes, in the profileWindows, macOS

Two rules hold across the whole table. First, a method that the app ignores fails open: the app connects direct and nothing tells you. Second, credentials are the most common blocker at levels 1 to 3, because several popular runtimes cannot send a proxy password from a flag. Plan the auth choice before you pick the method.

The SparkProxy Endpoint, Ports and Auth Choice

All examples use the SparkProxy gateway at gateway.sparkproxy.io. We confirmed on 2026-10-30 that the name resolves and that all three ports accept TCP connections.

PortProtocolRotationGood fit for one app that...
11000HTTP/HTTPSRandom Rotation, IP changes between requestsfetches independent pages, checks prices, runs a crawler
11002HTTP/HTTPSSticky Sessions, same IP for 5 minuteslogs in, keeps a cart, pages through results
13000SOCKS5as configured on your accountneeds non-HTTP TCP, or a tool that only speaks SOCKS

If you're unsure which rotation mode your app needs, our explainer on sticky session proxies walks through the login and cart cases.

SparkProxy accepts both IP whitelist and user:pass authentication. For per-app routing, the IP whitelist removes a whole class of failures: Chrome, Electron apps and Java's HTTPS client can all reach the gateway, then stall on a 407 because they won't send credentials from the place you configured them. Whitelisting your machine's public IP in the dashboard means the gateway never asks. The trade-off is that every program on a whitelisted machine could use the gateway if pointed at it, which is fine on your own workstation and worth thinking about on a shared server. How proxy authentication works covers both schemes in depth.

Cost doesn't change with the method. SparkProxy plans are packs with unlimited bandwidth, starting from $75/month (USD, read from the live pricing page on 2026-10-09), so routing a heavy browser through the gateway costs the same as routing a tiny CLI tool. What you're buying is the plan and its concurrency, not gigabytes. A 24-hour free trial with no credit card is enough to run every leak check in this guide.

Free trial

Scraping at scale? Skip the blocks.

Fast, unblockable datacentre proxies with unlimited bandwidth.

Method 1: The App's Own Proxy Setting

If the program has a proxy field, use it. It's the only method where the app knows it's being proxied and can handle auth prompts, retries and DNS itself.

Desktop apps often bury the field under Network or Connection settings. Firefox is the useful exception among browsers: it keeps its own proxy configuration per profile instead of borrowing the operating system's. Create a separate profile with firefox -P and give only that profile the proxy; your everyday Firefox stays direct. The full walkthrough, including the "Proxy DNS when using SOCKS v5" box, is in our Chrome and Firefox proxy guide.

For your own code, "the app's setting" means configuring the HTTP client object rather than the process. That keeps the proxy inside one session, so a second client in the same script can stay direct:

import os
import requests

PROXY = "http://{u}:{p}@gateway.sparkproxy.io:11002".format(
    u=os.environ["SPARK_USER"], p=os.environ["SPARK_PASS"]
)

proxied = requests.Session()
proxied.proxies = {"http": PROXY, "https": PROXY}

direct = requests.Session()
direct.trust_env = False  # ignore any HTTP(S)_PROXY inherited from the shell

print("via proxy:", proxied.get("https://api.ipify.org", timeout=20).text)
print("direct:   ", direct.get("https://api.ipify.org", timeout=20).text)

Setting trust_env = False on the direct session matters. Requests reads http_proxy, https_proxy, no_proxy and all_proxy (and their uppercase forms) by default, according to its advanced-usage docs, so a variable left in your shell can silently proxy the session you meant to keep clean.

Browser automation follows the same idea. Playwright accepts a proxy at launch or per browser context, and its network docs state you can "optionally specify username and password for HTTP(S) proxy". That's the cleanest way to give one automated Chromium instance an authenticated proxy without touching the rest of the machine:

import os
from playwright.sync_api import sync_playwright

with sync_playwright() as pw:
    browser = pw.chromium.launch()
    proxied = browser.new_context(proxy={
        "server": "http://gateway.sparkproxy.io:11000",
        "username": os.environ["SPARK_USER"],
        "password": os.environ["SPARK_PASS"],
    })
    page = proxied.new_page()
    page.goto("https://api.ipify.org")
    print("context exit IP:", page.inner_text("body"))
    browser.close()

Command-line tools usually have a one-shot flag that applies to a single invocation and writes nothing to disk. Prefer these over editing a global config file:

# one git command through the proxy, global config untouched
git -c http.proxy=http://USER:PASS@gateway.sparkproxy.io:11000 fetch origin

# one pip install
pip install --proxy http://USER:PASS@gateway.sparkproxy.io:11000 requests

# one curl call over SOCKS5, with DNS resolved at the proxy (socks5h)
curl -x socks5h://USER:PASS@gateway.sparkproxy.io:13000 https://api.ipify.org

Leak check for method 1: print the exit IP from inside the app (the snippets above already do), then run the same request from a second, unproxied client and confirm the two IPs differ. Our Windows and macOS setup guides list where persistent per-tool config files live if you later want them permanent; here, one-shot flags keep the blast radius to a single command.

Method 2: Launch Flags for Browsers, Electron and Java

Some programs have no settings screen for a proxy but read one from the command line when they start. The flag lives only as long as that process.

Chrome and Edge take --proxy-server. Pair it with a separate --user-data-dir; without one, an already-running Chrome tends to open the new window itself and the flag doesn't apply. Our browser guide has the per-OS commands, so here are only the two facts from the Chromium proxy documentation that decide whether per-app routing works:

  • Chrome "will not use any credentials embedded in the proxy settings", and "No authentication methods are supported for SOCKSv5 in Chrome". With SparkProxy, that means IP whitelist for the SOCKS5 port, or the HTTP port plus an auth prompt.
  • If the proxy is unreachable, requests "fail with ERR_PROXY_CONNECTION_FAILED", unless you append ,direct:// to the flag. Don't append it. Failing closed is exactly what you want when the point is that this one browser never shows your real IP.

Electron apps are Chromium underneath, and many accept the same switch. Electron's own command-line reference says --proxy-server "overrides the system setting" and that "The proxy URL does not support username and password authentication". VS Code documents the flag directly:

# VS Code through the rotating port; everything else on the machine stays direct
code --proxy-server="http://gateway.sparkproxy.io:11000" --proxy-bypass-list="localhost;127.0.0.1"

VS Code's network docs add that "SOCKS5 proxy authentication support isn't implemented yet", the same limit as Chrome. Whitelist your IP before you launch.

Java programs read proxy system properties passed with -D. Oracle's networking-properties reference lists http.proxyHost, https.proxyHost and socksProxyHost, each with a matching port property:

java -Dhttps.proxyHost=gateway.sparkproxy.io -Dhttps.proxyPort=11000 \
     -Dhttp.proxyHost=gateway.sparkproxy.io  -Dhttp.proxyPort=11000 \
     -jar crawler.jar

Here is the trap almost nobody mentions. The JDK's default net.properties contains jdk.http.auth.tunneling.disabledSchemes=Basic, which disables Basic auth when tunnelling HTTPS through an HTTP proxy with CONNECT. A user:pass proxy will therefore reject every HTTPS request from a stock JVM, and the source throws a message of the form Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 Proxy Authentication Required". You can re-enable Basic with -Djdk.http.auth.tunneling.disabledSchemes="" and an Authenticator in code, but if you can't modify the jar, IP whitelisting is the fix that needs no code.

Leak check for method 2: launch with the flag pointed at a dead port such as http://127.0.0.1:9. If the app still loads pages, it is ignoring the flag (or another instance handled the launch). Then switch to the real gateway and compare exit IPs.

Method 3: Environment Variables Scoped to One Process

HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY are a convention, not a standard, and each runtime picks which of them it honours. The per-app trick is scope: set them for one command and its children, never for the whole user or machine.

# Linux/macOS: the variables exist only for this one process
HTTPS_PROXY=http://USER:PASS@gateway.sparkproxy.io:11002 \
HTTP_PROXY=http://USER:PASS@gateway.sparkproxy.io:11002 \
python scraper.py
# PowerShell 7.4+: override variables for one child process only
Start-Process python -ArgumentList 'scraper.py' -NoNewWindow -Wait -Environment @{
    HTTPS_PROXY = 'http://USER:PASS@gateway.sparkproxy.io:11002'
    HTTP_PROXY  = 'http://USER:PASS@gateway.sparkproxy.io:11002'
}
:: cmd.exe: the variable dies with this inner shell (no space before &&)
cmd /c "set HTTPS_PROXY=http://USER:PASS@gateway.sparkproxy.io:11002&& python scraper.py"

Microsoft's Start-Process reference notes the -Environment parameter "was added in PowerShell 7.4". On Windows PowerShell 5.1, use the cmd /c form. If you need machine-wide variables on Windows instead, that's a different job, and the Windows datacenter proxy setup guide covers it.

Which programs actually read these? This is where per-app routing most often leaks:

RuntimeReads HTTPS_PROXY by default?Source or measurement
curlYes; `http_proxy` lowercase onlycurl man page, "Environment" section
Python requests and urllibYes, lower and upper caseRequests advanced docs; urllib measured below
Go `net/http` default transportYes, except requests to `localhost`Go `ProxyFromEnvironment` docs
Node.js `fetch` and `https`**No**, unless `NODE_USE_ENV_PROXY=1` or `--use-env-proxy`Node 24 CLI docs; measured below
JavaNo, uses `-D` propertiesOracle networking properties
Chrome, ElectronNo, uses flags or system settingsChromium proxy docs

We measured the two riskiest rows on Windows Server 2022 (build 20348) on 2026-10-30, using HTTPS_PROXY=http://127.0.0.1:9, a port with nothing listening. A client that honours the variable must fail; a client that ignores it connects direct.

  • Python 3.14.2 urllib.request failed with [WinError 10061] No connection could be made because the target machine actively refused it. It honoured the variable.
  • curl 8.15.0 failed with curl: (7) Failed to connect to 127.0.0.1 port 9 after 2000 ms: Could not connect to server. It honoured it too.
  • Node.js v24.22.0 fetch returned our server's real public IP. It ignored the variable completely.
  • The same Node call with NODE_USE_ENV_PROXY=1 failed with ECONNREFUSED, as it should.

That Node result is the single most common silent leak in "I set HTTPS_PROXY for my scraper" setups. The Node 24 docs list NODE_USE_ENV_PROXY as added in v24.0.0 and --use-env-proxy in v24.5.0, both at Stability 1.1 (Active Development), so on older Node versions you need an agent library instead.

# Node 24: opt in, or the variables are decoration
NODE_USE_ENV_PROXY=1 HTTPS_PROXY=http://USER:PASS@gateway.sparkproxy.io:11000 node crawl.mjs

Leak check for method 3: run the dead-port test above against your actual program before you trust it. One command, and it tells you whether the variable is real for that runtime.

Method 4: proxychains-ng on Linux and macOS

When the program has no proxy setting, ignores flags and doesn't read environment variables, proxychains-ng forces it. Its README describes it as hooking "network-related libc functions in DYNAMICALLY LINKED programs via a preloaded DLL (dlsym(), LD_PRELOAD)". The project is active: the latest tagged release is v4.17 (published 2024-01-21) and the most recent commit on the default branch is dated 2026-10-06, both read from GitHub on 2026-10-30.

The config's [ProxyList] comment says "only numeric ipv4 addresses are valid" (the changelog allows hostnames only "under specific circumstances"), so resolve the gateway first and write the IP into a per-app config file:

GW_IP=$(getent hosts gateway.sparkproxy.io | awk '{print $1; exit}')
mkdir -p ~/.proxychains
cat > ~/.proxychains/spark.conf <<EOF
strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks5 $GW_IP 13000 USER PASS
EOF

# only this process tree goes through the proxy
proxychains4 -f ~/.proxychains/spark.conf ./legacy-tool --fetch-all

On macOS, swap getent hosts for dig +short gateway.sparkproxy.io | head -1. Keep strict_chain with a single proxy: if the gateway is unreachable the connection fails instead of falling through. proxy_dns sends name lookups through the proxy so the app doesn't query your local resolver for every target.

Know the limits before you blame the proxy. All of these come from the proxychains-ng README:

  • TCP only. "It supports TCP only (no UDP/ICMP etc)." Anything the app sends over UDP, including QUIC, goes direct or fails.
  • Dynamic binaries only. Statically linked programs, which includes most Go binaries, never load the preload library. For those, graftcp traces socket syscalls with ptrace(2) instead and its README says "statically linked binaries such as most Go programs can be traced as well". It's Linux-only; v0.8.3 was released 2026-07-15 and the last commit is dated 2026-08-25.
  • macOS SIP. System Integrity Protection "prevents hooking of system apps". The README's workaround is to copy the system binary into your home directory and run that copy; a Homebrew-installed tool outside /usr/bin also works, and neither requires disabling SIP.
  • Scripting languages. The README warns that a glibc behaviour stops dlopen()ed modules from being hooked, which "mainly affects scripting languages such as perl or python". For Python, use method 1 or 3; they're more reliable anyway.

Leak check for method 4: run proxychains4 -f ~/.proxychains/spark.conf curl -s https://api.ipify.org. With quiet mode off, proxychains prints a line starting [proxychains] Strict chain that ends in OK or timeout, and curl prints the exit IP. Then run your real tool and watch for the same chain lines on each connection. A tool that prints no chain lines at all isn't being hooked.

Method 5: Rule-Based Routing With Proxifier on Windows

Windows has no built-in per-application proxy, and LD_PRELOAD has no direct Windows equivalent. A rule-based proxifier fills that gap by intercepting connections at the network layer and matching them to rules. Proxifier is the long-standing commercial option: the vendor's download page lists Windows v4.14 (2025-04-23) and macOS v3.15 (2025-09-18, macOS 12 to 26). The buy page prices the Standard, Portable and Mac editions at $39.95 USD each, as a perpetual license with free minor updates and a 31-day trial (read 2026-10-30).

The setup that keeps everything else direct takes four steps:

  1. Add the proxy. Profile, Proxy Servers, Add: gateway.sparkproxy.io, port 13000, SOCKS Version 5, with your username and password. Proxifier sends SOCKS5 auth itself, so unlike Chrome you don't need a whitelist here.
  2. Leave the Default rule on Direct. The docs call Default the rule Proxifier "uses when no other rule matches the connection". Direct here is what keeps the machine unproxied.
  3. Add one rule above it. Applications: scraper.exe; "My Tool.exe", Action: the SparkProxy proxy. The rules page says application lists accept wildcards, and "It is possible to specify a process ID using a notation such as pid=1234", handy for one instance of a program that runs several times. Rules are scanned "from top to bottom, so the order of rules is important".
  4. Keep the Localhost rule enabled. The docs warn that some applications, "such as Firefox, may depend on loopback connections".

Then fix DNS, because the default isn't what you want for a no-leak setup. Proxifier's Name Resolution page says the default "Detect DNS settings automatically" mode only enables "Resolve hostnames through proxy" when system DNS is unavailable. On a normal network, your proxied app's lookups still go to your local resolver. Turn automatic mode off and enable proxy resolution for strict isolation, accepting the documented cost that the app sees placeholder IPs "such as 127.8.." and IP-based rules stop matching.

Two more settings from the changelog are worth switching on. Version 4.11 added "Proxifier can now log and block UDP connections" and a master "DNS and IP Leak Prevention Mode" (Profile, Advanced). Blocking UDP for the proxied app means a browser's QUIC attempts fail, and browsers normally fall back to TCP, which the SOCKS5 rule can carry.

If you also run a VPN client or a local relay, read the "Connection Loop Problem" page first. A proxifier that captures the relay's own outbound traffic will loop until the machine runs out of connections; the fix is a Direct rule for the relay executable above everything else.

Leak check for method 5: open the Proxifier log, start your app and confirm each connection line names your app and the SparkProxy proxy. Then open a browser that isn't in the rule and check its IP: it should still be your own.

One Leak Check That Works for Every Method

Exit-IP checks catch the obvious failure. They don't catch DNS or UDP sneaking out beside a working TCP proxy. Run all three tests, in this order, every time you change a method:

# 1. Fail-closed test: point the app at a dead proxy. Success here = the app ignores your setting.
HTTPS_PROXY=http://127.0.0.1:9 your-app --one-request

# 2. Exit IP from inside the app vs. from an unproxied shell
curl -s https://api.ipify.org                                            # your real IP
curl -s -x http://USER:PASS@gateway.sparkproxy.io:11000 https://api.ipify.org   # a proxy IP

# 3. Rotation sanity: three calls on 11000 should usually differ, three on 11002 should match
for i in 1 2 3; do curl -s -x http://USER:PASS@gateway.sparkproxy.io:11002 https://api.ipify.org; echo; done

For a browser, add two checks the shell can't do: load a DNS leak test page to see which resolvers answer, and check WebRTC, since it uses UDP and can bypass an HTTP proxy. Our DNS leak testing guide and the explainer on WebRTC leaks cover both. On macOS, the Mac proxy configuration guide shows how to confirm no system-wide proxy is set, which matters here: if one is, your "per-app" test is measuring the system setting, not your method.

For Scrapers: Skip Local Routing With the Scraping API

If the one application is a scraper you wrote, there's a way to avoid machine-level routing entirely: the scraper calls the SparkProxy Scraping API as an ordinary HTTPS endpoint, and the API fetches the target through SparkProxy's pool. Nothing on your machine needs a proxy setting, so nothing can leak, and the only outbound connection is to scrape.sparkproxy.io.

import base64
import os
import requests

API = "https://scrape.sparkproxy.io/api/v1"
HEADERS = {"X-API-Key": os.environ["SPARK_API_KEY"]}


def fetch(target, country=None):
    params = {
        "url": target,
        "render_js": "false",      # plain fetch, 1 credit (render_js defaults to true, 5 credits)
        "proxy_type": "premium",
        "json_response": "true",   # the only way to get the envelope
    }
    if country:
        params["country_code"] = country   # +5 credits
    r = requests.get(API, headers=HEADERS, params=params, timeout=60)
    r.raise_for_status()
    env = r.json()
    html = base64.b64decode(env["body"]).decode("utf-8", "replace")  # body is base64
    return env["status_code"], env["credits_used"], html


status, credits, html = fetch("https://www.sparkproxy.io/")
print(status, credits, len(html))

Two rules from the API reference keep this correct. format only converts content (html, md, mdx, json, screenshot, pdf); it is not the envelope. json_response=true is the only source of job_id, status_code, duration_ms, credits_used and body, and that body is base64, so decode it before matching anything. Don't stack extract_rules with json_response, since extract_rules replaces the response with an extracted object. New accounts get 1,000 free credits, which is enough to validate a scraper before you decide between the API and raw proxies.

Error Strings and the Method Each One Points To

Every string below was either produced against the SparkProxy gateway on 2026-10-30 or quoted from the tool's own documentation or source.

What you seeWhat it meansFix
`curl: (56) CONNECT tunnel failed, response 407`Gateway reached, no valid credentials and IP not whitelistedAdd user:pass to the proxy URL, or whitelist your IP
`HTTP/1.1 407 Proxy Authentication Required` (in `curl -v`)Same 407, seen rawSame
`curl: (97) cannot complete SOCKS5 connection to api.ipify.org. (2)`SOCKS5 port reached, request refused: no auth sent and IP not whitelistedUse `socks5h://USER:PASS@...:13000`, or whitelist
`ERR_PROXY_CONNECTION_FAILED` (Chrome)Proxy unreachable; Chrome failed closedCheck host and port; don't add `,direct://`
`Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407 ..."` (Java)JVM won't send Basic auth over CONNECT by defaultWhitelist your IP, or re-enable Basic plus an Authenticator
`proxychains: can't load process '...'.`proxychains couldn't start the targetCheck the path; the binary must exist and be executable
`[proxychains] Strict chain ... timeout`Proxy in `[ProxyList]` didn't answerRe-resolve the gateway IP; check the port is 13000 for socks5
App works but shows your real IPThe method isn't reaching this appRun the dead-port test; move one method down the ladder

The last row is the one a proxy can't fix by itself. A 407 or a SOCKS refusal is an auth problem you solve in the dashboard. An app that ignores your setting is a routing problem, and the answer is a more forceful method, not a different proxy.

Frequently asked questions

FAQ

Use the app's own proxy field if it has one, launch flags for Chrome, Edge or Electron apps, or cmd /c "set HTTPS_PROXY=...&& app.exe" for tools that read environment variables. For programs with no hook at all, a rule-based tool like Proxifier routes only the executables you list and leaves the Default rule on Direct.

Yes. Launch Chrome with --proxy-server and a separate --user-data-dir, which applies only to that instance. Chrome won't send credentials from the flag and supports no SOCKS5 auth, so whitelist your IP or use the HTTP port and answer the auth prompt.

Node's built-in fetch and https modules don't read proxy variables by default. In our test, Node v24.22.0 returned the real IP with HTTPS_PROXY set; adding NODE_USE_ENV_PROXY=1 (Node 24 and later) made it use the proxy.

No. proxychains-ng hooks libc through LD_PRELOAD, so it only works on dynamically linked programs, carries TCP only, can't hook macOS system binaries under SIP, and is unreliable with Python and Perl modules. Statically linked Go binaries need a ptrace-based tool such as graftcp instead.

It can. HTTP and SOCKS proxies carry TCP, so UDP traffic such as WebRTC and QUIC may go direct, and some tools resolve DNS locally unless told otherwise. Use socks5h:// in curl and requests, proxy_dns in proxychains, proxy name resolution plus UDP blocking in Proxifier, then run a DNS and WebRTC leak test.

Use port 11000 (Random Rotation) for apps that make independent requests, such as crawlers and price checks. Use port 11002 (Sticky Sessions, same IP for 5 minutes) for anything that logs in or holds a session, and port 13000 when the app needs SOCKS5.

Special Discount ยท 20% off

Get 20% off your first month

Premium datacentre proxies with unlimited bandwidth. Use the code at checkout.

Save up to 15% more on quarterly, half-yearly and yearly plans

Claim Discount

About the Author

SparkProxy Technical Team builds and runs SparkProxy's proxy network (1M+ premium IPs across 80+ countries, HTTP/HTTPS/SOCKS5, IP whitelist and user:pass auth, 1 Gbps ports) and the SparkProxy Scraping API. The gateway responses, curl, Python and Node.js measurements in this guide were taken on Windows Server 2022 build 20348 on 2026-10-30; tool versions, release dates and prices were read from each project's or vendor's own pages that day.

Keep reading

Related articles