Skip to main content
[ DOCS / PYTHON ]

Python proxy integration, working in 60 seconds

Use residential proxies in Python with the code you already have. No SDK, no client library, no API key: give requests, aiohttp or httpx one proxy URL and every request leaves from a real home IP, in the country you pick, with the browser fingerprint you pick.

  • One proxy URLrequests, aiohttp and httpx work as they are
  • Real home IPs219 countries, down to the city
  • Browser TLS at the gateway139 fingerprints, no curl_cffi

No plan yet? The smallest one is the test: 1 GB of Residential for $0.99, no subscription.

KEY FACTS

  • Ludax works with any Python HTTP client through one proxy URL, http://resi-USERNAME:[email protected]:7777: no SDK, no client library, no API key.
  • Without a session token every new connection leaves from a new residential IP. With -session-<token>-time-<minutes> in the password the IP holds for up to 1000 minutes; without -time- it holds for 1 minute. On the TLS ports add -sameip to hold the IP too.
  • The location goes in the password after the session: -country-de, then -state-by, then -city-munich.
  • Residential TLS (gw.ludaxproxy.com:9999) and Residential Premium TLS (gw.ludaxproxy.com:8081) connect to the site with a real browser TLS handshake, chosen in the username (-AE-chrome154, 139 profiles), and need the Ludax CA certificate.
  • 407 means a wrong username or password, or a plan with no data left; 502 means the exit failed and a retry helps. 30 failed logins in 5 minutes block the client IP for 10 minutes.
  • SOCKS5 runs on Residential (gw.ludaxproxy.com:7575) and Residential Premium (gw.ludaxproxy.com:1080); socks5h:// makes the exit resolve DNS.
  • Plans are prepaid, with no subscription, from $0.99 for 1 GB of Residential.

Using an AI assistant? Give it this guide

One Markdown file with everything ChatGPT, Claude, Cursor or Copilot needs to write working Ludax code: the URL format, the gateways in force, sessions, TLS, errors and tested examples. Copy it into the chat, or paste this prompt:

Read https://ludaxproxy.com/docs/python.md and use Ludax proxies in my Python scraper.

[ 01 / QUICKSTART ]

Set up a proxy in Python requests in three steps

Two minutes, start to finish. If you see a JSON answer at the end, your Python proxy is connected, and everything after this is options.

  1. Get your username and password

    In the dashboard, open Generate. Your username looks like lx_k3m9q2p7xa and is the same for all your plans; each plan has its own 16-character password. In the proxy URL the username gets the product prefix: resi- for Residential, premi- for Residential Premium.

    No account yet? Get 1 GB of Residential for $0.99: an email address is all it takes, you pay in crypto, and you are ready in a minute.

  2. Install requests

    terminal.sh
    pip install requests
  3. Run this

    first_request.py
    import requests
    
    proxy = "http://resi-lx_k3m9q2p7xa:[email protected]:7777"
    
    r = requests.get(
        "https://api.ludaxproxy.com/whoami",
        proxies={"http": proxy, "https": proxy},
        timeout=30,
    )
    print(r.json())

    You should see something like this, with your own exit IP:

    output
    {'ip': '203.0.113.24', 'country': 'Germany', 'type': 'residential', 'tls_profile': None, 'latency_ms': 412}

    That is a real home connection in Germany, picked by -country-de in the password. tls_profile is None because the site sees Python’s own handshake (why that matters). Change de to us, jp or any of the 181 country codes and run it again.

[ 02 / CODE GENERATOR ]

Python proxy code generator: pick, copy, run

Choose the product, the country and how the IP should behave, and the code writes itself for requests, aiohttp or httpx. Type your own username and password to get code you can run as is: they stay in this browser tab and are never sent anywhere.

Product

Real home IPs for everyday scraping. Gateway: gw.ludaxproxy.com:7777

IP address

YOUR CONNECTION STRING

http://resi-lx_k3m9q2p7xa:YOUR_PASSWORD-country-us@gw.ludaxproxy.com:7777
  • username (+ browser on TLS)
  • password
  • session
  • location
  • gateway
scrape.py
import requests

proxy = "http://resi-lx_k3m9q2p7xa:[email protected]:7777"
proxies = {"http": proxy, "https": proxy}

# a new IP on every new connection
r = requests.get("https://api.ludaxproxy.com/whoami", proxies=proxies, timeout=30)
print(r.json())
[ 03 / RECIPES ]

Python proxy recipes: rotating, sticky, geo and async

Each one runs on its own: paste it, put in your username and password, run. The outputs show what you should see.

01

Rotating proxies in Python: a new IP on every request

Scraping many pages where no page should see the same visitor twice, as in web scraping and price monitoring.

rotate.py
import requests

USER = "resi-lx_k3m9q2p7xa"
PASS = "YOUR_PASSWORD-country-us"
proxy = f"http://{USER}:{PASS}@gw.ludaxproxy.com:7777"

for i in range(5):
    # requests.get opens a new connection each time, so each call gets a new IP
    r = requests.get("https://api.ludaxproxy.com/whoami",
                     proxies={"http": proxy, "https": proxy}, timeout=30)
    print(i, r.json()["ip"])
output (your IPs will differ)
0 203.0.113.24
1 198.51.100.7
2 203.0.113.181
3 192.0.2.66
4 198.51.100.142

Official docs: requests: proxies

02

Sticky sessions: the same IP for a whole flow

Login, search, add to cart, checkout: anything a site expects from one visitor. A random token per job keeps each job on its own IP.

sticky_loop.py
import secrets
import requests

USER = "resi-lx_k3m9q2p7xa"
PASS = "YOUR_PASSWORD"

for job in range(3):
    token = secrets.token_hex(4)  # a new random proxy session = a new IP for this job
    proxy = f"http://{USER}:{PASS}-session-{token}[email protected]:7777"

    # requests.Session keeps the site's cookies (your login) from one step to the next
    with requests.Session() as s:
        s.proxies = {"http": proxy, "https": proxy}
        ips = [s.get("https://api.ludaxproxy.com/whoami", timeout=30).json()["ip"]
               for step in ("login", "search", "checkout")]
    print(f"job {job} (session {token}): {ips}")
output (your IPs will differ)
job 0 (session 9f2c41ab): ['203.0.113.24', '203.0.113.24', '203.0.113.24']
job 1 (session 0d77e3c5): ['198.51.100.7', '198.51.100.7', '198.51.100.7']
job 2 (session c41a9e02): ['192.0.2.66', '192.0.2.66', '192.0.2.66']

Two different sessions work together here. The proxy session (-session- in the password) keeps the IP; the requests.Session keeps the cookies, so the site still knows you are logged in. A login flow needs both. Proxy sessions hold for up to 1000 minutes on every plan; always send -time-, without it a session lasts 1 minute. On the TLS ports add -sameip after the time (-session-9f2c41ab-time-10-sameip), or only the browser profile is held and the IP still changes.

Official docs: requests: Session objects

03

Geo-targeting: a country, a region, a city

Local prices, local search results, local ads.

geo.py
import requests

def proxy(password):
    url = f"http://resi-lx_k3m9q2p7xa:{password}@gw.ludaxproxy.com:7777"
    return {"http": url, "https": url}

# a country
requests.get("https://api.ludaxproxy.com/whoami", proxies=proxy("YOUR_PASSWORD-country-jp"), timeout=30)

# a region and a city in it (Bavaria, Munich)
requests.get("https://api.ludaxproxy.com/whoami",
             proxies=proxy("YOUR_PASSWORD-country-de-state-by-city-munich"), timeout=30)

# everything together: one IP in New York for 30 minutes
requests.get("https://api.ludaxproxy.com/whoami",
             proxies=proxy("YOUR_PASSWORD-session-ny01-time-30-country-us-state-ny-city-newyork"), timeout=30)

Order matters: session first, then -country-, -state-, -city-. Codes for every country are in the locations directory (for example Germany, the United States and Japan) and in the dashboard's generator.

04

Async proxies with aiohttp

50 pages, ten at a time, each from a different IP.

async_aiohttp.py
import asyncio
import aiohttp

PROXY = "http://resi-lx_k3m9q2p7xa:[email protected]:7777"
URLS = [f"https://api.ludaxproxy.com/whoami?page={n}" for n in range(50)]

async def fetch(session, url):
    async with session.get(url, proxy=PROXY) as r:
        return (await r.json())["ip"]

async def main():
    # limit=10: ten requests in flight; force_close: a new connection, so a new IP, each time
    connector = aiohttp.TCPConnector(limit=10, force_close=True)
    timeout = aiohttp.ClientTimeout(total=30)
    async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
        ips = await asyncio.gather(*(fetch(session, url) for url in URLS))
    print(len(ips), "requests from", len(set(ips)), "different IPs")

asyncio.run(main())

Official docs: aiohttp: proxy support

05

Async proxies with HTTPX

If your project already uses httpx. Needs httpx 0.26 or later for proxy=.

async_httpx.py
import asyncio
import httpx

PROXY = "http://resi-lx_k3m9q2p7xa:[email protected]:7777"
URLS = [f"https://api.ludaxproxy.com/whoami?page={n}" for n in range(50)]

async def main():
    # max_connections=10: ten in flight; no keep-alive: a new connection, so a new IP, each time
    limits = httpx.Limits(max_connections=10, max_keepalive_connections=0)
    async with httpx.AsyncClient(proxy=PROXY, limits=limits, timeout=30) as client:
        responses = await asyncio.gather(*(client.get(url) for url in URLS))
    ips = [r.json()["ip"] for r in responses]
    print(len(ips), "requests from", len(set(ips)), "different IPs")

asyncio.run(main())

Official docs: HTTPX: proxies

06

SOCKS5 proxies in Python without DNS leaks: socks5h://

When your tool speaks SOCKS5. The h makes the gateway resolve the hostname, so no DNS query leaves from your machine. SOCKS5 is on Residential and Residential Premium.

socks5h.py
import requests  # pip install "requests[socks]"

# Residential Premium over SOCKS5 (Residential: gw.ludaxproxy.com:7575)
proxy = "socks5h://premi-lx_k3m9q2p7xa:[email protected]:1080"

r = requests.get("https://api.ludaxproxy.com/whoami",
                 proxies={"http": proxy, "https": proxy}, timeout=30)
print(r.json())

Official docs: requests: SOCKS

07

Retrying proxy errors without getting blocked

Production scrapers. Retry what a retry can fix (502, timeouts), never 407.

retry.py
import time
import requests

def get(url, proxy, tries=4):
    """GET through Ludax: retry a dropped exit, stop at once on 407 and certificate errors."""
    proxies = {"http": proxy, "https": proxy}
    for attempt in range(1, tries + 1):
        try:
            r = requests.get(url, proxies=proxies, timeout=30)
            if r.status_code != 502:
                return r  # a 407 comes back here too: a retry cannot fix credentials
            error = RuntimeError(f"502 Bad Gateway on attempt {attempt}")
        except requests.exceptions.SSLError:
            raise  # on the TLS gateways: pass verify="ludax-ca.crt"
        except requests.exceptions.ProxyError as e:
            if "407" in str(e):
                raise  # wrong username or password, or no data left on the plan
            error = e  # Tunnel connection failed: 502
        except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
            error = e  # the exit dropped mid-request
        if attempt < tries:
            time.sleep(2 ** (attempt - 1))  # 1, 2, 4 seconds; no wait after the last try
    raise RuntimeError(f"{url}: no answer after {tries} tries") from error

Use it in place of requests.get: r = get("https://example.com", proxy). A 407 or a certificate error stops at once with the real message; a 502 or a dropped connection is tried again after 1, 2 and 4 seconds.

[ 04 / GETTING BLOCKED? ]

Python requests blocked? Fix the TLS fingerprint, keep your code

If a site blocks your Python scraper even from a clean home IP, it is usually not the IP. It is the TLS handshake.

Before a site reads your URL or a single header, your client says hello: the TLS handshake. Chrome says hello one way; Python’s ssl module (so requests, aiohttp and httpx) says it in a way no browser does. Anti-bot systems read that hello as a fingerprint (JA3/JA4) and block on it, however good the IP is.

The usual fix is to switch libraries (curl_cffi, tls-client) and rewrite your code around them. With Residential TLS proxies you change the proxy URL instead: the gateway makes the connection to the site with a real browser’s handshake, HTTP/2 settings and matching headers.

WHAT CHANGES IN YOUR CODE

- proxy = "http://resi-lx_k3m9q2p7xa:[email protected]:7777"+ proxy = "http://resi-lx_k3m9q2p7xa-AE-chrome154:[email protected]:9999"- r = requests.get(url, proxies=proxies, timeout=30)+ r = requests.get(url, proxies=proxies, timeout=30, verify="ludax-ca.crt")
  1. The TLS gateway: gw.ludaxproxy.com:9999 (Residential Premium TLS: gw.ludaxproxy.com:8081).
  2. -AE-chrome154 at the end of the username: the browser to look like. AE also sets a matching User-Agent for you.
  3. ludax-ca.crt, downloaded once: the gateway re-signs HTTPS to send the browser handshake, so your client trusts its CA.
terminal.sh
curl -O https://ludaxproxy.com/downloads/ludax-ca.crt
tls_check.py
import requests

USER = "resi-lx_k3m9q2p7xa-AE-chrome154"  # + the browser to look like
PASS = "YOUR_PASSWORD-country-us"
proxy = f"http://{USER}:{PASS}@gw.ludaxproxy.com:9999"  # the Residential TLS port

r = requests.get(
    "https://api.ludaxproxy.com/whoami",
    proxies={"http": proxy, "https": proxy},
    verify="ludax-ca.crt",  # curl -O https://ludaxproxy.com/downloads/ludax-ca.crt
    timeout=30,
)
print(r.json()["tls_profile"])
output
Chrome 154

Official docs: requests: SSL verification · HTTPX: SSL · Python: ssl.create_default_context

The whoami endpoint reads your handshake the way an anti-bot system does. Plain requests prints None; through the TLS gateway it prints the browser you picked.

TWO WAYS TO LOOK LIKE A BROWSER
curl_cffi / tls-clientLudax Residential TLS
Your codeA different HTTP library and its own APIYour requests, aiohttp or httpx code, unchanged
Where the handshake is madeOn your machine, by a compiled extensionAt the gateway
User-Agent and client hintsYou keep them consistent yourselfAE sets them to match the profile
Browser profilesThe ones your library version ships139: Chrome, Edge, Firefox, Safari, Opera, OkHttp
Residential IPStill needs a proxyIncluded: the same request

Try it on the site that blocks you

1 GB of Residential TLS is enough to test a target properly, and the same username keeps working when you scale.

Get 1 GB — $1.49

Good to know: AE replaces your User-Agent; with NAE your headers pass through unchanged, so send a User-Agent from the same browser. Apps with certificate pinning refuse a re-signed certificate: use the standard gateways (gw.ludaxproxy.com:7777, gw.ludaxproxy.com:8080) for those. Request and response bodies are never stored. All 139 profiles: TLS profiles.

[ 05 / TROUBLESHOOTING ]

Python proxy errors: 407, 502, SSL and more

Every error a Python client gets from the gateway, what it means and the one thing to do. All codes: status codes.

SYMPTOM, CAUSE, FIX
You seeWhyFix
407 Proxy Authentication RequiredWrong username or password, a space or quote pasted into the password, or the plan's data is used up or expired.Copy the credentials again from Generate and check the plan in the dashboard. Do not loop retries: 30 failed logins in 5 minutes block your IP for 10 minutes.
502 Bad Gateway or Tunnel connection failed: 502The exit IP dropped mid-request or could not reach the site.Retry (recipe 07). With a sticky session, switch to a new token after two failures. Many at once: check the network status.
CERTIFICATE_VERIFY_FAILED on a TLS gatewayThe TLS gateways re-sign HTTPS with the Ludax CA.Download ludax-ca.crt once: requests verify="ludax-ca.crt", httpx and aiohttp an ssl.create_default_context(cafile="ludax-ca.crt").
The same IP every time, with no sessionYour client reuses one open connection (a requests.Session, an httpx client, aiohttp keep-alive).requests.get, aiohttp force_close=True, httpx max_keepalive_connections=0.
The IP changes in the middle of a flowNo -time- (a session then lasts 1 minute), the time ran out, or no -sameip on a TLS port.Add -time-30 (or what the flow needs) after the session token; on the TLS ports, -sameip after it.
Missing dependencies for SOCKS supportrequests needs its SOCKS extra.pip install "requests[socks]"
A different city than askedNo free exit in that city at that moment: the request falls back to the country.Check where you landed with whoami; the locations directory lists the regions and cities of every country.
Still blocked on the TLS portNAE mode with a User-Agent from another browser, or a page that needs JavaScript.Use AE (it sets a matching User-Agent); for JavaScript pages use a headless browser.
[ 06 / FAQ ]

Python proxy FAQ

Short answers. The full option list is in the credential syntax.

01Do I need an SDK, a library or an API key?

No. Ludax is an ordinary HTTP proxy. Put your username and password in a proxy URL and pass it to requests, aiohttp or httpx the way you would pass any proxy. There is nothing to install from us and no API key.

02How do I get a new IP for every request?

Send no -session- in the password. Every new connection then leaves from a new IP. Clients that keep connections open (a requests.Session, an httpx client, an aiohttp session) reuse the same connection and IP: use requests.get, aiohttp with force_close=True, or httpx with max_keepalive_connections=0.

03How do I keep the same IP for a login or checkout flow?

Add -session-<any token>-time-<minutes> to the password and send the same token on every request of the flow. Always add -time-: without it a session lasts 1 minute. Up to 1000 minutes on every plan, Premium included. On the TLS ports also add -sameip (-session-<token>-time-<minutes>-sameip), or only the browser profile is held.

04Do I still need curl_cffi, tls-client or a headless browser?

Not for the TLS fingerprint. Through the Residential TLS gateway (gw.ludaxproxy.com:9999) or the Premium TLS one (gw.ludaxproxy.com:8081) the site sees a real browser handshake while your code stays plain requests, aiohttp or httpx. A headless browser is only still needed when the site builds its content with JavaScript.

05Why socks5h and not socks5?

With socks5://, requests looks the hostname up on your own machine, so the DNS query leaves from your network. With socks5h:// the gateway resolves it at the exit instead. SOCKS5 is on Residential (gw.ludaxproxy.com:7575) and Residential Premium (gw.ludaxproxy.com:1080).

06Why do I get CERTIFICATE_VERIFY_FAILED on the TLS gateways?

The TLS gateways re-sign HTTPS with the Ludax CA so they can send the browser handshake. Download the certificate once (curl -O https://ludaxproxy.com/downloads/ludax-ca.crt). In requests pass verify="ludax-ca.crt"; in httpx and aiohttp pass ssl.create_default_context(cafile="ludax-ca.crt"), as verify= and ssl= respectively.

07Is there a free trial?

No: the smallest plan is the test. 1 GB of Residential costs $0.99 and 1 GB of Residential TLS $1.49, with no subscription, and your username stays the same when you buy more.

[ START NOW ]

Your first Python proxy request is two minutes away

  1. Pick a plan. The smallest one is the test: 1 GB, no subscription.
  2. Generate your credentials in the dashboard.
  3. Paste them into the code generator above and run.

Stuck? Send us the request you are making and the answer you get, and we debug it with you on Telegram. Every plan and price: pricing.