# Proxies.sx Pool Gateway - Rotation Cookbook (for LLMs & humans) Paste this whole file to your AI assistant. It is the copy-paste-correct way to do IP rotation on the Pool Gateway. You do NOT need to write custom rotation code - rotation is chosen in the proxy **username**. Getting the username right is the whole job. Canonical: if this disagrees with the live API, the live API wins. Gateway host: `gw.proxies.sx` - HTTP on port `7000`, SOCKS5 on `7001`. --- ## The username format (this is everything) ``` psx_--[- ...] ``` - The username is lowercased and split on `-`. **No value may itself contain a `-`.** - `accountId` - your proxy username, looks like `psx_ab12cd`. Get it in your dashboard. - password - your proxy password, OR a `pak_...` pool access key. - `pool` - `mbl` (real 4G/5G modems, 6 countries: us, gb, fr, nl, pl, ge), `peer` (residential/mobile peers, ~82 countries), `any`, or `best`. - `country` - 2-letter ISO (`us`, `gb`, `de`...) or `any`. Everything after country is optional `- ` pairs. The one that controls rotation is `-rot`. The one that makes a session STICK is `-sid`. ## Rotation modes (`-rot-`) | Mode | What it does | |---|---| | `auto10` (default) | soft-rotate: re-pick a different modem every 10 min. Also `auto5`, `auto20`, `auto60`. | | `ondemand` | re-pick only when a NEW connection opens | | `sticky` | pin the same modem for the whole session (needs a `-sid-`, see below) | | `hard` | same as `sticky` at routing time - it does NOT mean "new IP per request" | There is no mode that gives a guaranteed new IP on every single request. If you need that, open a new connection with `-rot-ondemand`, or rotate on your own schedule. ## THE #1 RULE: sticky/auto need a `-sid-` A `-sid-` is your session name. Without it, every connection gets a fresh throwaway session, so `sticky` won't actually stick across connections and `auto*` won't keep the same modem between the intervals. - `sid` value: 1-64 chars, `[a-z0-9_]` only (it's sanitized for you). - Same `sid` = same session = same modem (subject to the IP caveat below). - DIFFERENT `sid` values = different modems = your parallel fan-out. --- ## Recipe 1 - one rotating IP (simplest) Rotate to a fresh US modem every 10 minutes, no state to manage: ```bash curl -x "http://psx_ab12cd-mbl-us-rot-auto10:YOUR_PASS@gw.proxies.sx:7000" https://api.ipify.org ``` ## Recipe 2 - hold ONE IP across many requests (sticky) Same modem for the whole job (cookies, login, cart). The `-sid-` is what makes it persist: ```bash curl -x "http://psx_ab12cd-mbl-us-rot-sticky-sid-job42:YOUR_PASS@gw.proxies.sx:7000" https://api.ipify.org ``` Reuse the exact same username (same `-sid-job42`) on every request in that job. ## Recipe 3 - hundreds of parallel sticky sessions (fan-out) One credential, N workers, each pinned to its OWN modem - just give each worker a distinct `sid`: ```python import requests def proxy_for(worker_id: int, country="us"): user = f"psx_ab12cd-mbl-{country}-rot-sticky-sid-w{worker_id}" return {"http": f"http://{user}:YOUR_PASS@gw.proxies.sx:7000", "https": f"http://{user}:YOUR_PASS@gw.proxies.sx:7000"} # worker 0..99 each land on a different modem, each stable for its session for wid in range(100): r = requests.get("https://api.ipify.org", proxies=proxy_for(wid), timeout=30) print(wid, r.text) ``` Limits: **500 concurrent connections and 250 concurrent sessions per account.** ## Recipe 4 - new IP whenever a connection opens ```javascript // node - HttpsProxyAgent; a fresh agent/connection re-picks a modem import { HttpsProxyAgent } from 'https-proxy-agent'; const user = 'psx_ab12cd-mbl-us-rot-ondemand'; const agent = new HttpsProxyAgent(`http://${user}:YOUR_PASS@gw.proxies.sx:7000`); const res = await fetch('https://api.ipify.org', { agent }); console.log(await res.text()); ``` ## Multi-country from ONE credential Just change the country slot - no repurchase, same key: ``` psx_ab12cd-mbl-us-rot-auto10 -> US psx_ab12cd-mbl-gb-rot-auto10 -> GB psx_ab12cd-peer-jp-rot-sticky-sid-a -> Japan (peer pool, wider country coverage) ``` --- ## FOOTGUNS (read before your LLM invents its own rotation) 1. **Sticky pins the MODEM, not the IP.** Mobile carriers (T-Mobile especially) re-NAT the egress IP on their own cadence, so a perfectly-pinned modem can still show different exit IPs across short calls. If you need the *same exit IP* held for a whole workflow (cf_clearance, banking 2FA), use the **residential peer** pool (home-ISP IPs are stable for hours) or a dedicated modem port. 2. **`-session-` is NOT the sticky token.** The token is `sid`. `-session-` is silently ignored and you get NO stickiness. Always use `-sid-`. 3. **`sticky`/`auto*` do nothing across connections without a `-sid-`.** No sid = throwaway session per connection. 4. **No token value may contain a `-`** (it's the delimiter). Keep `sid` in `[a-z0-9_]`. 5. **`hard` != per-request rotation.** `hard` pins like `sticky`. Nothing gives a guaranteed new IP per request on the pool; open a new `-rot-ondemand` connection instead. 6. **Country stock differs by pool.** `mbl` = us/gb/fr/nl/pl/ge only; `peer` = ~82 countries. Use `-any-` or `-best-` for the pool if you don't care which. 7. **Verify before you trust.** Route any exit through `https://ipinfo.io/org` or MaxMind/IP2Location - our IPs are real mobile/residential, and you should be able to confirm that yourself. ## SDK (skips all the string-building) ``` npm install @proxies-sx/pool-sdk ``` ```javascript import { buildProxyUrl } from '@proxies-sx/pool-sdk'; // validates your sid client-side and builds the URL correctly const url = buildProxyUrl('psx_ab12cd', 'YOUR_PASS', { pool: 'mbl', country: 'us', rotation: 'sticky', sid: 'job42', }); ``` Errors come back as machine-parseable codes in the proxy response (`E_AUTH_INVALID`, `E_NO_STOCK_COUNTRY`, `E_SESSION_LIMIT`, `E_CAP_EXCEEDED`...), so your agent can branch on them instead of guessing.