Python
requests, httpx, aiohttp, async concurrency
Docs · gateway, username format, sessions, errors, limits
Everything you need to send the first request, then the reference you will come back to: targeting parameters, session rules, error codes and limits.
Quick answer
How do I connect to CrawlRelay proxies?
Point any HTTP client at http://USERNAME:[email protected]:7777, or SOCKS5 at port 7778. CrawlRelay, a developer-first residential proxy service, reads targeting and sessions from the username: USERNAME-country-us-city-new_york-session-job1-ttl-30. Residential traffic costs $1.50 for 1 GB and $0.50/GB from 50 GB. Paid in crypto, with no KYC.
| Gateway host | gw.crawlrelay.com |
|---|---|
| HTTP / HTTPS port | 7777 (HTTPS sites through CONNECT) |
| SOCKS5 port | 7778 (use socks5h:// so DNS resolves at the exit) |
| Authentication | Username and password of your plan or of a sub-user, or an IP allowlist (up to 10 IPs) |
| Username format | USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes} |
| Session length | up to 30 minutes; the IP can change earlier |
| Test URL | https://api.ipify.org returns the exit IP as plain text |
| Management API | https://crawlrelay.com/api/v1, API keys you can revoke at any time (API docs) |
Copy the username and password from your dashboard, then run one of these. Each prints the IP address the website sees, which usually changes from one run to the next.
curl -x http://USERNAME-country-us:[email protected]:7777 https://api.ipify.orgimport requests
proxy = "http://USERNAME-country-us:[email protected]:7777"
r = requests.get("https://api.ipify.org", proxies={"http": proxy, "https": proxy}, timeout=(10, 30))
print(r.text)import { ProxyAgent, fetch } from "undici";
const dispatcher = new ProxyAgent("http://USERNAME-country-us:[email protected]:7777");
const res = await fetch("https://api.ipify.org", { dispatcher });
console.log(await res.text());Start from the username in your dashboard and append parameters with hyphens, in the order of the format above. Every parameter is optional. Values are lowercase, and city names use underscores (new_york, sao_paulo). City availability varies.
| Goal | Username |
|---|---|
| Any country, rotating per connection | USERNAME |
| Germany | USERNAME-country-de |
| Paris | USERNAME-country-fr-city-paris |
| Texas | USERNAME-country-us-state-tx |
| One ZIP code | USERNAME-country-us-zip-10001 |
| One internet provider | USERNAME-country-us-asn-7922 |
| Same IP for up to 30 minutes | USERNAME-country-gb-session-abc123-ttl-30 |
If your password contains @, : or /, URL-encode it before you put it in a proxy URL. The 407 error page shows how.
A username without session- gets an IP from the pool on each new TCP connection, usually a different one. A username with session-<id>-ttl-<minutes> keeps the same exit IP for that ID until the TTL ends or the residential device goes offline.
The sessions guide covers connection reuse in each library.
First find out who answered: the gateway, or the website behind it.
| You see | Sent by | Usual cause | What to do |
|---|---|---|---|
| 407 | Gateway | Wrong or unencoded credentials | Fix the username or password; never retry blindly |
| ERR_TUNNEL_CONNECTION_FAILED | Browser | CONNECT refused (often a hidden 407) | Pass credentials as fields, not in the server URL |
| 502 / 504 | Gateway or CDN | Exit dropped, target slow or down | Retry on a new connection, with a cap |
| 403 | Website | Wrong country, headers, rate, or a refusal | Check in a browser; slow down or respect the refusal |
| 429 | Website | Rate limit | Honour Retry-After; lower per-host concurrency |
| SSL: WRONG_VERSION_NUMBER | Your client | https:// in front of the proxy URL | Use http:// for the proxy URL |
All 15 entries are in the error reference.
In the dashboard, or through the REST API at https://crawlrelay.com/api/v1 with an API key. API keys you can revoke at any time. The main tasks:
requests, httpx, aiohttp, async concurrency
Middleware, sessions per request, AutoThrottle
Python and Node.js, proxy per context
Flag plus page.authenticate()
Authenticated proxy through a local forwarder
undici, axios, got, SOCKS5
HTTP, SOCKS5, debugging with -v
Connection reuse, TTL, one IP per flow
Per-host limits, throughput and backoff
CrawlRelay publishes copy-paste guides for Python (requests, httpx, aiohttp), Scrapy, Playwright, Puppeteer, Selenium, Node.js and curl, a reference of 15 proxy errors and a REST API reference with curl, Python and Node.js samples. Every example uses the real gateway host and ports, and each snippet is checked for syntax before publication.
No. Username and password authentication works from any machine, so you can run the same scraper on a laptop, a server or a CI runner. If you prefer, add up to 10 IPs to an allowlist instead. Keep credentials in environment variables or a secrets manager, never in your repository.
Either your username contains a session ID, which keeps one IP on purpose, or your client reuses one kept-alive connection. Rotation happens per new connection. Remove the session part, or open a new connection per request, as shown in the sessions guide.
Use the HTTP port (7777) for web scraping: every library and browser supports it with authentication, and HTTPS sites work through CONNECT tunnels. Use SOCKS5 (7778) for tools that only speak SOCKS, with socks5h:// so DNS resolves at the exit.
Request https://api.ipify.org through the proxy to get the IP, then look it up in a geolocation database you trust. Databases disagree on some IPs, especially mobile ones, so check the content the target serves too: currency, language and local results are what matter for your data.
Plans are billed per GB, not per request, and the limits you will meet first are the targets' own. Pace each target separately and back off on 429 and 503 responses. If you plan a very large crawl, tell support at [email protected] first.
From $0.50/GB · no KYC
Get started