Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
---
title: Create a tunnel (API)
pcx_content_type: how-to
sidebar:
order: 2
---

import { Tabs, TabItem } from "~/components";

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

## 1. Create an API token

[Create an API token](/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](/api/resources/zero_trust/subresources/access/subresources/applications/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 output
{
"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](/fundamentals/setup/manage-domains/add-site/).
- [Change your domain nameservers to Cloudflare](/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](/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](/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](/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](/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](/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](/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](/api/resources/zero_trust/subresources/tunnels/subresources/cloudflared/subresources/token/methods/get/) endpoint.

<Tabs> <TabItem label="Windows">

1. [Download and install](/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>
```

</TabItem> <TabItem label="macOS">

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

2. Run the following command:

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

</TabItem> <TabItem label="Linux">

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

2. Run the following command:

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

</TabItem> <TabItem label="Docker">

1. Open a terminal window.

2. Run the following command:

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

## 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 output
{
"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.
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ Follow these steps to connect an application through your tunnel. If you are loo

<Render file="tunnel/add-public-hostname" product="cloudflare-one" />

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

The application is now publicly available on the Internet. To allow or block specific users, [create an Access application](/cloudflare-one/applications/configure-apps/self-hosted-public-app/).

## 2b. Connect a network
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
1. In the **Public Hostnames** tab, select **Add a public hostname**.

2. Enter a subdomain and select a **Domain** from the dropdown menu. Specify any subdomain or path information.
:::note
If you add a multi-level subdomain (more than one level of subdomain), you must [order an Advanced Certificate for the hostname](/cloudflare-one/faq/troubleshooting/#i-see-this-site-cant-provide-a-secure-connection).
:::

3. Specify a service, for example `https://localhost:8000`.

Expand Down
Loading