# Proxies (https://upapi.io/docs/platform/proxies)



Operations that fetch from third-party sites run through a proxy pool by
default. You can override it per request, or configure a pool of your own for
the whole organization.

## Per request [#per-request]

Send the proxy URL in the `x-proxy-url` header:

```bash
curl -X POST https://api.upapi.io/github-trending.get \
  -H 'x-api-key: upapi_YOUR_KEY' \
  -H 'x-proxy-url: http://user:pass@proxy.example.com:8080' \
  -H 'content-type: application/json' \
  -d '{"since":"daily"}'
```

The URL is validated before use — it must resolve to a public address, the same
guard that protects [hosted functions](https://upapi.io/docs/platform/hosted-functions). A URL
that fails validation returns `400 INVALID_INPUT` naming the reason, rather than
silently falling back to the default pool.

The header works on any operation. Some operations — most of the social-platform
ones — *additionally* declare a `proxyUrl` field in their input schema, which
their worker honours; the operation's marketplace page shows whether it does. The
header is the portable choice, since it needs nothing from the schema.

## Per organization [#per-organization]

You can also save a set of proxy URLs on your organization. When no
`x-proxy-url` header is present, one of them is chosen at random for the call.
A request header always wins over the pool.

Organization proxies are validated when you save them, so a bad entry is caught
at configuration time rather than on a call at three in the morning.

## Why it matters [#why-it-matters]

The usual reason to bring your own proxy is **IP consistency across a chain of
calls**. If a workflow logs in, then reads, then acts, having those steps arrive
from three different addresses is what gets sessions flagged. Pinning one proxy
for the chain keeps it coherent.

Proxy cost is already included in the price of a call. There is no separate
proxy bill, whether you use ours or your own.

## Two behaviours to design around [#two-behaviours-to-design-around]

### A custom proxy disables caching [#a-custom-proxy-disables-caching]

Responses fetched through your proxy are never cached and never served from
cache, so `x-upapi-cache` will not report a `HIT`. A response fetched from your
egress IP is not interchangeable with one fetched from ours — geography and
personalization both make it a different answer. Expect full latency and full
upstream load on every proxied call.

### Hosted functions are not proxied [#hosted-functions-are-not-proxied]

`ctx.fetch` inside a [hosted function](https://upapi.io/docs/platform/hosted-functions) egresses
directly. `x-proxy-url` on a hosted-function call does not route its outbound
requests. When you need a specific egress IP, call a marketplace operation that
supports proxying instead of reimplementing the fetch in a function.
