Skip to content

Instantly share code, notes, and snippets.

@tenekev
Created September 27, 2025 14:03
Show Gist options
  • Select an option

  • Save tenekev/d539c3a46344cc6aa90d5e1f51495819 to your computer and use it in GitHub Desktop.

Select an option

Save tenekev/d539c3a46344cc6aa90d5e1f51495819 to your computer and use it in GitHub Desktop.
Clean up Tailscale nodes, based on hostname
import requests
def get_tailscale_nodes(tailnet, api_key) -> list:
url = f"https://api.tailscale.com/api/v2/tailnet/{tailnet}/devices"
headers = {
"Authorization": f"Bearer {api_key}"
}
# Step 1: Get the list of all devices
response = requests.get(url, headers=headers)
if response.status_code != 200:
print("Error fetching device list:", response.text)
return False
return response.json().get("devices", [])
def delete_tailscale_node(api_key, device_id):
url = f"https://api.tailscale.com/api/v2/device/{device_id}"
headers = {
"Authorization": f"Bearer {api_key}"
}
delete_response = requests.delete(url, headers=headers)
if delete_response.status_code == 200:
print(f"Node '{device_id}' deleted successfully.")
return True
else:
print("Error deleting node:", delete_response.text)
return False
tailnet = "" # Email Address
api_key = "tskey-api-***" # Working API key
device_name_to_remove = "server-private-insider-docker2"
devices = get_tailscale_nodes(tailnet, api_key)
print(f'Found {len(devices)} devices')
device_id = None
for device in devices:
if device.get("authorized") == False:
if device_name_to_remove in device.get("hostname"):
device_id = device.get("id")
delete_tailscale_node(api_key, device_id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment