Skip to main content

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. 1

    Add or pick a project SSH key

    Shared project keys mean you do not repeat access parameters in every create request.

  2. 2

    Create the network

    Give the network a stable name and read the subnet from the response. Wait until its status is active before attaching VMs.

  3. 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. 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. 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 status is Creating; an active rule is Created.

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.