How to Set Up Residential Proxies: Endpoint, Session, and Code

On this page
To set up a residential proxy, you need four values (host, port, username, and password) and two decisions: which protocol endpoint your client should use, and whether requests should rotate or stay on one IP. With PacketStream, the host is proxy.packetstream.io, the recommended port is 31111 for the HTTPS proxy, the username is your PacketStream username, and the password is your auth key. Add _country-US or _session-label to the auth key to target a country or keep one IP, then confirm the exit with a single test request before you point real work at it.
The checklist below covers the whole setup. The sections after it give working examples for cURL, Python, Node.js, and Playwright.
Setup checklist
| Step | What to do | PacketStream value |
|---|---|---|
| 1. Create an account and add balance | Sign up and make a first purchase. | $1/GB, $50 minimum purchase, no subscription; the balance does not expire. |
| 2. Copy your credentials | Open the Proxy Access page in the dashboard. | Username, plus your auth key as the password. |
| 3. Store them outside your code | Use environment variables or a secret store. | PACKETSTREAM_USER, PACKETSTREAM_AUTH_KEY |
| 4. Choose an endpoint | Match the protocol your client supports. | HTTPS 31111 (recommended), SOCKS5 31113, HTTP 31112 |
| 5. Choose session behavior | Rotate for independent requests; stick for related ones. | Plain auth key, or AUTH_KEY_session-label |
| 6. Choose a country, if needed | Add an ISO two-letter code. | AUTH_KEY_country-US |
| 7. Verify the exit | Send one request to an IP lookup service. | Check the returned IP and country. |
| 8. Configure your client | Pass the proxy explicitly, with timeouts. | Examples below. |
Choose an endpoint
All three endpoints use the same host and credentials. Only the port and scheme change.
| Protocol | Proxy URL | Use it when |
|---|---|---|
| HTTPS proxy | https://proxy.packetstream.io:31111 | Your client supports an HTTPS proxy. This is the default choice, because the connection to the gateway, including your credentials, is encrypted. |
| SOCKS5 | socks5h://proxy.packetstream.io:31113 | Your client specifically needs SOCKS5. |
| HTTP proxy | http://proxy.packetstream.io:31112 | Your client cannot use the other two. Requests to HTTPS sites stay encrypted, but your proxy credentials reach the gateway unencrypted. |
Supporting HTTPS websites is not the same as supporting an HTTPS proxy. If a client fails to connect on 31111, check that it can speak TLS to the proxy itself. Do not turn off certificate verification to make an error go away. The HTTPS vs. SOCKS5 guide compares the two in more depth.
Choose rotation or a sticky session
Session behavior and country targeting are both set by adding suffixes to the auth key. The host and port stay the same.
| Workload | Password value | Behavior |
|---|---|---|
| Independent public-page checks | AUTH_KEY | New exit selected for each new connection |
| Several steps that must share one exit | AUTH_KEY_session-order42 | Same exit while the label stays active |
| Location-sensitive independent checks | AUTH_KEY_country-US | Rotation within the requested country |
| Location-sensitive multi-step workflow | AUTH_KEY_country-US_session-order42 | One exit in the requested country |
Three rules decide how this behaves in practice:
- Rotation is per connection, not per request. HTTP clients and browsers reuse open connections, and every request on one connection uses the same exit. A new connection triggers a new selection, but the IP is not guaranteed to differ. See how connection pooling affects rotation.
- A sticky session lasts while it is used. The label keeps its IP as long as it opens at least one successful new connection every 60 minutes. After 60 minutes without one, it expires and the next connection gets a new exit.
- A sticky session never moves. If the Packeter providing the IP goes offline, new connections on the label fail with
502 Proxy Error (sticky session IP is offline)(a general failure reply on SOCKS5) until that IP returns or the label expires. If the workflow cannot wait, use a new label and restart from a checkpoint.
A requested country is never swapped for another: if no exit is available there, the request fails. Use labels that contain no personal data, such as catalog42, not an email address.
Verify the proxy with cURL
Set your credentials once per shell:
export PACKETSTREAM_USER='your_username'
export PACKETSTREAM_AUTH_KEY='your_auth_key'Send one request through the HTTPS proxy. The response shows the exit's IP address, country, and network, which should differ from your own:
curl --silent --show-error --fail-with-body \
--connect-timeout 15 --max-time 45 \
--proxy 'https://proxy.packetstream.io:31111' \
--proxy-user "${PACKETSTREAM_USER}:${PACKETSTREAM_AUTH_KEY}" \
'https://ipinfo.io'Check a country and a sticky session the same way. Run the second command twice; both runs should report the same IP:
# United States exit, rotating
curl --silent --show-error --fail-with-body \
--proxy 'https://proxy.packetstream.io:31111' \
--proxy-user "${PACKETSTREAM_USER}:${PACKETSTREAM_AUTH_KEY}_country-US" \
'https://ipinfo.io'
# Sticky session: same exit on each new connection
curl --silent --show-error --fail-with-body \
--proxy 'https://proxy.packetstream.io:31111' \
--proxy-user "${PACKETSTREAM_USER}:${PACKETSTREAM_AUTH_KEY}_session-setup1" \
'https://ipinfo.io'For SOCKS5, change the proxy to socks5h://proxy.packetstream.io:31113. To test more than one request at a time, the open-source ProxySampler tool reads the same environment variables, opens a new connection for each request, and reports errors without printing the auth key.
Python with Requests
Build the password from the auth key and any suffixes, URL-encode both credentials, and pass the proxy on every request so environment settings cannot override it:
import os
from urllib.parse import quote
import requests
def packetstream_proxy(country=None, session=None):
password = os.environ["PACKETSTREAM_AUTH_KEY"]
if country:
password += f"_country-{country}"
if session:
password += f"_session-{session}"
user = quote(os.environ["PACKETSTREAM_USER"], safe="")
url = f"https://{user}:{quote(password, safe='')}@proxy.packetstream.io:31111"
return {"http": url, "https": url}
response = requests.get(
"https://ipinfo.io",
proxies=packetstream_proxy(country="US"),
timeout=30,
)
response.raise_for_status()
print(response.json())Install Requests with python -m pip install requests. Do not print or log the proxy URL; it contains your auth key.
Node.js with Undici
Undici's ProxyAgent supports HTTPS proxy URIs. Install it with npm install undici, then:
import { ProxyAgent, fetch } from "undici";
const username = process.env.PACKETSTREAM_USER;
const authKey = process.env.PACKETSTREAM_AUTH_KEY;
if (!username || !authKey) {
throw new Error("Set PACKETSTREAM_USER and PACKETSTREAM_AUTH_KEY");
}
// Add "_country-US" or "_session-label" here to target or stick.
const password = authKey;
const token = Buffer.from(`${username}:${password}`).toString("base64");
const dispatcher = new ProxyAgent({
uri: "https://proxy.packetstream.io:31111",
token: `Basic ${token}`,
});
try {
const response = await fetch("https://ipinfo.io", {
dispatcher,
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());
} finally {
await dispatcher.close();
}Playwright
Playwright takes the proxy server and credentials separately. This example keeps one exit for the whole browser run with a sticky session label:
import { chromium } from "playwright";
const browser = await chromium.launch({
proxy: {
server: "https://proxy.packetstream.io:31111",
username: process.env.PACKETSTREAM_USER,
password: `${process.env.PACKETSTREAM_AUTH_KEY}_session-browser1`,
},
});
try {
const page = await browser.newPage();
await page.goto("https://ipinfo.io/json", {
waitUntil: "domcontentloaded",
timeout: 30_000,
});
console.log(JSON.parse(await page.locator("body").innerText()));
} finally {
await browser.close();
}Browsers reuse connections, so with the plain auth key a new page or navigation does not guarantee a new exit. The Playwright guide covers targeting, sessions, and recovery in more detail. Go, Rust, PHP, Ruby, Java, C#, Puppeteer, Selenium, Scrapy, and Crawlee examples are in the PacketStream examples repository.
Browser and operating-system proxy settings
For manual browsing, a browser or operating-system proxy dialog needs the same host and port and prompts for the username and auth key when you first connect. Many of these dialogs only accept a plain HTTP proxy. In that case, use proxy.packetstream.io on port 31112, keeping in mind that the credentials travel to the gateway unencrypted. A system-wide setting sends every application's traffic through the proxy and bills it per GB, so prefer configuring only the application that needs it.
If the test request fails
| Symptom | Likely cause | What to do |
|---|---|---|
| Authentication fails | Wrong username or auth key, stray whitespace, or a typo in a suffix | Copy the credentials again and stop the job; do not retry. |
502 Proxy Error (no funds available) | The balance is empty (on SOCKS5 this looks like a wrong password) | Add balance, then retry. |
| Connection fails before authentication | Port and scheme do not match, or an outbound firewall or VPN blocks the port | Check the endpoint table and outbound rules. |
| TLS or certificate error | The client does not support an HTTPS proxy, or the trust store is outdated | Test with current cURL; use SOCKS5 if the client cannot do TLS to a proxy. |
| Country-targeted request fails | No exit is available in that country | Retry with bounded backoff; keep the country constraint. |
| Same IP on every request | The client is reusing one connection | Expected; see connection pooling above. |
502 Proxy Error (sticky session IP is offline) | The session's Packeter went offline | Wait and retry with a limit, or start a new label from a checkpoint. |
The troubleshooting docs cover each case and what to send support. When the test request works, set connect and total timeouts in your client, retry only transient failures with backoff, and you are ready to run real jobs. Not set up yet? Create an account; residential bandwidth is $1/GB with no subscription.