Providers
Bring your GPU hardware online as OpenRelay capacity with a single command and start earning.
Contribute GPU hardware to the OpenRelay network: customer workloads run on your boxes and you earn a share of the usage. Onboarding a node is one command.
Before you start
You need an org that has been approved as a provider and a host
running Ubuntu 22.04/24.04 with root access, curl, and outbound HTTPS. See
Provider nodes for the full hardware checklist.
Two node kinds, detected automatically
OpenRelay runs your hardware one of two ways, and the installer picks the right one by inspecting the box at enrollment. You do not choose or configure this: mint a token, run the command, and the node enrolls as whatever its hardware is.
VM node (qemu) | Pod node (runc) | |
|---|---|---|
| Detected when | The box is bare metal | The box is a cloud/virtualized VM guest |
| Serves | Customer VMs with full GPU passthrough | Inference pods (containers) |
| GPU access | GPUs are rebound to vfio-pci (host driver is torn down) | Keeps the host NVIDIA driver (nvidia-smi must work) |
Needs /dev/kvm | Yes | No |
| Needs IOMMU / VT-d | Yes | No |
| Unit of allocation | The IOMMU group | One unit per GPU |
| Health check | vectorlay-node-doctor | vectorlay-pod-node-preflight |
A pod node is not a VM node
The two are mutually exclusive on the same box: a VM node's GPUs are bound to
vfio-pci and are invisible to the NVIDIA driver, while a pod node keeps the
driver and never touches VFIO. Running vectorlay-node-doctor on a pod node
reports no /dev/kvm as a hard failure — that is expected and is not a
problem with the node. Use the pod preflight instead.
Become a provider
Apply from the dashboard (or POST /v1/orgs/{orgId}/provider/apply).
Once your application is approved, your organization is cleared to run provider nodes.
Check your provider status any time with GET /v1/orgs/{orgId}/provider/status.
Mint a provisioning token
The same token works for either node kind: the box decides which it becomes.
In the dashboard go to Nodes → Add Node. It
generates a ready-to-paste command with a provisioning token (vtk_…) baked
in:
curl -fsSL "https://api.openrelay.inc/v1/provider/bootstrap?token=vtk_…" | sudo bashThe token self-authenticates the request, so no API key is needed on the node. It is shown once, lives 24 hours, and enrolls any number of nodes in that window, so one token can drive a cloud-init or Ansible rollout across a rack. Revoke it from the same page to stop it early.
Run it on the box
The installer detects the box's shape, stages the agents (sha256-verified), enrolls the node, and brings it online in your pool automatically. Re-running the exact same command is always safe: enrollment is idempotent per box.
It also stages vectorlay-pod-node-preflight,
the pod-node health check. Run it any time with sudo vectorlay-pod-node-preflight
to see whether a box can sell pods (GPU catalog match, native driver, storage
mount).
Verify the node is online
Watch the Nodes tab in the dashboard (it updates live), or:
curl -fsSL -H "Authorization: Bearer $VL_KEY" \
https://api.openrelay.inc/v1/orgs/$VL_ORG/provider/nodes | jq '.[] | {hostname, status, runtime}'A healthy node shows as ready in its pool, and runtime confirms which kind of
node you actually enrolled. From then on it keeps itself up to date automatically.
Bootstrap options
Append these query params to the bootstrap URL:
| Param | Default | Meaning |
|---|---|---|
token | none | A pre-minted provisioning token (vtk_…); replaces the API-key header. The pool rides on the token; the node kind is detected on the box, not passed. |
gpu | none | Accepted for backward compatibility and ignored. The installer detects GPUs and the node kind itself, so it is not needed. |
name | none | Optional label for the minted token (bearer/mint path only). |
pool and nodeType are no longer bootstrap params
Earlier versions of this page documented pool and nodeType query params. They
were removed: every node enrolls as persistent in the community pool, and the
API ignores those params if you pass them. The pool lives on the token, and the
node kind is detected on the box.
Security
Neither credential persists on the node: the API key is used once in the request
header, and the provisioning token is not stored on the node (each enrolled node
receives its own durable identity instead). The token stays reusable until it
expires or is revoked; it is never written to disk. Installer responses are never cached
(Cache-Control: no-store, because the script embeds a secret), and every
artifact is sha256-pinned.
Managing nodes & tokens
- Mint provisioning tokens from the dashboard (Nodes → Add Node) or
POST /v1/orgs/{orgId}/provider/tokens. - List tokens:
GET /v1/orgs/{orgId}/provider/tokens. - Revoke one:
DELETE /v1/orgs/{orgId}/provider/tokens/{id}(the token id from the mint response or the list, not thevtk_secret). - List your provider nodes:
GET /v1/orgs/{orgId}/provider/nodes.
See the Providers endpoints in the API reference for full request/response shapes.
Earnings
You earn a share of the usage your hardware serves, settled monthly. Earnings and utilization are visible in the provider dashboard.
For the hardware checklist, GPU setup for both runtimes, the health checks, and how nodes behave across reboots, updates, recycling, and decommissioning, see Provider nodes.
Troubleshooting
| Symptom | Cause |
|---|---|
403 NOT_A_PROVIDER | The org isn't an approved provider yet. |
403 FORBIDDEN | The credential may not write to the org, so it may not mint a provisioning token. An API key needs clusters:write; a session needs to be a member or above. |
403 TOKEN_REVOKED | The provisioning token was revoked. Mint a new one. |
403 RUNTIME_HOST_MISMATCH | The box's shape and the runtime it enrolled as disagree (e.g. a converted VM host re-enrolling as a pod). The message names the fix; re-run the bootstrap. |
401 | Bad, missing, or expired API key / provisioning token. |
503 DISABLED | Node onboarding isn't configured on this environment. |
| Node enrolled as the wrong type | The node kind is detected from the hardware: bare metal becomes a VM host, a cloud guest becomes a pod node. Re-run the bootstrap and the installer re-detects. |
| Install didn't finish | Re-run the command — it's always safe to retry. |