Follow this guide to set up a Cloudflare Tunnel using the API.

## 1. Create an API token

[Create an API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with the following permissions:

| Type    | Item              | Permission |
| ------- | ----------------- | ---------- |
| Account | Cloudflare Tunnel | Edit       |
| Zone    | DNS               | Edit       |

## 2. Create a tunnel

Make a `POST` request to the [Cloudflare Tunnel](https://developers.cloudflare.com/api/resources/zero_trust/subresources/tunnels/subresources/cloudflared/methods/create/) endpoint:

```sh
curl 'https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--data '{
  "name": "api-tunnel",
  "config_src": "cloudflare"
}'
```

```sh
{
  "success": true,
  "errors": [],
  "messages": [],
  "result": {
    "id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
    "account_tag": "699d98642c564d2e855e9661899b7252",
    "created_at": "2025-02-18T22:41:43.534395Z",
    "deleted_at": null,
    "name": "example-tunnel",
    "connections": [],
    "conns_active_at": null,
    "conns_inactive_at": "2025-02-18T22:41:43.534395Z",
    "tun_type": "cfd_tunnel",
    "metadata": {},
    "status": "inactive",
    "remote_config": true,
    "credentials_file": {
      "AccountTag": "699d98642c564d2e855e9661899b7252",
      "TunnelID": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
      "TunnelName": "api-tunnel",
      "TunnelSecret": "bTSquyUGwLQjYJn8cI8S1h6M6wUc2ajIeT7JotlxI7TqNqdKFhuQwX3O8irSnb=="
    },
    "token": "eyJhIjoiNWFiNGU5Z..."
  }
}
```

Copy the `id` and `token` values shown in the output. You will need these values to configure and run the tunnel.

The next steps depend on whether you want to [connect an application](#3a-connect-an-application) or [connect a network](#3b-connect-a-network).

## 3a. Connect an application

Before you connect an application through your tunnel, you must:

* [Add a website to Cloudflare](https://developers.cloudflare.com/fundamentals/setup/manage-domains/add-site/).
* [Change your domain nameservers to Cloudflare](https://developers.cloudflare.com/dns/zone-setups/full-setup/setup/).

Follow these steps to connect an application through your tunnel. If you are looking to connect a network, skip to the [Connect a network section](#3b-connect-a-network).

1. Make a [`PUT` request](https://developers.cloudflare.com/api/resources/zero_trust/subresources/tunnels/subresources/cloudflared/subresources/configurations/methods/update/) to route your local service URL to a public hostname. For example,

   ```sh
   curl --request PUT \
   'https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel/c1744f8b-faa1-48a4-9e5c-02ac921467fa/configurations' \
   --header 'Content-Type: application/json' \
   --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
   --data '{
     "config": {
       "ingress": [
         {
           "hostname": "app.example.com",
           "service": "http://localhost:8001",
           "originRequest": {}
         },
         {
           "service": "http_status:404"
         }
       ]
     }
   }'
   ```

   Note

   If you add a multi-level subdomain (more than one level of subdomain), you must [order an Advanced Certificate for the hostname](https://developers.cloudflare.com/cloudflare-one/faq/troubleshooting/#i-see-this-site-cant-provide-a-secure-connection).

   Your ingress rules must include a catch-all rule at the end. In this example, `cloudflared` will respond with a 404 status code when the request does not match any of the previous hostnames.

2. [Create a DNS record](https://developers.cloudflare.com/api/resources/dns/subresources/records/methods/create/) for your application:

   ```sh
   curl https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records \
   --header 'Content-Type: application/json' \
   --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
   --data '{
     "type": "CNAME",
     "proxied": true,
     "name": "app.example.com",
     "content": "c1744f8b-faa1-48a4-9e5c-02ac921467fa.cfargotunnel.com"
   }'
   ```

   This DNS record allows Cloudflare to proxy `app.example.com` traffic to your Cloudflare Tunnel (`<tunnel-id>.cfargotunnel.com`).

This application will be publicly available on the Internet once you [run the tunnel](#4-install-and-run-the-tunnel). To allow or block specific users, [create an Access application](https://developers.cloudflare.com/cloudflare-one/applications/configure-apps/self-hosted-public-app/).

## 3b. Connect a network

To connect a private network through your tunnel, [add a tunnel route](https://developers.cloudflare.com/api/resources/zero_trust/subresources/networks/subresources/routes/methods/create/):

```sh
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--data '{
  "network": "172.16.0.0/16",
  "tunnel_id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
  "comment": "Example private network route"
}'
```

To configure Zero Trust policies and connect as a user, refer to [Connect private networks](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/private-net/cloudflared/).

## 4. Install and run the tunnel

Install `cloudflared` on your server and run the tunnel using the `token` value obtained in [2. Create a tunnel](#2-create-a-tunnel). You can also get the tunnel token using the [Cloudflare Tunnel token](https://developers.cloudflare.com/api/resources/zero_trust/subresources/tunnels/subresources/cloudflared/subresources/token/methods/get/) endpoint.

* Windows

  1. [Download and install](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/#windows) `cloudflared`.

  2. Open Command Prompt as administrator.

  3. Run the following command:

     ```txt
     cloudflared.exe service install <tunnel-token>
     ```

* macOS

  1. [Download and install](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/#macos) `cloudflared`.

  2. Run the following command:

     ```sh
     sudo cloudflared service install <tunnel-token>
     ```

* Linux

  1. [Download and install](https://pkg.cloudflare.com/index.html) `cloudflared`.

  2. Run the following command:

     ```sh
     sudo cloudflared service install <tunnel-token>
     ```

* Docker

  1. Open a terminal window.

  2. Run the following command:

     ```sh
     docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <tunnel-token>
     ```

## 5. Verify tunnel status

To check if the tunnel is serving traffic:

```sh
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/cfd_tunnel/c1744f8b-faa1-48a4-9e5c-02ac921467fa \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
```

```sh
{
  "success": true,
  "errors": [],
  "messages": [],
  "result": {
    "id": "c1744f8b-faa1-48a4-9e5c-02ac921467fa",
    "account_tag": "699d98642c564d2e855e9661899b7252",
    "created_at": "2025-02-18T22:41:43.534395Z",
    "deleted_at": null,
    "name": "example-tunnel",
    "connections": [
      {
        "colo_name": "bos01",
        "uuid": "2xz99mfm-a59e-4924-gyh9-z9vafaw6k0i2",
        "id": "2xz99mfm-a59e-4924-gyh9-z9vafaw6k0i2",
        "is_pending_reconnect": false,
        "origin_ip": "10.1.0.137",
        "opened_at": "2025-02-19T19:11:12.101642Z",
        "client_id": "4xh4eb3f-cz0j-2aso-hu6i-36207018771a",
        "client_version": "2025.2.0"
      },
      {
        "colo_name": "phl01",
        "uuid": "axe2socu-2fb5-3akx-b860-898zyes3cs9q",
        "id": "axe2socu-2fb5-3akx-b860-898zyes3cs9q",
        "is_pending_reconnect": false,
        "origin_ip": "10.1.0.137",
        "opened_at": "2025-02-19T19:11:12.006297Z",
        "client_id": "4xh4eb3f-cz0j-2aso-hu6i-36207018771a",
        "client_version": "2025.2.0"
      },
      {
        "colo_name": "phl01",
        "uuid": "9b5y0wm9-ca7f-ibq6-8ff4-sm53xekfyym1",
        "id": "9b5y0wm9-ca7f-ibq6-8ff4-sm53xekfyym1",
        "is_pending_reconnect": false,
        "origin_ip": "10.1.0.137",
        "opened_at": "2025-02-19T19:11:12.004721Z",
        "client_id": "4xh4eb3f-cz0j-2aso-hu6i-36207018771a",
        "client_version": "2025.2.0"
      },
      {
        "colo_name": "bos01",
        "uuid": "g6cdeiz1-80f5-3akx-b18b-3y0ggktoxwkd",
        "id": "g6cdeiz1-80f5-3akx-b18b-3y0ggktoxwkd",
        "is_pending_reconnect": false,
        "origin_ip": "10.1.0.137",
        "opened_at": "2025-02-19T19:11:12.110765Z",
        "client_id": "4xh4eb3f-cz0j-2aso-hu6i-36207018771a",
        "client_version": "2025.2.0"
      }
    ],
    "conns_active_at": "2025-02-19T19:11:12.004721Z",
    "conns_inactive_at": null,
    "tun_type": "cfd_tunnel",
    "metadata": {},
    "status": "healthy",
    "remote_config": true
  }
}
```

A healthy tunnel will have four connections to Cloudflare's network.
