Skip to main content
DELETE
/
v1
/
tunnels
/
:id
Delete Tunnel
curl --request DELETE \
  --url https://api.example.com/v1/tunnels/:id
{
  "ok": true,
  "INVALID_TUNNEL_ID": {},
  "TUNNEL_NOT_FOUND": {},
  "TUNNEL_STOP_PENDING_ACTIVE_CONNECTIONS": {},
  "TUNNEL_CLOUDFLARE_DELETION_FAILED": {}
}
Stop and delete a tunnel, removing its DNS record and cleaning up resources.

Authentication

Requires a valid access token in the Authorization header:
Authorization: Bearer <access_token>

Path Parameters

id
string
required
Tunnel identifier. Can be either:
  • The tunnel UUID (e.g., a1b2c3d4-e5f6-7890-abcd-ef1234567890)
  • The tunnel hostname (e.g., my-app.example.com)

Request Body

No request body is required.

Response

ok
boolean
Always true on success.

Error Responses

INVALID_TUNNEL_ID
400
The tunnel identifier is missing or invalid.
TUNNEL_NOT_FOUND
404
The tunnel was not found for this user.
TUNNEL_STOP_PENDING_ACTIVE_CONNECTIONS
503
The tunnel has active connections and will be stopped once they drain. The tunnel is marked as stopping and cleanup will continue automatically.
TUNNEL_CLOUDFLARE_DELETION_FAILED
502
Failed to delete the tunnel from Cloudflare. The tunnel is marked as stopping and cleanup will be retried automatically.

What Happens on Delete

When you delete a tunnel, the following operations are performed:
  1. DNS Record Deletion: The DNS record pointing to the tunnel is immediately deleted
  2. Cloudflare Tunnel Deletion: The Cloudflare tunnel is deleted from the Cloudflare API
  3. Lease Deletion: The heartbeat lease is removed
  4. Status Update: The tunnel status is changed to stopped
  5. Audit Log: A tunnel.stopped audit log entry is created
If the tunnel has active connections, the deletion process may take longer. The tunnel will be marked as stopping and cleanup will continue in the background.

Cleanup Behavior

Example Request

curl -X DELETE https://api.example.com/v1/tunnels/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Authorization: Bearer <access_token>"

Example Response

{
  "ok": true
}

Graceful Shutdown Example

import { tunnelClient } from './client';

// Handle shutdown signals
process.on('SIGINT', async () => {
  console.log('\nShutting down tunnel...');
  
  try {
    await tunnelClient.deleteTunnel(tunnelId);
    console.log('Tunnel stopped successfully');
    process.exit(0);
  } catch (error) {
    console.error('Failed to stop tunnel:', error);
    process.exit(1);
  }
});

process.on('SIGTERM', async () => {
  console.log('\nShutting down tunnel...');
  
  try {
    await tunnelClient.deleteTunnel(tunnelId);
    console.log('Tunnel stopped successfully');
    process.exit(0);
  } catch (error) {
    console.error('Failed to stop tunnel:', error);
    process.exit(1);
  }
});

Best Practices

Always delete tunnels when your application shuts down to avoid leaving stale tunnels and DNS records.
Deleted tunnels cannot be recovered. If you need to expose the same port again, you’ll need to create a new tunnel.
If you’re experiencing issues with tunnel deletion, check the tunnel’s status with the List Tunnels endpoint. Tunnels in stopping state will be cleaned up automatically.

Build docs developers (and LLMs) love