List GPU catalog
curl https://gputw.ai/api/gpus/activeList available machines
curl -H "Authorization: Bearer $GPUTW_API_KEY" "https://gputw.ai/api/nodes/available?catalogId=<catalog-id>"Create an instance
curl -X POST https://gputw.ai/api/instances/create \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nodeId":"<node-id>","bandwidthMbps":100,"templateId":"<template-id>","ports":[8080]}'Deploy a public custom image
Pass customImage instead of templateId to launch any image from a public registry (Docker Hub, GHCR, …). The reference must carry an explicit non-latest tag or a sha256 digest. With sshEnabled you log in as root using your account SSH keys — they are injected automatically, and if the image lacks an SSH server one is installed at startup (requires the image to run as root with a package manager such as apk/apt/dnf). Alternatively declare a Web UI. Optional env injects environment variables; optional args replaces the image CMD (the ENTRYPOINT is preserved).
curl -X POST https://gputw.ai/api/instances/create \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nodeId":"<node-id>","bandwidthMbps":100,"customImage":{"dockerImage":"ghcr.io/acme/trainer:1.4.2","sshEnabled":true,"env":[{"name":"HF_TOKEN","value":"hf_xxx"}],"args":["--port","8080"]},"ports":[8080]}'Deploy a private custom image
Add registryAuth for a private registry. GPUtw turns it into a short-lived image-pull secret and deletes the stored credential when the instance stops, fails, or terminates. Set webUiEnabled with a webUiLabel and webUiPort to surface a browser UI.
curl -X POST https://gputw.ai/api/instances/create \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"nodeId":"<node-id>","bandwidthMbps":100,"customImage":{"dockerImage":"registry.example.com/team/app:2025-06-30","registryAuth":{"registry":"registry.example.com","username":"<user>","password":"<token>"},"webUiEnabled":true,"webUiLabel":"My App","webUiPort":8080}}'Custom-image deploys need the instances:create scope. Pull time counts toward billing, and customImage cannot be combined with templateId/template. Omit registryAuth for public images. env accepts up to 32 entries (names [A-Za-z_][A-Za-z0-9_]*; the platform-reserved PUBLIC_KEY, GATEWAY_KEY, NVIDIA_VISIBLE_DEVICES, NVIDIA_DRIVER_CAPABILITIES are rejected) and args up to 64 strings.
Stop an instance
curl -X POST https://gputw.ai/api/instances/stop \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"instanceId":"<instance-id>"}'Manage HTTP ports
curl -X PATCH https://gputw.ai/api/instances/<instance-id>/ports \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ports":[8080,18080],"portAccess":{"8080":{"mode":"unlisted","password":"strong-password"},"18080":{"mode":"public"}}}'Create a raw TCP exposure
Maps a container port to a platform-assigned public port on tcp.gputw.ai. The response returns the assigned endpoint.
curl -X POST https://gputw.ai/api/instances/<instance-id>/exposures \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"protocol":"tcp","containerPort":25565}'Create a raw UDP exposure
Set protocol to udp for datagram services (game servers, WireGuard, QUIC, …). It is assigned an independent public port on udp.gputw.ai — TCP and UDP port numbers are allocated separately, so the same number can appear on both.
curl -X POST https://gputw.ai/api/instances/<instance-id>/exposures \
-H "Authorization: Bearer $GPUTW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"protocol":"udp","containerPort":51820}'Raw TCP/UDP endpoints are unauthenticated L4 pass-through. Use a service that has its own auth, and never raw-expose an unauthenticated web UI. Delete an exposure with DELETE /api/instances/{id}/exposures/{exposureId}; it frees the public port for reuse.