# https://tunnels.io/learn/what-is-a-reserved-subdomain

[Home](https://tunnels.io/) / [Learn](https://tunnels.io/learn) / What is a reserved subdomain

Learn

# What is a reserved subdomain?

A reserved subdomain is a hostname you claim once and keep, so your tunnel always comes back at the same public URL instead of a new random one. It stays yours between restarts, reboots and reconnects, which is what makes it safe to register with a webhook provider, an OAuth callback, or a client.

## What exactly is being reserved?

The label on the left of the tunnel provider's domain, the `myapi` in `myapi.tunnels.host`. Reserving it binds that name to your account rather than to a running process. An ordinary tunnel is given a hostname at connect time and gives it back when the connection ends; a reserved one is allocated to you in advance, so reconnecting reclaims the same name instead of drawing a new one.

Nothing else about the tunnel changes. The traffic path, the TLS termination and the local port you are forwarding to are identical. The only difference is that the address is now a fact about your account instead of a fact about one connection.

## Why does a tunnel URL change every time?

Because by default the hostname is allocated per session. When the client connects, the server picks a free label, maps it to that one connection, and releases it when the connection drops. Nothing about the name is stored against your account, so the next connection gets whatever is free at that moment.

That is a sensible default for a throwaway share, and it is the wrong default the second anything else writes your URL down.

```
# Monday morning
$ tunnels localhost:3000
Active Tunnels:
▸ https://k7m2p9x4qw8n3vzt.tunnels.host → http://localhost:3000  [https]
# Same command, after lunch. Same laptop, same port, different URL.
$ tunnels localhost:3000
Active Tunnels:
▸ https://9f8e7d6c.tunnels.host → http://localhost:3000  [https]
```

## What breaks when the URL changes?

Everything that stored the old one. A webhook endpoint you registered at Stripe, GitHub, Shopify or Twilio keeps delivering to a hostname that is no longer yours, and you find out through missing events rather than an error on your screen. OAuth redirect URIs are matched exactly, so a changed host is rejected at the callback. The same applies to CORS allowlists, mobile builds compiled against an API base URL, QR codes, and the link you sent a client on Friday.

There is a security edge to it too. Once a random label is released it can be handed to a different connection, so a request meant for you may arrive somewhere you do not control. Anything carrying a signed payload or a token is worth keeping on a name you actually hold.

### Webhooks

Registered once in a provider dashboard and never looked at again. A dead host means silent delivery failures until the retry window closes.

### OAuth callbacks

Redirect URIs are compared as exact strings. A new host is not a near match, it is a rejected authorization.

### Anything compiled in

Mobile builds, CORS allowlists, printed QR codes and CI config all bake the host in. Changing it means a rebuild, not an edit.

## Is a reserved subdomain the same as a static IP?

No, and the difference matters. A reserved subdomain fixes the name; the address behind it can move whenever the provider needs it to. That indirection is the feature, because the edge can reroute your traffic without anything you registered having to change.

If a third party insists on a fixed IP address for a firewall allowlist, a stable hostname does not satisfy that requirement. Those are different problems with different solutions.

## Reserved subdomain or custom domain?

A reserved subdomain sits on the provider's domain and needs no DNS work from you, which is why it takes seconds rather than a change request. A custom domain is one you already own, pointed at the tunnel, so the URL carries your name and can outlive the tool that serves it.

Use a reserved subdomain for development, webhook endpoints, staging links and anything internal. Reach for a custom domain when someone outside your team will read the URL out loud, or when you need the address to survive a change of provider.

## How many do you actually need?

Fewer than most people assume. The honest count is one per long-lived integration: one for the webhook endpoint registered in a provider dashboard, one for the staging site a client has bookmarked, one for the API your mobile build points at.

Everything else is fine on a random URL. A quick demo, a screen share, a link with a two-hour lifespan; none of those are stored anywhere that outlives the session. The rule is simple: reserve a name when something other than a human is going to remember it.

## What happens to the subdomain while the tunnel is offline?

The name stays allocated to your account. It simply has nothing to serve, so requests to it fail while no client is connected, and they start succeeding again the moment one reconnects.

That is the behaviour you want for a registered endpoint. Most webhook providers retry a failed delivery on a backoff for some period, so closing your laptop at the end of the day does not mean re-registering anything in the morning.

## Related reading

[Webhook development Why a URL that survives a restart is the difference between a working integration and a silent one.](https://tunnels.io/use-cases/webhooks) [How to test webhooks locally The job a reserved subdomain exists for. Giving Stripe, GitHub and the rest an address that reaches your laptop.](https://tunnels.io/learn/how-to-test-webhooks-locally) [What is tunneling? The mechanism underneath. Worth reading first if the words reverse tunnel and NAT are still doing a lot of unexplained work.](https://tunnels.io/learn/what-is-tunneling) [HTTP vs HTTPS tunnels Where TLS gets terminated on a tunnel URL, and why webhook providers increasingly refuse anything but HTTPS.](https://tunnels.io/learn/http-vs-https-tunnels)

More of these in [Learn](https://tunnels.io/learn).

## How do tunnels.io reserved subdomains work?

You name the subdomain when you start the tunnel and it is yours from then on, on `tunnels.host`. Names are 4 to 63 characters, lowercase letters, numbers and hyphens. There is no DNS to configure, no certificate to renew, and no interstitial or warning page on any plan, so a webhook caller gets your response rather than a click-through screen.

It is a paid capability. The free Basic plan issues a random URL on every connection by design, and the server will not accept a requested name on a random-URL plan. Pro, at $4 a month or $40 a year, includes up to three reserved subdomains alongside 128 GB of transfer and 5 tunnels. Gold adds your own custom domains on top of that.

[See plans and limits →](https://tunnels.io/pricing) [Start on the free plan](https://tunnels.io/get-started)

## Questions

### Can I get a reserved subdomain on a free plan?

Not on tunnels.io. The free Basic plan issues a random URL each time the tunnel connects, and the server rejects a requested name on a random-URL plan. Reserved subdomains start on Pro, which is $4 a month or $40 a year and includes up to three of them.

### Does a reserved subdomain survive a restart or a reboot?

Yes. The name belongs to your account rather than to the process, so when the client reconnects it reclaims the same hostname and traffic resumes at the same URL. Nothing needs re-registering at your webhook provider. That is the entire reason the feature exists.

### Is a reserved subdomain the same thing as a custom domain?

No. A reserved subdomain is a name you hold on the provider's domain, such as myapi.tunnels.host, and it needs no DNS configuration from you. A custom domain is a domain you already own and point at the tunnel yourself. On tunnels.io, reserved subdomains are included from Pro and custom domains start on Gold.

### Do I still get HTTPS on a reserved subdomain?

Yes. Public tunnel URLs are HTTPS, with TLS terminated at the edge before traffic is forwarded down the tunnel to your local port. You do not issue or renew a certificate for the subdomain, and your local server can keep serving plain HTTP on localhost.

### What if the subdomain I want is already taken?

Names on a shared domain have to be unique, so one already held by another account is not available to you. Pick a different label, or move to a custom domain on Gold or above, where the whole namespace is yours and nobody else can claim a name inside it.
