Tutorials 2 min read
How to Use Rotating Proxies with Python Requests
Step by step: connect Python requests to a rotating proxy gateway, add country targeting, sticky sessions, retries and concurrency without getting blocked.

This guide shows how to send Python requests traffic through a rotating proxy gateway, then adds the pieces you need in production: geo targeting, sticky sessions, retries and concurrency.
1. Install requests
pip install requests
2. Send your first request through the proxy
Copy the endpoint from your dashboard. It contains your username, password, the gateway host and the port of the pool you want.
import requests
PROXY = "http://USER-zone-premium:PASS@gate.example.com:8000"
proxies = {"http": PROXY, "https": PROXY}
r = requests.get("https://ipinfo.io/json", proxies=proxies, timeout=30)
print(r.json()["ip"], r.json()["country"])
Run it twice. You should see a different IP each time, because the gateway rotates on every request by default.
3. Target a country
Add the country code to the username:
PROXY = "http://USER-zone-premium-country-de:PASS@gate.example.com:8000"
Every request now exits from Germany. City targeting works the same way on residential pools, for example -country-us-city-newyork.
4. Keep the same IP with a sticky session
Some flows need the same IP for a while, such as logging in. Add a session ID and a time to live in minutes:
import uuid
session_id = uuid.uuid4().hex[:8]
PROXY = f"http://USER-zone-premium-country-us-session-{session_id}-ttl-10:PASS@gate.example.com:8000"
All requests that use this username keep the same exit IP for 10 minutes. Generate a new session_id when you want a new IP.
5. Retry on a fresh IP
Even good IPs fail sometimes. Retry blocked or failed requests; with rotation enabled every retry leaves from a different address.
import time
def fetch(url, tries=3):
for attempt in range(tries):
try:
r = requests.get(url, proxies=proxies, timeout=30)
if r.status_code in (403, 429) or r.status_code >= 500:
raise requests.HTTPError(r.status_code)
return r
except requests.RequestException:
time.sleep(1.5 * (attempt + 1))
return None
6. Scale with concurrency
The gateway accepts many connections at once, so you can parallelise with a thread pool:
from concurrent.futures import ThreadPoolExecutor
urls = [f"https://example.com/page/{i}" for i in range(1, 201)]
with ThreadPoolExecutor(max_workers=20) as pool:
for resp in pool.map(fetch, urls):
if resp is not None:
print(resp.url, resp.status_code)
Start with 10 to 20 workers and raise the number while watching your success rate in the dashboard.
Common errors
- 407 Proxy Authentication Required: wrong username or password, or your IP is not whitelisted.
- Timeouts: raise
timeout, or switch to a closer country. - Many 403 responses: move the target to a premium or mobile pool, and slow down your request rate.
Next steps
Not sure which pool fits your target? Read residential vs mobile vs datacenter proxies.