# Exposing publicly

> Make a local route reachable from the internet for webhooks, OAuth, and mobile testing.

Public exposure sends requests through a routeup server and back to your local agent over an outbound tunnel. Your app still listens only on a local port.

## Requirements

You need a public-server control URL. For the hosted service, use
`https://edge.routeup.dev`. You can start immediately with a temporary URL under
`try.routeup.dev`. For a reusable named URL, [request a hosted token](/docs/getting-started/using-a-token#request-a-hosted-token).

The named examples below assume a token for `*.team.routeup.dev`, which grants
URLs such as `https://example-app.team.routeup.dev`. A public address is
reachable only while its tunnel is connected.

Save the hosted server during setup. Add a token when you have one:

```bash
routeup setup --server https://edge.routeup.dev
routeup setup --server https://edge.routeup.dev --token sk_routeup_xxx
```

Or pass them per command:

```bash
routeup serve example-app --port 8080 --server https://edge.routeup.dev --token sk_routeup_xxx --expose
```

## Expose a local port

```bash
routeup serve example-app --port 8080 --expose
```

The command prints the local route, the public URL, the exposed path scope, and
the resolved targets. It holds both the local route and public tunnel until you
press `Ctrl-C`.

```txt frame="terminal" title="terminal"
route: example-app
local: https://example-app.localhost
public: https://example-app.team.routeup.dev
expose: all paths
targets:
  /        http://localhost:8080

requests: live
press Ctrl-C to stop
```

## Name rules

Local route names may be dotted, such as `api.example-app`. Public hosts must be one
label under their namespace, so routeup normalizes dots to hyphens when
exposing: local route `api.example-app` becomes public label `api-example-app`.

Do not include `https://` or the public suffix in the route name. Pass `example-app`, not `https://example-app.routeup.dev`.

## Token-less random names

`--random` generates a random route name. Without a token, a server's public
namespace makes that claim session-only:

```bash
routeup serve --random --port 8080 --server https://edge.routeup.dev --expose
```

On the hosted server, random token-less names are under `try.routeup.dev`:

```txt frame="terminal" title="terminal"
route: happy-fox
local: https://happy-fox.localhost
public: https://happy-fox.try.routeup.dev
expose: all paths
targets:
  /        http://localhost:8080

requests: live
press Ctrl-C to stop
```

## Limit public paths

By default, public exposure forwards every path on the route. To expose only a webhook prefix, set `expose.paths` in project config:

```json title="routeup.json"
{
  "name": "example-app",
  "port": 8080,
  "expose": {
    "paths": ["/api/webhooks/*"]
  }
}
```

Then run:

```bash
routeup serve --expose
```

Requests to `https://example-app.team.routeup.dev/api/webhooks/...` are public; other paths stay local-only.

When path limits are active, routeup rejects dot segments, backslashes, and
encoded separators rather than risk an upstream framework normalizing a request
outside the allowed prefix.
