Connecting to a Proxy
Once you have an active sub-user you have everything you need to make live proxy requests. ProxyHat's residential and mobile pool is exposed through a single rotating gateway host. You point your HTTP or SOCKS5 client at that host, authenticate with the sub-user's proxy credentials, and encode every targeting option (country, city, sticky session, AI quality filter) directly into the proxy username. This page is the complete grammar for that username plus copy-paste connection examples.
POST /v1/proxy-descriptors) takes a sub-user UUID plus structured location, session and filter options and returns the fully assembled username, password, host, port and ready-to-use url. Use it when you want the server to be the source of truth for the grammar described below.
The Gateway
All residential and mobile traffic goes through one host, on one of two ports depending on the protocol you speak:
| Host | Port | Protocol | Notes |
|---|---|---|---|
| gate.proxyhat.com | 1080 | SOCKS5 | Recommended. Full SOCKS5 support; use socks5h:// in curl so DNS is resolved through the proxy. |
| gate.proxyhat.com | 8080 | HTTP / HTTPS | Browser-compatible HTTP proxy. Use when your client or tooling only speaks HTTP proxies. |
gate.proxyhat.com or any username token grammar. See ISP Proxies for that model. Everything on this page is about the rotating residential / mobile gateway.
Authentication
The gateway authenticates with a standard proxy username:password pair drawn from the sub-user:
- Password — the sub-user's
proxy_password, used verbatim. - Username — the sub-user's
proxy_usernameas the base, with dash-delimited targeting tokens appended to it (the rest of this page).
Both values come from the sub-user object — see Sub-Users for how to create one and read back its proxy_username and proxy_password. A sub-user must be in the active lifecycle state to authenticate.
Username Grammar
The username is the base proxy_username followed by targeting tokens, always appended in this fixed order. Only -country- is always present; every other token is optional and simply omitted when unused.
| Token | Required | Description |
|---|---|---|
| <base> | Always | The sub-user's proxy_username. Every other token is suffixed onto this. |
| -country-<iso> | Always | Target country as a lowercased ISO code (e.g. us, de). Always emitted; when you don't want to pin a country, use the literal -country-any. |
| -region-<slug> | Optional | State / region, appended only when set. Slugified to [a-z0-9_] (e.g. -region-california). |
| -city-<slug> | Optional | City, appended only when set. Slugified, so spaces become underscores (e.g. -city-new_york). |
| -isp-<slug> | Optional | Target a specific ISP. Appended only when set. |
| -type-mobile | Optional | Request a mobile / cellular exit instead of residential. Fixed literal — present or absent. |
| -ipv4-true | Optional | Restrict the exit pool to IPv4 addresses only. Fixed literal — present or absent. |
| -sid-<hex>-ttl-<dur> | Optional | Sticky session: pins one upstream IP for the session. -sid- is a 16-character hex id, immediately followed by -ttl- with a lifetime of 30m or 12h. Omit the whole pair for a rotating session — you then get a fresh IP on every request. |
| -<filter> | Optional | AI quality filter, appended last. The value already contains its own filter- prefix, so it reads e.g. -filter-medium. Omit entirely to disable filtering. Defaults to filter-medium when unspecified. |
-zip- token. The upstream gateway rejects -zip- (and the -zipcode- / -postal- aliases) with a 407, so it is deliberately never emitted. Scope by country / region / city / ISP instead.
AI Quality Filter
The final token selects a quality/speed tradeoff for the exit IP. It is appended verbatim (it carries its own filter- prefix), or omitted entirely for no filtering. Valid values:
| Value | Label | Tradeoff |
|---|---|---|
| filter-medium | Medium Quality | Default and recommended. Balanced performance at normal speed. |
| filter-high | High Quality | Best success rate, slower speed. |
| filter-high-speed-fast | High Speed | Fast response with good quality. |
| filter-medium-speed-fast | Medium Speed | Maximum speed; slightly lower quality than filter-medium. (No dashboard tile, but still a valid value.) |
| none | No Filter | All available proxies, quality varies. Appends no token to the username. |
A Full Example
Consider a sub-user whose proxy_username is ph-8f2a1c and whose proxy_password is PxSecret123. To request a sticky United States / New York IP that lives for 30 minutes with the high-speed AI filter, the assembled username is:
ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast
Breaking that down token by token:
ph-8f2a1c ← base (proxy_username)
-country-us ← United States
-city-new_york ← New York (slugified)
-sid-a1b2c3d4e5f60718-ttl-30m ← sticky, pinned for 30 minutes
-filter-high-speed-fast ← AI filter (last)
For a rotating mobile exit in Germany over IPv4 (new IP each request), drop the -sid-/-ttl- pair entirely:
ph-8f2a1c-country-de-type-mobile-ipv4-true-filter-medium
Connection URLs
The full proxy URL is protocol://<username>:<password>@gate.proxyhat.com:<port>. Using the sticky example above:
# SOCKS5 (recommended) — port 1080
socks5h://ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast:PxSecret123@gate.proxyhat.com:1080
# HTTP / HTTPS — port 8080
http://ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast:PxSecret123@gate.proxyhat.com:8080
Some antidetect browsers and tools expect a host:port:user:pass export form instead of a URL:
gate.proxyhat.com:1080:ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast:PxSecret123
Making a Request
The quickest way to confirm a connection works is to fetch your exit IP through the proxy. The response IP should be an address in the country you targeted, and (for a rotating session) should change between calls.
# SOCKS5 (recommended) — resolve DNS through the proxy with socks5h://
curl -x "socks5h://ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast:PxSecret123@gate.proxyhat.com:1080" \
https://api.ipify.org?format=json
# HTTP / HTTPS — port 8080
curl -x "http://ph-8f2a1c-country-de-type-mobile-ipv4-true-filter-medium:PxSecret123@gate.proxyhat.com:8080" \
https://api.ipify.org?format=json
import requests
username = "ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast"
password = "PxSecret123"
# SOCKS5 (recommended). Requires: pip install "requests[socks]"
proxy = f"socks5h://{username}:{password}@gate.proxyhat.com:1080"
response = requests.get(
"https://api.ipify.org?format=json",
proxies={"http": proxy, "https": proxy},
)
print(response.json()) # {"ip": "<a US residential IP>"}
// npm install socks-proxy-agent
import { SocksProxyAgent } from "socks-proxy-agent";
const username = "ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast";
const password = "PxSecret123";
const agent = new SocksProxyAgent(
`socks5h://${username}:${password}@gate.proxyhat.com:1080`
);
const response = await fetch("https://api.ipify.org?format=json", { agent });
console.log(await response.json());
package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
username := "ph-8f2a1c-country-us-city-new_york-sid-a1b2c3d4e5f60718-ttl-30m-filter-high-speed-fast"
password := "PxSecret123"
// HTTP proxy on port 8080. For SOCKS5, use golang.org/x/net/proxy.
proxyURL, _ := url.Parse(fmt.Sprintf("http://%s:%s@gate.proxyhat.com:8080", username, password))
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
}
resp, err := client.Get("https://api.ipify.org?format=json")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
-sid-<hex>-ttl-<30m|12h> to keep the same IP for the session; leave it out to rotate to a new IP on every request. The session id must be 16 hex characters — let Proxy Descriptors generate a valid one for you if you don't want to manage it yourself.