---
title: Outbound fetch
description: "fetch() reaches any public address, and never a private one."
---

## Usage

`fetch()` needs no configuration.

```js
const res = fetch("https://api.stripe.com/v1/charges", {
  method: "POST",
  headers: { authorization: "Bearer " + env.STRIPE_KEY },
  body,
});
```

It returns the response directly, and the whole body is read into memory, up to 32 MiB by default. Redirects are returned to the handler, not followed.

## Private addresses

`fetch()` refuses private and reserved addresses: loopback, private networks (RFC 1918), link-local and the cloud metadata endpoint `169.254.169.254`, CGNAT, multicast, and their IPv6 equivalents, including IPv4-mapped and NAT64 forms. The check runs on the address a name resolves to, at connect time, so a public name pointing at a private address is refused too.

```
fetch() refused: db.internal resolves to 10.0.0.7, a private or reserved address (10.0.0.0/8). An operator can allow it with SB_EGRESS_ALLOW=10.0.0.7
```

Whoever runs the server can let specific addresses through with `SB_EGRESS_ALLOW`, either `*` or a comma-separated list of exact addresses. On a self-hosted platform, add it to `/etc/sproutboat/egress.env` and restart `sproutboat-egress`; for a [standalone build](/docs/get-started/standalone), set it in the binary's environment. Handler code cannot change it.

## Related

- [Platform limits](/docs/platform/limits): response body size
- [Service bindings](/docs/bindings/service-bindings): call another of your projects over the server's loopback
