Volt API Reference
Deploy and manage confidential Intel TDX GPU pods, SSH keys, templates, and Docker credentials through a single REST API. Memory is encrypted on every confidential tier; tenant-side attestation is generated by you on the Confidential VM tier. Standard GPUs (no enclave, for data that is not sensitive) deploy through the same API and the same balance.
Quick Start
Everything you need to make your first API call in under a minute.
Base URL & Authentication
All Volt API endpoints live under a single base URL. Every request must include your API key in the X-API-Key header.
Base URL
https://api.voltagegpu.com/api/voltAuthentication Header
X-API-Key: volt_xxxExample: List Your Pods
curl -X GET \
https://api.voltagegpu.com/api/volt/pods \
-H "X-API-Key: volt_xxx"Response Format
All responses are JSON. Successful requests return 2xx status codes. Errors include a message field describing what went wrong.
Authentication
Secure API key authentication with scoped permissions and rate limiting.
API Key Setup
Generate an API key from the VoltageGPU dashboard. Navigate to Dashboard → API Keys → Generate. Your key is shown once, store it securely.
Header Format
X-API-Key: <your-key>Rate Limits
Each endpoint accepts up to 10 requests per 10 seconds from one client IP. Beyond that it returns 429 Too Many Requests with a Retry-After header in seconds. When you poll a pod, one request every 10 to 15 seconds is enough.
Key Permissions
Each API key has access to the following resource scopes:
- pods, Create, read, stop and delete Confidential VMs and standard pods
- templates, List the curated templates
- ssh-keys, Add and remove SSH public keys
- docker-credentials, Store private registry credentials
- machines, Browse confidential and standard GPU inventory with live pricing
- balance, Read your balance and running pod count
Keep Your Key Secret
Never expose your API key in client-side code, public repositories, or logs. If compromised, revoke it immediately from the dashboard and generate a new one.
Confidential Pods API
Deploy and manage Intel TDX confidential GPU pods with encrypted memory and hardware attestation.
List & Manage Confidential Pods
/api/volt/podsList your running pods: Confidential VMs first, then standard pods. Every entry carries provider ("confidential" or "standard") and confidential_compute.
curl -X GET \
https://api.voltagegpu.com/api/volt/pods \
-H "X-API-Key: volt_xxx"// Response 200, array of pods (a confidential entry shown)
[
{
"id": "wl_01h...",
"name": "cm_01h...",
"status": "RUNNING",
"gpu_type": "Confidential GPU",
"gpu_count": 1,
"hourly_price": 3.60,
"created_at": "2026-03-15T10:30:00Z",
"updated_at": "2026-03-15T10:31:12Z",
"ssh_host": "ssh.voltagegpu.com",
"provider": "confidential",
"confidential_compute": true
}
]/api/volt/podsCreate a Confidential VM (Intel TDX, full Ubuntu 24.04 guest, NVIDIA driver and CUDA preinstalled). Always pass provider: "confidential", a name and a resource_name from GET /api/volt/machines. Your balance is debited one hour upfront at deploy. With provider: "standard" the same endpoint deploys a standard pod: see Standard Pods. A request without provider is refused with 400.
curl -X POST \
https://api.voltagegpu.com/api/volt/pods \
-H "X-API-Key: volt_xxx" \
-H "Content-Type: application/json" \
-d '{
"provider": "confidential",
"name": "my-confidential-vm",
"resource_name": "rtx6000b-small",
"ssh_key_uids": ["key_abc123"],
"hardstop_hours": 4
}'// Response 200
{
"success": true,
"podId": "cm_01h...",
"workloadUid": "wrk-...",
"resourceName": "rtx6000b-small",
"hourlyPrice": 3.80,
"sudoPassword": "shown once, we keep no copy",
"hardStopAt": "2026-10-01T18:00:00.000Z",
"message": "Booting. SSH details appear on the pod page in about two minutes."
}Required fields, SSH & billing
provider, name and resource_name are required. Pricing is resolved server-side; any cost_per_hour in the body is ignored. If ssh_key_uids is omitted, one of your existing SSH keys is used. After about two minutes GET /api/volt/pods returns ssh_ready: true and an ssh_command of the form ssh -p PORT ubuntu@HOST. Stopping a VM destroys it and erases its disk.
What changed in October 2026
Our confidential provider retired container tiers, standalone volumes and container templates. template_uid and image are no longer used. Since 8 October 2026, standard (non-confidential) GPUs also deploy through this endpoint, with provider: "standard" and a machine_id: see Standard Pods.
/api/volt/pods/:idGet full details for a specific pod including IP, ports, and resource usage
curl -X GET \
https://api.voltagegpu.com/api/volt/pods/pod_def456 \
-H "X-API-Key: volt_xxx"// Response 200, confidential workload details
{
"uid": "wl_01h...",
"name": "my-confidential-pod",
"resource_name": "h200-small",
"image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-devel",
"type": "rental",
"status": "RUNNING",
"created_at": "2026-03-28T14:00:00Z"
}Connecting over SSH
Confidential pods are reached through the SSH gateway. Use the command returned at creation: ssh <workload_uid>@ssh.voltagegpu.com. No separate IP or port is exposed.
/api/volt/pods/:id/stopRelease a confidential pod. For Intel TDX pods this destroys the enclave and is equivalent to DELETE /api/volt/pods/:id. Confidential pods cannot be paused and resumed.
curl -X POST \
https://api.voltagegpu.com/api/volt/pods/pod_def456/stop \
-H "X-API-Key: volt_xxx"// Response 200
{
"success": true
}/api/volt/pods/:idPermanently destroy a confidential pod and its enclave. This action cannot be undone.
curl -X DELETE \
https://api.voltagegpu.com/api/volt/pods/wl_01h... \
-H "X-API-Key: volt_xxx"// Response 200
{
"success": true
}Deletion is Permanent
Destroying a confidential pod tears down the Intel TDX enclave. Everything inside the enclave memory and local filesystem is unrecoverable by design, that is the point of hardware-sealed compute. Push any outputs to external storage before deleting.
Confidential VMs
Full virtual machines inside an Intel TDX trust domain, with a dedicated GPU and root access. Unlike the container tier, a Confidential VM exposes /dev/tdx_guest, so you can pull a TDX quote and a NVIDIA GPU attestation report yourself from inside.
Deploy and manage Confidential VMs
Register your SSH key before you deploy
A Confidential VM binds its SSH key at creation and cannot be given one afterwards, so a deploy call from an account with no registered key is refused with needsSshKey. Call POST /api/volt/ssh-keys first. That call accepts an API key like every other, so the whole sequence is scriptable.
/api/confidential/vm/tiersLive Confidential VM inventory with your selling price and how many machines are free right now. Prices are computed server side, never sent by the client.
curl -H "X-API-Key: $VOLT_API_KEY" \
https://api.voltagegpu.com/api/confidential/vm/tiers{
"tiers": [
{
"resourceName": "rtx6000b-small",
"displayName": "NVIDIA RTX Pro 6000B - Small",
"gpuType": "RTX6000B",
"gpuCount": 1,
"vcpu": 32,
"memoryGb": 128,
"pricePerHour": 3.8,
"available": 10,
"gpuAttestation": true,
"attestation": {
"verified": true,
"verifiedOn": "2026-09-17",
"evidenceUrl": "https://voltagegpu.com/blog/two-proofs/evidence/rtx6000b-2026-09-17/README.txt",
"generatedBy": "tenant, inside the VM, on a nonce the tenant chooses",
"verifyInsideTheVm": ["curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --user --break-system-packages", "..."],
"index": "https://voltagegpu.com/api/attestation/evidence"
}
}
]
}gpuAttestation is true only on the SKUs where we have actually run the NVIDIA attestation from inside the VM and kept the report. It is not a marketing flag, and it reads false on hardware we have not tested. The attestation block says when, links the published evidence, and lists the exact commands to reproduce both proofs inside the VM (the image ships without pip, which is why the list starts with get-pip). The same list, per SKU and without any key, is served by GET /api/attestation/evidence.
/api/confidential/vm/deployStart a Confidential VM. One hour is charged upfront and the unused part is returned to your balance per second when you stop it, so a short test costs cents.
curl -X POST \
-H "X-API-Key: $VOLT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-vm",
"resource_name": "h100-small",
"hardstop_hours": 4,
"ports": [{"port": 8080, "protocol": "tcp"}]
}' \
https://api.voltagegpu.com/api/confidential/vm/deployports is optional and opens inbound TCP or UDP ports on the VM, up to eight of them, in the range 1 to 65535. Port 22 is rejected because SSH is already mapped for you. The response has no address yet, the VM is still being provisioned: poll GET /api/volt/pods below for it.
{
"success": true,
"podId": "cmu5i01bz001vl9042ag1ps0w",
"workloadUid": "wrk-xhnrun04sbj8",
"resourceName": "rtx6000b-small",
"hourlyPrice": 3.8,
"sudoPassword": "shown once, never again",
"hardStopAt": "2026-09-17T13:20:45.887Z",
"hardStopRequested": true,
"ports": [],
"attestation": { "verified": true, "verifiedOn": "2026-09-17", "...": "same block as the tier" },
"message": "Confidential VM is starting"
}One hour at hourlyPrice is debited when this call returns. Use podId to stop the VM and workloadUid to find it in the listing.
/api/volt/podsA bare JSON array of your running Confidential pods. Poll it every 15 seconds after a deploy: a VM shows provider_status "provisioning" until it has an address, then "running" with ssh_ready true. VMs are reached directly as user ubuntu on their own host and port, not through the container gateway. Measured on 17 September 2026: 15 seconds to an address, 19 seconds more for both proofs.
[
{
"id": "wrk-xhnrun04sbj8",
"name": "wrk-xhnrun04sbj8",
"status": "RUNNING",
"provider_status": "running",
"resource_name": "rtx6000b-small",
"hourly_price": 3.8,
"ssh_ready": true,
"ssh_host": "157.254.50.65",
"ssh_port": 20000,
"ssh_user": "ubuntu",
"ssh_command": "ssh -p 20000 ubuntu@157.254.50.65",
"provider": "confidential",
"confidential_compute": true
}
]Generate the two proofs inside the VM, then verify them outside
Both proofs are produced by you, inside the VM, on a challenge you choose. VoltageGPU is not in the trust chain. The image ships without pip, hence the first line.
ssh -p 20000 ubuntu@157.254.50.65
curl -sS https://bootstrap.pypa.io/get-pip.py | python3 - --user --break-system-packages
python3 -m pip install --user --break-system-packages "voltage-verify[attest]>=0.2.1"
export PATH=$HOME/.local/bin:$PATH
voltage-verify manifest --challenge auto -o manifest.json # prints your challenge, keep it
sudo env PATH=$PATH PYTHONPATH=$(python3 -c 'import site;print(site.getusersitepackages())') \
voltage-verify attest --manifest manifest.json --mode single-gpu -o bundle.json
voltage-verify verify bundle.json --challenge <your challenge> # RESULT: VERIFIEDThe verification that counts is the one you run on your own machine, on the copied bundle, with the challenge you issued. A replayed bundle answers NOT VERIFIED.
scp -P 20000 ubuntu@157.254.50.65:bundle.json .
pip install "voltage-verify>=0.2.1"
voltage-verify verify bundle.json --challenge <your challenge> --hwmodel GB20X --gpus 1
voltage-verify verify bundle.json --challenge <your challenge> --offline # no network at allReference run, by API key alone, with the bundle anyone can re-verify: voltagegpu.com/blog/two-proofs/evidence/rtx6000b-api-2026-09-17/README.txt
/api/volt/pods/:id/stopPass the podId from the deploy response. Billing is per second: the unused part of the prepaid hour comes back to your balance in the same call (prepaidRefund). Documented in full above.
/api/attestation/evidencePublic, no key. Which SKUs have a published tenant-side attestation, on what date, the evidence URLs, what is not attested and why (8x H200, B200, B300, the NVSwitch fabric), and the reproduce commands. Read it before you pay.
Standard Pods
GPUs without an enclave, for work whose data is not sensitive: public datasets, benchmarks, rendering, experiments. No memory encryption, no TDX quote, no GPU attestation. Same API key, same balance and same endpoints as the confidential tier.
Deploy a standard pod by API
Four calls: list the machines, pick a template (optional), make sure an SSH key is registered, deploy. Then poll the pod until it has an SSH command, and release it when you are done.
/api/volt/machines?provider=standardMachines you can deploy right now, cheapest first. Only machines whose GPUs are all free are listed: a standard machine is rented whole. The list is refreshed at most once a minute.
curl -H "X-API-Key: volt_xxx" \
"https://api.voltagegpu.com/api/volt/machines?provider=standard"// Response 200, array of machines
[
{
"machine_id": "<machine_id>",
"name": "2x NVIDIA RTX A5000",
"provider": "standard",
"confidential_compute": false,
"gpu_type": "NVIDIA RTX A5000",
"gpu_count": 2,
"gpu_memory_gb": 24,
"price_per_hour": 0.64,
"price_per_gpu_hour": 0.32,
"price": 0.64,
"available": true,
"available_gpu_count": 2,
"location": { "city": "<city>", "country": "<country>", "country_code": "<CC>" },
"cpu_cores": 112,
"ram_gb": 125,
"disk_gb": 218,
"max_cuda_version": "13"
}
]price_per_hour is what one hour of the whole machine costs, markup included: it is the amount charged at deploy and the hourly rate billed afterwards. price_per_gpu_hour is the per-GPU price shown on the pricing page; because of rounding, it can differ by a cent from price_per_hour divided by gpu_count. Use ?provider=all to get confidential and standard machines in one array.
/api/volt/templates?provider=standardThe curated environments a standard pod can start from. Only these ids are accepted as template_id. The entry with default: true is used when you omit it.
// Response 200
{
"success": true,
"items": [
{
"id": "<template_id>",
"name": "PyTorch 2.12 · CUDA 13",
"description": "Official PyTorch 2.12 with CUDA 13 and a built-in Docker daemon. ...",
"category": "PyTorch",
"provider": "standard",
"default": true
},
{ "id": "...", "name": "PyTorch 2.11 · CUDA 12.8", "default": false, "...": "..." },
{ "id": "...", "name": "CUDA 13 (full toolkit)", "default": false, "...": "..." }
]
}SSH key
The pod is reached over SSH with a key registered on your account. If you have none, register one with POST /api/volt/ssh-keys (see SSH Keys). If you have exactly one, the deploy uses it. If you have several, pass ssh_key_id from GET /api/volt/ssh-keys. As in the dashboard, a VoltageGPU service key is also added to the pod so the web terminal works.
/api/volt/podsDeploy a standard pod on one machine. The price is read server-side from the live machine list; a price sent in the body is refused.
curl -X POST https://api.voltagegpu.com/api/volt/pods \
-H "X-API-Key: volt_xxx" \
-H "Content-Type: application/json" \
-d '{
"provider": "standard",
"name": "my-training-run",
"machine_id": "<machine_id>",
"template_id": "<template_id>",
"auto_terminate_hours": 6
}'| Field | Type | Description |
|---|---|---|
| provider | string required | "standard". There is no default: without it the call is refused with 400. "confidential" deploys a Confidential VM instead. |
| name | string required | Lowercase letters, digits and hyphens, at most 40 characters, starting with a letter or a digit. |
| machine_id | string required | From GET /api/volt/machines?provider=standard. |
| template_id | string optional | From GET /api/volt/templates?provider=standard. Default: the entry marked default. |
| ssh_key_id | string optional | From GET /api/volt/ssh-keys. Required only when your account has more than one key. |
| gpu_count | integer optional | Machines are rented whole. If you send it, it must equal the machine's gpu_count, otherwise the call is refused before anything is charged. |
| jupyter | boolean optional | Start a Jupyter server in the pod. Default false. |
| port_count | integer optional | Number of exposed ports, 1 to 31. Default 6. |
| auto_terminate_hours | integer optional | Release the pod automatically after this many hours, 1 to 720. |
| image | string optional | Your own Docker image instead of a template, for example nvidia/cuda:12.4.1-base-ubuntu22.04. Public, linux/amd64. Not with template_id. Port 22 (SSH) is always exposed. An image that cannot be prepared answers 400 and nothing is charged. |
| start_command | string optional | Run when the container starts. Needs image. Keep it to one simple command (for example python serve.py --port 8000): shell chaining such as && or ; can be refused, in which case the answer is 400 with reason: settings_refused and nothing is charged. For a multi-step start, bake it into the image. |
| ports | integer[] optional | Container ports to expose besides SSH, up to 16. Needs image. port_count, if sent, must be at least one more than this list. |
| env | object optional | Environment variables, up to 32, string values. Needs image. We never log or store the start command or the variables: they go to our provider in a private template, reused for your identical deploys and deleted after 7 days without use. |
// Your own image, command, port and variables
curl -X POST https://api.voltagegpu.com/api/volt/pods \
-H "X-API-Key: volt_xxx" -H "Content-Type: application/json" \
-d '{
"provider": "standard",
"name": "vllm-server",
"machine_id": "<machine_id>",
"image": "vllm/vllm-openai:latest",
"start_command": "vllm serve Qwen/Qwen2.5-7B-Instruct --port 8000",
"ports": [8000],
"env": { "HF_TOKEN": "hf_xxx" }
}'// Response 201
{
"success": true,
"pod": {
"id": "<pod_id>",
"name": "my-training-run",
"machine_id": "<machine_id>",
"template_id": "<template_id>",
"gpu_type": "NVIDIA RTX A5000",
"gpu_count": 2,
"hourly_price": 0.64,
"prepaid_amount": 0.64,
"status": "RUNNING",
"provider": "standard",
"confidential_compute": false,
"ssh_command": null
},
"message": "Deployment started. One hour ($0.64) was charged from your balance; ..."
}Billing
Billing is per second, from your prepaid balance. When the deploy call succeeds, one hour at hourly_price is charged; per-second billing starts once that hour has run. Releasing the pod within the first hour refunds the unused seconds. A deploy that fails is not charged, and a pod that the provider never manages to start gets the full prepaid hour back. If your balance reaches zero, running pods are stopped.
Errors
Every error has the shape {"success": false, "error": "...", "status_code": 402, "timestamp": "..."}. The error text says what to call next. Refusals from the deploy step itself also carry "charged": false.
| Status | When |
|---|---|
400 | Invalid body (missing provider, missing or malformed field, unknown field, a price in the body), unknown template_id, no SSH key on the account, several keys and no ssh_key_id, gpu_count different from the machine. |
401 | Missing or invalid X-API-Key. |
402 | Balance below one hour of the machine (the body gives required and balance), or below $0.10, the lowest price of any machine. |
404 | Machine not found or no longer available, or SSH key not found on your account. |
409 | The machine cannot be rented whole right now (taken in the meantime, partly rented, not enough disk), or a deploy of yours on this machine is already in progress. Pick another one. |
429 | Rate limit, see Retry-After. |
502 | The machine's price and availability could not be checked, or our provider refused or did not answer. Nothing was charged ("charged": false). One case differs: when our provider did not answer and we cannot tell whether the pod started, the body says so with "charged": true. The hour stays held, and if no pod started it is returned to your balance automatically within two hours. |
503 | Templates or the machine list are temporarily unavailable, or a temporary infrastructure issue. Nothing was charged. |
/api/volt/pods/:idPoll with the id from the deploy response, every 10 to 15 seconds, until ssh_command is set. The pod also appears in GET /api/volt/pods and in the dashboard. Values below are illustrative.
// Response 200
{
"id": "<pod_id>",
"name": "my-training-run",
"status": "RUNNING",
"gpu_type": "NVIDIA RTX A5000",
"gpu_count": 2,
"hourly_price": 0.64,
"ssh_command": "ssh root@<host> -p <port>",
"provider": "standard",
"confidential_compute": false
}/api/volt/pods/:idRelease the pod. Billing stops and, within the first hour, the unused seconds of the prepaid hour are returned to your balance (prepaidRefund). Releasing deletes the pod, including its local disk. Standard pods cannot be paused: POST /api/volt/pods/:id/stop answers 501 for them, and a running pod cannot be edited: PUT /api/volt/pods/:id answers 405. A release sent while the deploy is still in progress answers 409; retry a minute later.
curl -X DELETE -H "X-API-Key: volt_xxx" \
https://api.voltagegpu.com/api/volt/pods/<pod_id>// Response 200
{
"success": true,
"prepaidRefund": 0.4917
}Machines
Query available confidential Intel TDX GPU inventory with live pricing and hardware specs.
Available Confidential Machines
/api/volt/machinesList the available Confidential VM tiers with live pricing and availability. Add ?provider=standard for standard machines (see Standard Pods) or ?provider=all for both.
curl -X GET \
https://api.voltagegpu.com/api/volt/machines \
-H "X-API-Key: volt_xxx"// Response 200, confidential machines entries
[
{
"name": "H200 [Confidential]",
"price": 3.60,
"rental_rate": 3.60,
"p_min": 2.40,
"p_max": 3.60,
"base_price": 2.40,
"total_gpu_count": 8,
"k": 1,
"provider": "confidential",
"resource_name": "h200-small",
"gpu_type": "H200",
"gpu_count": 1,
"vcpu": 32,
"memory": 256,
"confidential_compute": true
}
]Live inventory & resource_name
The resource_name field is what you pass to POST /api/volt/pods with provider: "confidential". price is the final hourly price; no upstream cost is returned, and the server never uses a price sent by the client. Only entries flagged confidential_compute: true are eligible for confidential deploys.
SSH Keys
Manage SSH public keys used for secure shell access to your GPU pods.
SSH Key Management
/api/volt/ssh-keysList the SSH public keys of your account, newest first. The id is the ssh_key_id a standard pod deploy accepts.
curl -X GET \
https://api.voltagegpu.com/api/volt/ssh-keys \
-H "X-API-Key: volt_xxx"// Response 200, array of keys
[
{
"id": "cmg1x2y3z0001abcd",
"name": "work-laptop",
"publicKey": "ssh-ed25519 AAAAC3Nz...truncated",
"createdAt": "2026-01-10T08:00:00.000Z"
}
]/api/volt/ssh-keysAdd a new SSH public key to your account
curl -X POST \
https://api.voltagegpu.com/api/volt/ssh-keys \
-H "X-API-Key: volt_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-server",
"public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG..."
}'// Response 201
{
"id": "cmg1x2y3z0002efgh",
"name": "ci-server",
"publicKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG...",
"createdAt": "2026-03-28T15:00:00.000Z"
}/api/volt/ssh-keys/:idRemove an SSH key from your account. Running pods keep existing authorized keys until redeployed.
curl -X DELETE \
https://api.voltagegpu.com/api/volt/ssh-keys/cmg1x2y3z0002efgh \
-H "X-API-Key: volt_xxx"// Response 200
{
"success": true
}Balance
The balance every deploy is charged against, and how many pods are running.
/api/volt/balanceRead-only. A deploy charges the first hour up front, so check that the balance covers it before a scripted deploy. Four decimals, because billing is per second.
curl https://api.voltagegpu.com/api/volt/balance \
-H "X-API-Key: $VOLT_API_KEY"// Response 200
{
"success": true,
"balance": 11.0314,
"currency": "USD",
"active_pods": 0,
"top_up_url": "https://voltagegpu.com/billing"
}Templates
Curated, read-only Confidential Compute templates maintained by the provider (Jupyter, Ubuntu, DeepSeek-R1, GLM-4.6, Kimi-K2, Qwen3-Coder, GPT-OSS-120B, MiniMax and more). Use a template_uid in POST /api/volt/pods to deploy a pod with a pre-configured image, resource, commands, args and exposed ports.
Template Catalog
/api/volt/templatesList all curated public templates (cached 2 minutes). For standard pods, call GET /api/volt/templates?provider=standard instead: its id values are the template_id a standard deploy accepts (see Standard Pods).
curl -X GET \
https://api.voltagegpu.com/api/volt/templates \
-H "X-API-Key: volt_xxx"// Response 200
{
"success": true,
"items": [
{
"uid": "tpl-5npuuq70m1uo",
"name": "DeepSeek-R1",
"description": "DeepSeek-R1 reasoning model (sglang, 8x H200)",
"type": "SERVERLESS",
"image": "lmsysorg/sglang:v0.5.5.post3",
"resource_name": "h200-xlarge",
"visibility": "PUBLIC"
},
{
"uid": "tpl-ibnkqwo0esy4",
"name": "Jupyter Notebook",
"description": "Base image for Jupyter Notebook stacks",
"type": "RENTAL",
"image": "jupyter/base-notebook",
"resource_name": "cpu-small",
"visibility": "PUBLIC"
}
]
}/api/volt/templates/:uidFetch a single template with the full manifest (commands, args, ports, env)
curl -X GET \
https://api.voltagegpu.com/api/volt/templates/tpl-5npuuq70m1uo \
-H "X-API-Key: volt_xxx"Curated, read-only
Templates are maintained by the upstream provider and cannot be created, updated or deleted via the API, POST, PUT and DELETE return 405 Method Not Allowed. To run a custom image, skip templates entirely and pass a raw image + resource_name to POST /api/volt/pods.
Docker Credentials
Store private Docker registry credentials so pods can pull custom images.
Registry Credentials
/api/volt/docker-credentialsList all stored Docker registry credentials (passwords are redacted)
curl -X GET \
https://api.voltagegpu.com/api/volt/docker-credentials \
-H "X-API-Key: volt_xxx"// Response 200
{
"credentials": [
{
"id": "cred_abc123",
"name": "GitHub Container Registry",
"registry": "ghcr.io",
"username": "my-org",
"created_at": "2026-02-15T12:00:00Z"
}
],
"total": 1
}/api/volt/docker-credentialsAdd credentials for a private Docker registry
curl -X POST \
https://api.voltagegpu.com/api/volt/docker-credentials \
-H "X-API-Key: volt_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "AWS ECR Production",
"registry": "123456789.dkr.ecr.us-east-1.amazonaws.com",
"username": "AWS",
"password": "eyJwYXlsb2FkIjoiNGZ..."
}'// Response 201
{
"id": "cred_def456",
"name": "AWS ECR Production",
"registry": "123456789.dkr.ecr.us-east-1.amazonaws.com",
"username": "AWS",
"created_at": "2026-03-28T16:30:00Z"
}/api/volt/docker-credentials/:idGet details for a specific credential (password is always redacted)
curl -X GET \
https://api.voltagegpu.com/api/volt/docker-credentials/cred_abc123 \
-H "X-API-Key: volt_xxx"// Response 200
{
"id": "cred_abc123",
"name": "GitHub Container Registry",
"registry": "ghcr.io",
"username": "my-org",
"created_at": "2026-02-15T12:00:00Z"
}/api/volt/docker-credentials/:idDelete a stored credential. Templates referencing it will fail to pull on next deploy.
curl -X DELETE \
https://api.voltagegpu.com/api/volt/docker-credentials/cred_def456 \
-H "X-API-Key: volt_xxx"// Response 200
{
"id": "cred_def456",
"deleted": true,
"message": "Docker credential removed."
}API Keys
Manage your Volt API keys. Unlike every other endpoint on this page, these three are authenticated by your dashboard session, not by an API key, so they are called from the browser rather than from a script. That is deliberate: a key cannot be used to mint or revoke keys. Sending X-API-Key here returns 401.
API Key Management
/api/volt/api-keysList all API keys for your account (key values are partially redacted)
# These three are session-authenticated: an API key is rejected.
curl -X GET \
https://voltagegpu.com/api/volt/api-keys \
-H "Cookie: next-auth.session-token=<your dashboard session cookie>"// Response 200
{
"success": true,
"keys": [
{
"id": "ak_001",
"name": "Production Key",
"keyPreview": "volt_...x7f2",
"createdAt": "2026-01-05T08:00:00Z"
}
]
}/api/volt/api-keysGenerate a new API key. The full key is returned only once in this response.
curl -X POST \
https://voltagegpu.com/api/volt/api-keys \
-H "Cookie: next-auth.session-token=<your dashboard session cookie>" \
-H "Content-Type: application/json" -d '{
"name": "CI/CD Pipeline"
}'// Response 201
{
"id": "ak_002",
"name": "CI/CD Pipeline",
"key": "volt_sk_live_a1b2c3d4e5f6g7h8i9j0...",
"created_at": "2026-03-28T17:00:00Z",
"message": "Store this key securely. It will not be shown again."
}Save Your Key Immediately
The full API key is only returned in the creation response. Store it in a secrets manager or environment variable. If lost, delete the key and create a new one.
/api/volt/api-keysRevoke an API key. The id goes in the id query parameter, not in the body. Takes effect immediately.
# Session-authenticated, like the other two below.
curl -X DELETE \
"https://voltagegpu.com/api/volt/api-keys?id=ak_002" -H "Cookie: next-auth.session-token=<your dashboard session cookie>"// Response 200
{
"id": "ak_002",
"deleted": true,
"message": "API key revoked. Any requests using this key will now return 401."
}Error Codes
Standard HTTP status codes returned by the Volt API with their meanings.
HTTP Status Reference
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request succeeded. Response body contains the requested data. |
| 201 | Created | Resource created successfully (pods, keys, templates, jobs). |
| 400 | Bad Request | Invalid request body or missing required fields. Check the message field for details. |
| 401 | Unauthorized | Missing or invalid API key. Ensure the X-API-Key header is set correctly. |
| 402 | Payment Required | Insufficient account balance to perform the action. Add funds via the billing page. |
| 404 | Not Found | The requested resource does not exist or does not belong to your account. |
| 429 | Too Many Requests | Rate limit exceeded (1,000 req/hour). Wait for the Retry-After period. |
| 500 | Internal Server Error | Unexpected server error. Retry with exponential backoff. Contact support if persistent. |
| 502 | Bad Gateway | Upstream provider temporarily unavailable. Retry after a few seconds. |
Error Response Format
// All errors follow this structure
{
"error": true,
"status": 401,
"message": "Invalid API key. Generate a new key at Dashboard > API Keys.",
"code": "INVALID_API_KEY"
}Retry Strategy
For 429, 500, and 502 errors, implement exponential backoff starting at 1 second with a maximum of 5 retries. The Retry-After header is included on rate-limited responses.
Ready to Build with the Volt API?
Generate your API key and deploy your first pod in under 60 seconds.