When developing software on your devbox, you will often want to expose local services running on your devbox to the outside world. For example, you may want to have your agent start a local web server to serve a frontend application and then expose the live frontend to your users. Other examples include:Documentation Index
Fetch the complete documentation index at: https://docs.runloop.ai/llms.txt
Use this file to discover all available pages before exploring further.
- remotely collaborating on a frontend project
- testing a web service
- accessing a Jupyter notebook running on your devbox
- accessing a local database running on your devbox
Supported Protocols
devbox tunnels support multiple protocols, making them suitable for a wide variety of applications:- HTTP/HTTPS: Standard web traffic for REST APIs, web applications, and static content
- WebSockets: Real-time bidirectional communication for chat applications, live updates, and interactive features
- Server-Sent Events (SSE): One-way real-time communication from server to client for live data streams and notifications
Setting up a tunnel
There are two ways to set up a tunnel: at devbox creation time, or after the devbox is running.Option 1: Enable tunnel at devbox creation
The simplest approach is to enable the tunnel when creating the devbox. The tunnel will be automatically provisioned and available when the devbox is ready.Option 2: Enable tunnel on a running devbox
You can also enable a tunnel on an existing running devbox using theenable_tunnel method.
Tunnel URL Format
Tunnel URLs follow this format:{port}is the port number your service is running on (e.g., 8080, 3000){tunnel_key}is the encrypted key returned when you enable the tunnel
abc123xyz and your service runs on port 3000:
0.0.0.0.
Authentication Modes
Tunnels support two authentication modes:Open Mode (Public Access)
Withauth_mode: "open", anyone with the URL can access your tunnel. This is useful for:
- Sharing live previews with collaborators
- Testing webhooks from external services
- Public demos
Authenticated Mode (Restricted Access)
Withauth_mode: "authenticated", requests must include a bearer token. This is useful for:
- Sensitive development environments
- APIs that should not be publicly accessible
- Secure internal tools
Tunnel Lifecycle
- One tunnel per devbox: Each devbox can have one tunnel enabled at a time.
- Persistent until shutdown: Once enabled, tunnels remain active until the devbox is shut down.
- Survives suspend/resume: If you suspend and resume a devbox, the tunnel information is preserved (you’ll need to re-enable the tunnel after resume if needed).
- Multiple ports: A single tunnel allows access to any port on your devbox - just change the port number in the URL.
Wake on HTTP
Withwake_on_http enabled, HTTP traffic to the tunnel URL automatically resumes a suspended devbox. This lets you suspend devboxes when idle and only pay for compute when requests arrive.
When a request hits a suspended devbox:
- The tunnel returns
503 Service Unavailablewith aRetry-After: 5header - The devbox resumes (typically under a second of infrastructure overhead)
- The caller retries and the request is proxied to your running service
503 responses, so wake-on-HTTP works out of the box for webhook endpoints. For browsers, the tunnel returns an HTML page that auto-refreshes.
wake_on_http with an idle timeout:
http_keep_alive, enabled by default), so the devbox stays awake while requests are flowing.
Example: Complete Tunnel Workflow
Here’s a complete example showing how to create a devbox, start a web server, and access it via a tunnel:Advanced: Header Handling for Proxies
If you are placing another proxy in front of a Runloop tunnel, it is useful to understand how the tunnel resolves the target host and the exact behavior for headers forwarded upstream. For routing, the tunnel backend resolves the host in this order:ForwardedX-Forwarded-HostHost
Forwarded or X-Forwarded-Host to your Runloop tunnel hostname and still use Host for your own upstream origin. This is useful when you want an intermediate proxy or load balancer to preserve the origin host expected by your application.
For plain HTTP proxying, Runloop forwards request headers upstream except for hop-by-hop headers such as:
ConnectionTransfer-EncodingTETrailerProxy-AuthorizationProxy-AuthenticateKeep-Alive
x-runloop-request-idis added or replacedx-forwarded-foris addedx-real-ipis addedx-forwarded-protois added
https://8080-abc123xyz.tunnel.runloop.ai, you can route with Forwarded while preserving a different Host header for your application:
Forwarded host for routing and your application still receives Host: internal.example.