DocumentationAccount

Custom domains, TCP ports, dedicated addresses and private networks

Four ways to connect sandboxes to the rest of your world. They are for paid accounts: an account that has not added credit gets payment_required (402). A custom domain or a TCP port also needs the sandbox it serves to be a paid one.

  • Custom domain: a sandbox's web port at your own hostname, with HTTPS.
  • TCP port: a public address:port for anything that is not HTTP, such as Postgres, Redis, MQTT or a game server.
  • Dedicated outbound address: every sandbox of your account sends from one address of its own, so you can allow-list it.
  • Private network: a WireGuard tunnel from your own network, in any cloud or on your premises, into your sandboxes.

None of them belongs to one sandbox alone, so each is its own product in the CLI, the SDKs and MCP: runtime domain, runtime port, runtime address and runtime tunnel; runtime.domains, runtime.ports, runtime.addresses and runtime.tunnel; runtime_domain_*, runtime_port_*, runtime_address_* and runtime_tunnel_*. They are not billed yet; the pricing page will list their prices before they are.

Custom domains

Terminalruntime domain add app.example.com <sandbox> 3000

The answer lists two DNS records to set at your DNS provider:

Record Name Value What it does
TXT _runtime-challenge.app.example.com runtime-verify=<token> Proves the name is yours
CNAME app.example.com domains.runtimehost.com Sends visitors to Runtime

A name with no subdomain (example.com) cannot have a CNAME; set an A record to the address the answer gives instead. Then check:

Terminalruntime domain verify app.example.com

The name goes live when the TXT record matches. The first visit gets its certificate from Let's Encrypt, which takes a few seconds. Your server must listen on 0.0.0.0 or localhost inside the sandbox, as for a preview link, and be started with spawn, which keeps it running. WebSockets work, and a paused sandbox is woken by a visit, like a preview.

  • Ownership is the TXT record. A CNAME pointing at Runtime proves nothing, so a record someone forgot to delete cannot be used to take their name. Each claim has its own token.
  • The DNS owner wins. If another account proves the same name later, it takes the name over and your claim ends.
  • To move the name to another sandbox or port, run add again with the new target. To stop serving it, runtime domain rm app.example.com.
  • Limits: 50 domains per account, 20 added a day. Certificates are issued for proved names only.
  • Reports reach Runtime through the X-Runtime-Report header on every answer and the abuse address, as for previews. Runtime can take a name down; it then stays down for every account.

TCP ports

Terminalruntime port open <sandbox> 5432# 203.0.113.10:23456psql "postgres://app@203.0.113.10:23456/app?sslmode=require"

A TCP port carries raw TCP from a public address and port to a port inside the sandbox. Opening the same sandbox and port again returns the same public port.

  • Anyone who knows the address can connect. Use your service's own authentication and TLS.
  • Only TCP is carried. UDP (most game servers' own traffic, QUIC) is not.
  • Limits: 5 ports per sandbox, 20 per account and 50 opened a day. Each sandbox's ports share 256 open connections, 50 new connections a second, and 32 connections from any one client address. Bandwidth and the daily byte quota are the same as the sandbox's outbound ones.
  • A closed port rests for a day before anyone else can be given it, so a client still pointed at it never reaches someone else's service.
  • A paused sandbox is woken by a connection, and its connections end when it stops, pauses or is deleted.
  • runtime port ls lists them; runtime port close <portId> closes one.

Dedicated outbound addresses

Terminalruntime address reserve# 203.0.113.50

From then on every sandbox of your account sends from that address, on every port, so a database, an API provider or a firewall can admit exactly you. No other account sends from it while you hold it.

  • One IPv4 address per account, and one IPv6 with --ipv6.
  • runtime address release <addressId> gives it back, and your sandboxes send from the shared addresses again at once. A released address rests for 30 days before any other account gets it. Remove it from your allow-lists first.
  • Addresses are added to Runtime as accounts need them. If none is free, the answer is no_capacity (503): write to support.

Private networks

A WireGuard tunnel from a machine or router on your network into your sandboxes. Every sandbox gets an address in the tunnel's subnet, and your machines reach any port of it there.

Terminalruntime tunnel create                                # subnet 10.250.0.0/16 by defaultruntime tunnel peer add office --route 10.0.0.0/16   # writes runtime.confsudo wg-quick up ./runtime.confruntime tunnel get                                   # each sandbox's addresspsql -h 10.250.0.32 app

runtime tunnel peer add makes the WireGuard key pair on your machine; the private key goes only into runtime.conf, which only you can read. Any WireGuard client works with the file: wg-quick on Linux and macOS, the WireGuard apps on Windows, macOS, iOS and Android, or your router. To use a key you already have, pass --public-key.

  • Choose a subnet your network does not use, from /16 to /24, when you create the tunnel: --subnet 172.30.0.0/16.
  • --route names your own ranges behind the peer. List them when your sandboxes will reach your network through the peer.
  • What a peer reaches: your own account's sandboxes, at their tunnel addresses, on any port except Runtime's own relays inside the sandbox (10800, 10802 and 10853). Nothing else: not another account's sandboxes, not Runtime's servers, not the internet. Only TCP is carried.
  • Rotate a key with runtime tunnel peer rotate <peerId>: the old key stops working within seconds, and connections opened with it end. runtime tunnel peer rm <peerId> removes a peer the same way.
  • Limits: one tunnel per account, 16 peers. A paused sandbox is woken by a connection.

From the SDKs:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.tunnel.create();const office = await runtime.tunnel.addPeer({ name: "office", routes: ["10.0.0.0/16"] });// office.config is the wg-quick file; with no publicKey given, it holds the// private key Runtime generated for you, shown once.
Pythonruntime.tunnel.create()office = runtime.tunnel.add_peer("office", routes=["10.0.0.0/16"])

Errors

Code Status Meaning
payment_required 402 The account has not added credit, or the sandbox is a trial one
network_not_allowed 403 Runtime turned network features off for the account
quota_exceeded 409 A limit above was reached
rate_limited 429 Too many added today
no_capacity 503 No public port or dedicated address is free just now
network_unavailable 503 The feature is not switched on in this region yet

Was this page right?