Direct Answer
To use a mobile proxy with tls-client, create a Session with a client_identifier and pass your endpoint to the proxy argument on each request as a http://user:pass@host:port string. That pairs a browser-consistent TLS handshake with a real German mobile IP, so the request looks like the ordinary browser it claims to be. Add your host, port, username and password from your account.
Why tls-client Exists, and the Proxy Gotcha
tls-client is bogdanfinn's Go HTTP client — with an official Python binding — built to reproduce the exact TLS handshake of a named browser. Most HTTP libraries speak TLS through their own stack, producing a cipher order, extension list and HTTP/2 setting that together form a recognisable fingerprint. tls-client lets you pick a client_identifier such as chrome_120, so the connection presents itself as that browser rather than a scripting library.
The gotcha is where the proxy goes. In the Python binding you do not set session.proxies the way you would with requests. Instead you pass a proxy argument on each request. Miss that and your traffic quietly leaves through your own IP.
And a browser handshake is only half of a coherent request. The TLS layer says "I am this kind of client"; the network layer says "I come from this kind of IP." When those agree — a browser-shaped handshake from an everyday mobile connection — the request is simply consistent. When they contradict — a browser handshake from a datacenter range — the mismatch is what stands out. For how that transport fingerprint is read, see TLS fingerprinting with JA3 and JA4. The goal is consistency, not concealment: look like the ordinary browser you are, from an IP that fits.
Install
The Python binding installs as one package:
pip install tls-client
Before You Start
You will need four values from your GermanProxy.io account:
- Host and port of your endpoint
- Username and password
The examples use PROXY_HOST, PORT, USER and PASS as placeholders — replace them with your own. GermanProxy.io supports HTTP, SOCKS5 and OpenVPN, so you can pick whichever your tool prefers.
Step 1 — A Session with a Browser Handshake
Create a Session, choose the client_identifier, then pass the endpoint to the proxy argument on the request:
import tls_client
session = tls_client.Session(
client_identifier="chrome_120",
random_tls_extension_order=True,
)
resp = session.get(
"https://www.example.de",
proxy="http://USER:PASS@PROXY_HOST:PORT",
)
print(resp.status_code)
print(resp.text[:200])
random_tls_extension_order=True keeps the handshake from being identical on every call. One rule keeps the request coherent: if you present a Chrome handshake, send a matching Chrome User-Agent at the HTTP layer — a handshake that says Chrome paired with a scripting-library header reintroduces the contradiction you removed.
Step 2 — HTTP and SOCKS5 Forms
The only thing that changes between schemes is the proxy URL:
# HTTP
resp = session.get("https://www.example.de",
proxy="http://USER:PASS@PROXY_HOST:PORT")
# SOCKS5
resp = session.get("https://www.example.de",
proxy="socks5://USER:PASS@PROXY_HOST:PORT")
Use HTTP for most web traffic; choose SOCKS5 when you want DNS and connection handling to happen at the proxy. For the trade-offs, see the difference between HTTP and SOCKS5.
Verify the IP First
Before scaling up, request an IP-echo endpoint through the same proxy and confirm the German mobile IP your target actually sees:
import tls_client
session = tls_client.Session(client_identifier="chrome_120")
resp = session.get("https://api.ipify.org?format=json",
proxy="http://USER:PASS@PROXY_HOST:PORT")
print(resp.text)
If it returns your own address, re-check the proxy string. See validating the proxy connection to compare, and if you hit 407, fix 407 proxy authentication required.
Sticky Sessions vs. Rotation
With one dedicated endpoint you control the IP at the proxy, not with a pool:
- Sticky session: reuse one
Sessionwith the same proxy string to keep the same German mobile IP across a multi-request flow. - Rotation on demand: request a fresh IP at the proxy when you want to spread load.
See sticky sessions and IP rotation explained.
Why a Real German Mobile IP
client_identifier settles the transport fingerprint; the IP settles where the request originates. A real German 5G mobile IP is a normal consumer address on a real German mobile network, shared across many everyday users through CGNAT, so its reputation reflects ordinary phone traffic rather than a flagged server range. Paired with a browser-consistent handshake, both stories agree — the whole-request view that how websites detect proxies describes, and why a clean IP reputation matters as much as the handshake. For the wider spectrum, see mobile vs residential vs datacenter proxies.
Scrape Responsibly
A browser-consistent client on a clean mobile IP improves reliability for legitimate data collection — it is not a way around access controls or a site's rules. Keep the pipeline defensible:
- Respect
robots.txtand each site's terms of service. - Send requests at a human-reasonable rate — add delays; do not hammer servers.
- Collect only public data you need, and handle any personal data in line with the GDPR.
- Keep your
User-Agenthonest and aligned with theclient_identifieryou present.
For German and EU targets this is our positioning: public data only, polite rates, no storing of personal data. See the legal status of web scraping in the EU.
FAQ
How do I set a proxy in the tls-client Python binding?
Per request, not on the session object. Unlike requests, where you set session.proxies, tls-client takes a proxy argument on each call — session.get(url, proxy="http://USER:PASS@PROXY_HOST:PORT"). The same string routes that request through your German mobile endpoint.
What does client_identifier do?
It selects which browser's TLS fingerprint the client reproduces, such as client_identifier="chrome_120". tls-client then presents that browser's handshake and HTTP/2 settings, aligning your JA3/JA4 with a real browser instead of a generic HTTP library — at the transport layer only.
Does tls-client support SOCKS5 proxies?
Yes. tls-client accepts both http://USER:PASS@PROXY_HOST:PORT and socks5://USER:PASS@PROXY_HOST:PORT proxy strings. Use HTTP for most web work; choose SOCKS5 when you want DNS and connection handling to happen at the proxy.
Do I still need a proxy if tls-client already matches a browser handshake?
Yes. client_identifier only settles the TLS and HTTP/2 layer; your IP is a separate signal. A browser-consistent handshake from a flagged datacenter range is still inconsistent overall. A real German mobile IP gives the network layer the everyday-consumer profile the handshake already claims.
How do I keep or refresh the same German IP with tls-client?
Reuse one Session and pass the same proxy string to keep a sticky session on one German mobile IP. To refresh, tls-client reconnects when you call the request again with that proxy — and you rotate on demand at the proxy when you want a fresh IP, without a pool of endpoints.
Is this the Go library or a Python one?
tls-client is written in Go by bogdanfinn, with an official Python binding (tls_client) exposing the same fingerprints. This guide shows the Python binding, where you set the proxy per request; the Go client uses the equivalent WithProxyUrl option or SetProxy method.
Related guides
- curl_cffi Proxy Setup: German Mobile IP + Browser TLS
- hrequests Proxy Setup: German Mobile IP + Browser TLS
- cURL Proxy Setup: HTTP & SOCKS5 with a German Mobile IP
CTA
Give your browser-consistent handshake an IP that fits. Get a German mobile proxy — HTTP/SOCKS5/OpenVPN, sticky sessions, on-demand rotation, fair-use 20 GB/day, from a transparent EU provider. Browse the plans to get started.
Get a German mobile proxy: Real 4G/5G IPs from Germany, fair-use 20 GB/day — see German 4G/5G mobile proxy options or start small with a shared 5G proxy.