> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qa.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Remote Tunnels API

> Create and manage secure tunnels to expose local environments

The Remote Tunnels API enables you to programmatically create secure tunnels that expose local ports via Cloudflare. This allows QA.tech to access locally-running applications for testing without deploying them to a public server.

## Prerequisites

Before using the Remote Tunnels API, you need:

1. **cloudflared** – Cloudflare's tunnel client must be installed on your machine or CI runner

   ```bash theme={null}
   # macOS
   brew install cloudflared

   # Linux (Debian/Ubuntu)
   curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
   sudo dpkg -i cloudflared.deb

   # See https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/
   ```

2. **Your application running locally** – The tunnel exposes local ports, so your app must be running

## Tunnel Expiration

<Warning>
  Tunnels expire **4 hours** after creation. The `expiresAt` field in the
  response indicates when the tunnel will be automatically torn down. For
  long-running development, you'll need to create a new tunnel when the current
  one expires.
</Warning>

## When to Use Remote Tunnels

* **Local development testing** – Test your local environment without deploying
* **CI/CD pipelines** – Expose ephemeral test servers during build processes
* **Preview environments** – Create temporary public URLs for testing
* **Firewall-protected environments** – Access applications behind corporate firewalls

<Note>
  For CLI-based tunnel management, see the [tunnel
  command](/cli/commands/tunnel) documentation. The CLI provides a simpler
  interface for common tunnel operations.
</Note>

## Authentication

All endpoints require Bearer token authentication. Create your API key in the QA.tech dashboard: **Organization Settings → API Keys**. The key is shown only once, at creation. See the [API Introduction](/api-reference/introduction#authentication) for details.

## Endpoints

For full request, response, and error details, see the generated reference pages:

* [Create Remote Tunnel](/api-reference/remote-tunnels/create-remote-tunnel) – Expose one or more local ports; returns the tunnel's public hostnames and a `tunnelToken`
* [List Remote Tunnels](/api-reference/remote-tunnels/list-remote-tunnels) – All tunnels for your project, including expired ones
* [Get Remote Tunnel Status](/api-reference/remote-tunnels/get-remote-tunnel-status) – Live Cloudflare health status of a tunnel
* [Delete Remote Tunnel](/api-reference/remote-tunnels/delete-remote-tunnel) – Tear down a tunnel and its DNS records

## Tunnel Lifecycle

1. **Create the tunnel** via [Create Remote Tunnel](/api-reference/remote-tunnels/create-remote-tunnel), specifying the local ports to expose. The response contains the public hostnames mapped to each port, a `tunnelToken`, and the `runnerId` used in subsequent calls.

2. **Start the cloudflared daemon** with the returned token:

   ```bash theme={null}
   cloudflared tunnel run --token YOUR_TUNNEL_TOKEN
   ```

   The tunnel remains active as long as cloudflared is running and the tunnel has not expired (4-hour maximum lifetime).

3. **Check health** with [Get Remote Tunnel Status](/api-reference/remote-tunnels/get-remote-tunnel-status) before pointing tests at the tunnel.

4. **Use the public URLs** as environment overrides when [starting a run](/api-reference/runs/start-test-run) or [creating a chat conversation](/api-reference/chat).

5. **Clean up** with [Delete Remote Tunnel](/api-reference/remote-tunnels/delete-remote-tunnel) when you're done.

<Tip>
  For simpler tunnel management, consider using the [CLI tunnel
  command](/cli/commands/tunnel) which handles cloudflared automatically:
  `qatech tunnel start --port 3000`
</Tip>

## Hostname Format

Each exposed port gets a public HTTPS hostname based on the tunnel's `runnerId`:

* Single port without `subdomain`: `r-{runnerId}.quack.run`
* Multiple ports without `subdomain`: `r-{runnerId}-p{localPort}.quack.run`
* With `subdomain`: `r-{runnerId}-{subdomain}.quack.run`

## Related

* [Tunnel CLI Command](/cli/commands/tunnel) – CLI interface for tunnel management
* [SSH Tunnel](/configuration/ssh-tunnel) – Alternative tunneling via SSH
* [Start Run API](/api-reference/runs/start-test-run) – Use tunnel URLs as environment overrides
* [API Introduction](/api-reference/introduction) – Authentication and ID reference
