Guides
Ports and private URLs
Expose a machine's ports as HTTPS URLs, keep them private with short-lived tokens, or make them public.
Any TCP port in a running machine can be served at its own HTTPS address:
https://<label>-<port>.<edge domain>label is 12 random characters given to the machine the first time it exposes a port. It never changes and is never reused, even after the machine is deleted, so a URL can never reach a different machine. VMYard's edge terminates TLS and forwards to the machine; the machine is never reachable directly.
Expose a port
curl -X POST "$VMYARD_API_URL/v1/machines/$MACHINE_ID/ports" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"port": 8080}'| Field | Meaning |
|---|---|
port | 1–65535, except 22 (use an SSH key for SSH). |
public | true serves the URL to anyone. The default, false, requires a token. |
localhost | true also reaches a service that listens only on 127.0.0.1 or [::1] inside the machine. |
Exposing is an operation; the port is open once it succeeds. Exposing a port that is already open replaces its public and localhost settings. A machine can have up to 16 exposed ports (409 port_limit_reached).
List ports
curl "$VMYARD_API_URL/v1/machines/$MACHINE_ID/ports" \
-H "Authorization: Bearer $VMYARD_API_KEY"{
"label": "k7f2mq3x9a1b",
"items": [
{ "port": 8080, "public": false, "localhost": false, "url": "https://k7f2mq3x9a1b-8080.on.example.com" }
]
}The list shows ports as the machine's host last confirmed them. Any member and any API key preset can read it.
Open a private port
Private ports need a token. Ask for one, valid for 1 to 3,600 seconds (900 by default):
curl -X POST "$VMYARD_API_URL/v1/machines/$MACHINE_ID/ports/8080/token" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ttl_seconds": 900}'{
"url": "https://k7f2mq3x9a1b-8080.on.example.com",
"url_with_token": "https://k7f2mq3x9a1b-8080.on.example.com/?_token=v1.…",
"header_token": "v1.…",
"expires_at": "2026-10-12T06:06:01Z"
}- In a browser, open
url_with_token. The edge checks the token, sets a cookie scoped to that one host, and redirects tourlso the token leaves the address bar. - From code, send the token in a header:
curl https://k7f2mq3x9a1b-8080.on.example.com/health \
-H "X-Vmyard-Token: $HEADER_TOKEN"A token opens only the one machine and port it was issued for and stops working at expires_at. Missing credentials get 401 from the edge; invalid or expired ones get 403. VMYard doesn't store tokens; issuing one is recorded with its port and expiry. Asking for a token for a port that isn't exposed is 404 port_not_exposed.
What the edge forwards
- HTTP/1.1 requests, streamed responses (server-sent events, long polls), and WebSocket upgrades.
- The edge sets
X-Forwarded-For,X-Forwarded-Proto, andX-Forwarded-Host, and removes the token cookie and header before forwarding. - Idle connections close after 5 minutes without traffic by default.
Close a port
curl -X DELETE "$VMYARD_API_URL/v1/machines/$MACHINE_ID/ports/8080" \
-H "Authorization: Bearer $VMYARD_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Closing a port that isn't exposed makes the operation fail. Deleting a machine closes all of its ports.
Access
Exposing, closing, and issuing tokens need a running machine and Owner, Admin, or Operator access (or a use_existing key). Port changes that fail emit operation.failed; successful ones emit no webhook.