Direct Answer
To route Pydantic AI through a mobile proxy, give the tool that fetches the web its own httpx.AsyncClient(proxy="http://USER:PASS@PROXY_HOST:PORT"). Pydantic AI agents work by calling tools, and a web tool makes an ordinary HTTP request — that request is what should leave through your German mobile IP. The proxy binds to the tool call, not the model. The LLM keeps its own connection unless you deliberately route the provider's http_client through the proxy too. You don't change how the agent reasons; you only change where the tool's web requests come from.
The One Thing Most Pydantic AI Proxy Guides Get Wrong
Pydantic AI is a typed agent framework: you define an agent, give it tools, and the model decides which tool to call and with what arguments. The common mistake is thinking of "the proxy" as something the whole agent or the LLM sits behind. It isn't.
The proxy binds to the tool, not the model. When the agent calls a tool that reads a German page, that HTTP request is what should exit through your German mobile IP. The reasoning steps — the calls to your LLM provider — are a separate connection and usually don't need a German exit at all. Get this distinction right and the setup is a few lines; get it wrong and you route model traffic through a mobile connection for no reason while your fetch still exits from your own address.
So the goal is precise: send the agent's tool web requests through the German mobile proxy, and leave everything else alone. Pydantic AI makes this clean because both its tools and its model providers speak httpx, and httpx takes a proxy argument directly.
Before You Start
You'll 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. There's no hardware to manage: the proxy is a dedicated mobile connection exposed as a host/port/credentials endpoint.
Install Pydantic AI (it ships with httpx):
pip install pydantic-ai
Step 1 — Put the Proxy on the Tool's HTTP Client
The binding lives on the httpx client your tool uses. Build a client with the proxy argument and make the tool's request through it:
import httpx
from pydantic_ai import Agent, RunContext
PROXY = "http://USER:PASS@PROXY_HOST:PORT"
agent = Agent("openai:gpt-4o")
@agent.tool
async def fetch_german_page(ctx: RunContext[None], url: str) -> str:
"""Fetch a URL through the German mobile proxy and return its text."""
# proxy= routes this tool's request through the German mobile IP.
async with httpx.AsyncClient(proxy=PROXY, timeout=30) as client:
resp = await client.get(url)
resp.raise_for_status()
return resp.text
That's the whole binding for the common case. When the model decides to call fetch_german_page, the request leaves through your German mobile IP — and the model's own reasoning traffic is untouched.
Step 2 — Run the Agent
Give the agent a task that needs the tool. The model chooses when to call it; the tool decides how the request leaves:
import asyncio
async def main():
result = await agent.run(
"Fetch https://www.example.de and summarise the public product details."
)
print(result.output)
asyncio.run(main())
The agent reasons about what to fetch; the httpx client in the tool carries the German mobile IP for the actual request. Nothing about the model call changes.
Step 3 — Share One Client, or Route the Model Too
For a tool that fires often, reuse a single client instead of opening one per call — and if you do want the model provider on the German exit as well, pass the same kind of client as the provider's http_client:
import httpx
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider
PROXY = "http://USER:PASS@PROXY_HOST:PORT"
# A shared client the tools can reuse.
proxied_client = httpx.AsyncClient(proxy=PROXY, timeout=30)
# Optional: route the model provider through the proxy too.
model = OpenAIChatModel(
"gpt-4o",
provider=OpenAIProvider(http_client=proxied_client),
)
agent = Agent(model)
# You own proxied_client's lifecycle — close it when the app shuts down.
Routing the provider is opt-in on purpose. Most agents only need the tool on the German mobile IP; the model call can stay on your normal connection.
Verify the IP First
Before a real run, confirm the exit IP is a German mobile address. The quickest check is a one-line request through the same proxy:
curl -x "http://USER:PASS@PROXY_HOST:PORT" https://api.ipify.org?format=json
If it returns your own address, the proxy didn't reach the tool's client — re-check the URL and that the credentials are in it. Confirm the ASN and geolocation look like a German mobile network, not a datacenter range. A full checklist is in testing your proxy setup.
Sticky Sessions vs. Rotation
How the agent should handle IPs depends on the task:
- Sticky session — keep the same German mobile IP across a multi-step flow (fetch a page, follow links, extract) so a sequence of tool calls looks like one coherent visitor.
- Rotation on demand — request a fresh IP at the proxy between runs to spread load across a longer job.
Keep request rates human-reasonable and cap how many tool calls fire at once. The mechanics are in sticky sessions and IP rotation.
Why a Mobile IP at All
German content is localised. German marketplaces and Google.de serve different results, pricing and stock by country and network. Have your agent fetch a German site from a US datacenter range and it measures the wrong market. A German IP gives it the in-country view the task needs.
Mobile IPs carry high IP reputation. German sites filter datacenter ranges aggressively — often a 403 Forbidden within a handful of requests. Mobile IPs sit in shared CGNAT pools used by thousands of real subscribers, so they carry high IP reputation — the reason a mobile IP keeps working where a datacenter range stalls.
For the trade-offs between IP types, see mobile vs residential vs datacenter proxy and, on cost, dedicated mobile vs pay-per-GB residential. For the wider agent picture, see mobile proxies for AI agents.
Scrape Responsibly
A mobile proxy improves reliability for legitimate data collection — it is not a tool to circumvent access controls or platform rules. An agent runs largely unattended, so the responsibility to keep it clean is higher, not lower:
- Respect
robots.txtand each site's terms — bake the check into the tool, not just into intentions. - Throttle — add a delay between tool calls and cap concurrency so you don't overload target servers.
- Collect only public data you need, and handle any personal data in line with the GDPR.
- Identify your client honestly — set a truthful
User-Agent; don't impersonate someone else.
Whether a specific task is lawful depends on your jurisdiction and the target's terms — this is general information, not legal advice. See are mobile proxies legal and the legal status of web scraping in the EU.
[!NOTE]
Note: This article is general information, not legal advice. Whether a specific data-collection task is lawful depends on your jurisdiction, the target site's terms and the data involved.
FAQ
Does the proxy change how Pydantic AI talks to the LLM?
Not unless you set it up that way. The proxy binds to the httpx client your tool uses — the request it makes to a target site. The LLM call your agent uses to reason stays on its own connection unless you deliberately pass a proxied http_client to the model provider. In practice you route the tool through the German mobile IP and leave the model traffic alone.
Where exactly does the proxy go in Pydantic AI?
On the HTTP client the tool function uses. Create httpx.AsyncClient(proxy="http://USER:PASS@PROXY_HOST:PORT") inside the tool (or share one across tools) and make your request with it. Because httpx takes proxy directly, no extra middleware is involved.
Can I also route the model provider through the proxy?
Yes. Pass a custom httpx.AsyncClient(proxy=...) as the provider's http_client — for example OpenAIProvider(http_client=client). Note that when you supply your own client you're responsible for closing it. Most setups only route the tool, not the model.
Why do I get a 407 error?
407 Proxy Authentication Required means the username and password didn't reach the proxy. Confirm they're in the URL you passed to httpx.AsyncClient(proxy=...) (http://USER:PASS@PROXY_HOST:PORT). See how to fix 407 proxy authentication required.
HTTP or SOCKS5?
httpx works with an HTTP endpoint out of the box, which is why the examples use http://. SOCKS5 and OpenVPN are available too — for SOCKS you install httpx with the socks extra and pass a socks5:// URL. For most Pydantic AI work, HTTP is simplest. See SOCKS5 vs HTTP proxy.
Do I need a rotating pool for Pydantic AI?
No. Pool middlewares exist to pick an IP from many. With one dedicated German endpoint you point every tool at a single host and rotate on demand at the proxy — nothing to manage in the agent. See dedicated vs shared mobile proxy.
Related guides
- Vercel AI SDK Proxy Setup with a German Mobile Proxy
- smolagents Proxy Setup: Route Agents via German Mobile IPs
- Running AI Agents on German Sites: A Reliability Playbook
Get Started
Give your Pydantic AI agent a real German mobile IP to collect from. 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 get a dedicated proxy on the Blue network.