Skip to main content

Network Controllers

Self-Hosting ZeroTier Network Controllers#

Reference Docs#


API clients#

There is an OpenAPI spec at which can be used to generate API clients in many languages.

You can browse the docs here.


First, skim the README.

We're going to use curl to set up an example ZeroTier network.

This is a low tech way to setup a controller for example purposes. You'd likely build yourself something fancier around this API.

I'm not sure what's involved in getting curl on Windows. Pull requests welcome.


The authtoken.secret file in the ZeroTier home directory is required to make API calls to the controller service.


ZeroTier generates the token at random the first time it starts. You can change it if you want.

Lets save the token to an environment variable. We need it in all the following commands.

TOKEN=$(sudo cat /var/lib/zerotier-one/authtoken.secret)

Get your Node ID#


Network IDs are based on the Node ID of the Controller. Controllers are nodes! When you join a network, your node finds the controller like it does with other nodes: by it's Node ID.

with zerotier-cli#

(may need sudo)

zerotier-cli info

with curl#

curl "http://localhost:9993/status" -H "X-ZT1-AUTH: ${TOKEN}"

It's the "Address" in the above's output.

Let's save the Node ID to an environment variable too:


or try:

NODEID=$(zerotier-cli info | cut -d " " -f 3)

Create a Network#

curl -X POST "http://localhost:9993/controller/network/${NODEID}______" -H "X-ZT1-AUTH: ${TOKEN}" -d {}

This should return JSON for a fresh network.


When you post to /network/${NODEID}______ the controller generates a random Network ID for you. See the "id" of your newly created network.

Let's save the new Network ID to an environment variable


List Networks#

curl "http://localhost:9993/controller/network/" -H "X-ZT1-AUTH: ${TOKEN}"

This returns a list of Network IDs. It should include the ID returned by the create command we did in the previous step.

Get Network Info#

curl "http://localhost:9993/controller/network/${NWID}/" -H "X-ZT1-AUTH: ${TOKEN}"

List Network Members#

You'll need another node join your network first, or this will be empty. You can use a phone, or another PC, or a VM, or a VPS...

curl "http://localhost:9993/controller/network/${NWID}/member" -H "X-ZT1-AUTH: ${TOKEN}"

I guess you could join the controller node to it's own network, for demonstation purposes.

Save the Node ID of one of your Network Members in an env var


Get Member Info#

curl "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" -H "X-ZT1-AUTH: ${TOKEN}"

Configure the Network#

For Nodes can talk, we need to add a Managed Route and IP Auto-Assign Range on the network. Let's make it a Private network too. Prefer Private networks.

curl -X POST "http://localhost:9993/controller/network/${NWID}/" -H "X-ZT1-AUTH: ${TOKEN}" \
-d '{"ipAssignmentPools": [{"ipRangeStart": "", "ipRangeEnd": ""}], "routes": [{"target": "", "via": null}], "v4AssignMode": "zt", "private": true }'

Authorize a member#

curl -X POST "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" -H "X-ZT1-AUTH: ${TOKEN}" -d '{"authorized": true}'

Network Info Again#

curl "http://localhost:9993/controller/network/${NWID}/" -H "X-ZT1-AUTH: ${TOKEN}"

Member Info Again#

curl "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" -H "X-ZT1-AUTH: ${TOKEN}"

Confirm from your nodes#

sudo zerotier-cli listnetworks

It should say "OK PRIVATE" and have an IP address.

Deauthorize Member#

curl -X POST "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" -H "X-ZT1-AUTH: ${TOKEN}" -d '{"authorized": false}'

Delete Member#

curl -X DELETE "http://localhost:9993/controller/network/${NWID}/member/${MEMID}" -H "X-ZT1-AUTH: ${TOKEN}"

You can "delete" a member, but they will show up in the output of "list member" again if the node is still online and trying to join. You should make sure to deauthorize before deleting.

Backup your controller#

If you want to keep these networks, copy the ZeroTier Home directory somewhere. Most importantly, the identity.secret and the controller.d directory.

Clean up networks#

You may want to delete these networks now that you're done testing. You could use the API to delete every network.

Or you can delete the controller.d directory.

stop zerotier (If you're ssh'd in over zerotier, this will break your connection):

systemctl stop zerotier-one

delete controller configs:

cd /var/lib/zerotier-one/
# rm -rf ./controller.d/

start zerotier:

systemctl start zerotier-one