Configure access and networking
This page collects the work done before and after a VM exists: project SSH keys, a private network, internal addressing, a public IP and external access through port forwarding rules.
Register an SSH key in the project
If access is managed centrally, add keys to the project once and refer to their identifiers when creating VMs. The
maximum length of the name and of the key itself comes from GET /limits/name-lengths, and the number of
keys per project is capped by maxSshKeysPerProject in GET /limits.
curl --request POST \
--url 'https://api.zennohosting.com/v1/projects/{projectId}/ssh-keys' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"name": "workstation-key",
"publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..."
}'
Create a private network and attach a VM
Network first, attachment second. The subnet is assigned by the platform — you do not pass it at creation, you read the resulting value from the response.
curl --request POST \
--url 'https://api.zennohosting.com/v1/projects/{projectId}/networks' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"name": "backend-private"
}'
- 1
Add or pick a project SSH key
Shared project keys mean you do not repeat access parameters in every create request.
- 2
Create the network
Give the network a stable name and read the subnet from the response. Wait until its
statusisactivebefore attaching VMs. - 3
Attach the VM
Attachment is its own request. The update call is only needed when an attachment already exists and has to be reconfigured.
- 4
Get a public IP
External access is built around
publicIpId. Either allocate an address or pick an existing one from the project's list. - 5
Create port forwarding rules
A rule maps an external port and protocol to a VM inside the network. While the change is applied the rule's
statusisCreating; an active rule isCreated.
Allocate a public IP
If the project has no reusable address yet, allocate one separately. It is a resource of its own with its own tariff, not a side effect of creating a network.
curl --request POST \
--url 'https://api.zennohosting.com/v1/projects/{projectId}/public-ips' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"tariffId": "00000000-0000-0000-0000-000000000000"
}'
Create a port forwarding rule
A rule binds an external port of an existing project address to a chosen VM and its internal port.
curl --request POST \
--url 'https://api.zennohosting.com/v1/projects/{projectId}/public-ips/{publicIpId}/port-forwards' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"vmId": "00000000-0000-0000-0000-000000000000",
"mode": "SpecificPorts",
"protocol": "Tcp",
"externalPort": 8080,
"internalPort": 80
}'
Rules survive a VM rebuild
Rebuilding a VM leaves port forwarding rules untouched. If the new image listens on a different port — RDP 3389 instead of SSH 22, say — the rule stays as it was and stops working. Update it with a separate request.
Three independent areas
A dashboard may present access and networking together, but in the API these are three separate areas: project keys, private network attachment, and a public IP with its rules. They meet in the workflow, not in the data model.
Related endpoints
/projects/{projectId}/ssh-keysRegister an SSH key in the project.
/projects/{projectId}/networksCreate a private network.
/projects/{projectId}/networks/{networkId}/vmsAttach a VM to the network.
/projects/{projectId}/networks/{networkId}/vms/{vmId}Change attachment settings or the internal address.
/projects/{projectId}/public-ipsAllocate a project public IP.
/projects/{projectId}/public-ipsInspect the project's public IPs.
/projects/{projectId}/public-ips/{publicIpId}/port-forwardsCreate a port forwarding rule.
/projects/{projectId}/public-ips/{publicIpId}/port-forwards/{forwardId}Update a rule after the service port changes.