TensorFusion API Reference
TensorFusion exposes three programmatic interfaces: the Kubernetes API (its CRDs), an HTTP API on the controller, and an HTTP API on each node's hypervisor. This page says what each is for and lists the HTTP endpoints. The TensorFusion Cloud console does not offer a public API yet; see the last section.
Which interface to use
| You want to | Use | Stability |
|---|---|---|
| Create or change pools, workloads, quotas, scheduling policy | Kubernetes API, group tensor-fusion.ai/v1. See the CRD reference. | Versioned API |
| Read metrics and logs | SQL against GreptimeDB. See the metrics reference. | Tables documented |
| Inspect scheduler state, or ask "why is this Pod not schedulable" | Controller HTTP API | Internal, may change between releases |
| Inspect devices and workers on one node | Hypervisor HTTP API | Internal, may change between releases |
Build integrations on the Kubernetes API. The two HTTP APIs exist for TensorFusion's own components and for troubleshooting. They have no version guarantee.
Controller HTTP API
The controller listens on port 8080 and is reachable through the controller Service in the TensorFusion namespace. To call it from your workstation:
kubectl -n tensor-fusion-sys get deploy # find the <release>-controller Deployment
kubectl -n tensor-fusion-sys port-forward deploy/<release>-controller 8080:8080
curl -s localhost:8080/api/allocation | jq '.gpuToWorkerMap'Endpoints used by TensorFusion components
These endpoints verify the caller's ServiceAccount token with a Kubernetes TokenReview. Send the token as Authorization: Bearer <token>.
| Method and path | Caller | Behavior |
|---|---|---|
GET /api/connection?name=<name>&namespace=<ns> | Client library in an application Pod | Returns the worker URL of a TensorFusionConnection as plain text. If the worker is not running yet, the request waits up to 5 minutes. The token must belong to the Pod that owns the connection. |
POST /api/assign-host-port?podName=<name> | Controller replicas | Returns a free port from -cluster-host-port-range as plain text. Answered by the leader only. |
GET /api/assign-index?podName=<name> | Controller replicas | Returns a device index for the Pod as plain text. Answered by the leader only. |
Status codes of GET /api/connection:
| Code | Meaning |
|---|---|
200 | Body is the connection URL. |
401 | Missing or invalid token, or the token's Pod does not own the connection. |
404 | No such TensorFusionConnection. |
503 | The controller stopped watching the connection; retry. |
504 | The worker did not become ready within 5 minutes. |
Diagnostic endpoints
| Method and path | Returns |
|---|---|
GET /api/allocation | The allocator's in-memory state as JSON: gpuStore (every GPU with capacity and availability), nodeWorkerStore, allocation (one entry per Pod with its requests, limits and GPUs) and gpuToWorkerMap (Pods per GPU). |
POST /api/simulate-schedule | Runs the scheduler's filter and score steps for a Pod without reserving or binding anything. Send the Pod manifest (YAML or JSON) as the request body. The response has scheduleResult, filterDetail (which GPUs each filter stage rejected and why) and, on failure, error with per-node diagnosis. |
GET /api/node-scaler | State of the node expander, including the nodes being provisioned and the GPUs expected on them. Returns 503 when the controller runs without -enable-auto-expander. |
GET /api/config | The dynamic config the controller currently uses. |
Example: find out why a Pod stays pending.
kubectl get pod <pod-name> -n <namespace> -o yaml > pod.yaml
curl -s -X POST --data-binary @pod.yaml localhost:8080/api/simulate-schedule | jq '.error, .filterDetail'The Pod's spec.schedulerName must name a scheduler profile the controller serves; otherwise the call returns 500 with scheduler framework not found.
The diagnostic endpoints rely on network isolation, not on per-request authentication, and their responses include cluster state such as Pod names, labels and annotations. The controller Service is of type ClusterIP; keep it that way, do not publish port 8080 through an Ingress or LoadBalancer, and restrict in-cluster access with a NetworkPolicy if tenants can run arbitrary Pods.
Hypervisor HTTP API
Each hypervisor listens on port 8001 on its node's host network. Change the port with componentConfig.hypervisor.portNumber in the GPUPool. Responses are JSON: {"data": ...} on success and {"error": "..."} on failure.
curl -s http://<node-ip>:8001/api/v1/devices | jq '.data[] | {UUID, Model, Healthy}'Health
| Method and path | Returns |
|---|---|
GET /healthz | {"status":"ok"} when the process is up. |
GET /readyz | {"status":"ready"} once the device and worker controllers are initialized, otherwise 503. |
Devices
| Method and path | Returns |
|---|---|
GET /api/v1/devices | All accelerators on the node: UUID, vendor, model, index, NUMA node, total memory, max TFLOPS, health. |
GET /api/v1/devices/:uuid | One device, or 404. |
POST /api/v1/devices/discover | Triggers device discovery immediately instead of waiting for -discovery-interval. |
Workers
| Method and path | Returns |
|---|---|
GET /api/v1/workers | Every worker on the node with its allocation: devices, injected environment variables and mounts. |
GET /api/v1/workers/:id | One worker by Pod UID, with per-device, per-process usage. 404 if the Pod has no allocation on this node. |
POST /api/v1/workers/:id/snapshot | Not implemented. Returns 501. |
POST /api/v1/workers/:id/resume | Not implemented. Returns 501. |
Limiter endpoints
These keep the request and response shapes of the earlier Rust hypervisor so that existing limiters and workers continue to work.
| Method and path | Caller | Behavior |
|---|---|---|
GET /api/v1/pod?container_name=<name> | Limiter or worker inside a Pod | Returns the Pod's GPU UUIDs, TFLOPS and VRAM limits, QoS level and isolation mode. Requires the Pod's ServiceAccount token as a Bearer token; the hypervisor verifies it with TokenReview and uses only the verified Pod UID. |
POST /api/v1/process?container_name=<name>&container_pid=<pid> | Limiter inside a Pod | Registers a GPU process and maps its container PID to the host PID. Same token check. |
GET /api/v1/pod (no token, no container_name) | Troubleshooting | Lists the Pods with GPU allocations on the node. |
GET /api/v1/limiter | Troubleshooting | Lists requests and limits per worker. |
POST /api/v1/trap | Limiter | Reports VRAM pressure. The response says how many low-QoS workers are candidates for a snapshot. |
Only the two token-checked calls authenticate the caller; the rest of the hypervisor API relies on network isolation. Because it listens on the node's network, allow port 8001 only from the node itself and the Pod network in your node firewall or security group.
TensorFusion Cloud console
The console at app.tensor-fusion.ai has no public, documented API today: there are no API keys, and its backend routes are tied to browser sessions and can change without notice. Everything the console shows comes from your cluster through the cluster agent, so the same data is available to you directly:
| Console area | Where to get it programmatically |
|---|---|
| Environments, pools, nodes, workloads | Kubernetes API, tensor-fusion.ai/v1 resources |
| Metrics and usage | GreptimeDB tables listed in the metrics reference |
| Billing and quotas | raw_cost in tf_worker_resources and tf_node_metrics; GPUResourceQuota resources |
Next steps
- CRD reference
- Security whitepaper for the authentication design behind these endpoints
TensorFusion Docs