Reserved GPU nodes (Compute API)
Read-only access to your account's GPU reservations: what is reserved, which workloads run on which node, how much of the storage quota is used and — for the account owner — the payment schedule. Reservations are set up by EcoLink; there are no write endpoints.
Prerequisites and the shared rules (auth, rate limits, errors) are on the overview. A key with Read-only Compute access is enough for every call here.
Endpoints
| Method | Path | What it does |
|---|---|---|
GET | /gpu-reservations | Your reservations, newest first |
GET | /gpu-reservations/{id} | One reservation: terms, storage, amendments and (owner only) payments |
GET | /gpu-reservations/{id}/nodes | Its nodes and the workloads on each, read live |
An account can hold more than one reservation — one per region, and a renewal is a new reservation — so list first and use the id.
Quick run
KEY="eco_YOUR_KEY"; API="https://api.ecohash.com"
curl -s $API/gpu-reservations -H "Authorization: Bearer $KEY" # note "id"
curl -s $API/gpu-reservations/<id> -H "Authorization: Bearer $KEY" # terms, storage, payments
curl -s $API/gpu-reservations/<id>/nodes -H "Authorization: Bearer $KEY" # nodes and workloads
GET /gpu-reservations
[
{
"id": 12,
"status": "active",
"region_id": "atl",
"gpu_type": "NVIDIA-RTX-PRO-6000-Blackwell-Server-Edition",
"node_count": 4,
"gpus_per_node": 8,
"reserved_gpus": 32,
"term_months": 12,
"billing_period": "monthly",
"starts_at": "2026-11-01T00:00:00Z",
"ends_at": "2027-11-01T00:00:00Z",
"drive_quota_gib": 5000,
"fs_quota_gib": 20000,
"contract_ref": "MSA-2026-014"
}
]
| Field | Notes |
|---|---|
status | assigning and scheduled (being set up), awaiting_payment (starts when its first invoice is paid; starts_at and ends_at are null until then), active, past_due (new launches paused), suspended (workloads stopped), ended |
billing_period | monthly or quarterly |
drive_quota_gib, fs_quota_gib | Cloud-drive and shared-filesystem storage included, in GiB |
past_due_since, stops_at | Present while past_due: when the payment became overdue, and when running workloads will be stopped unless it is paid |
ended_at | Present once ended |
GET /gpu-reservations/{id}
The list fields, plus:
{
"id": 12,
"status": "active",
"storage": { "drive_used_gib": 1200, "drive_quota_gib": 5000, "fs_used_gib": 8000, "fs_quota_gib": 20000 },
"amendments": [
{
"effective_at": "2027-02-01T00:00:00Z",
"node_count_before": 4, "node_count_after": 6,
"drive_quota_gib_before": 5000, "drive_quota_gib_after": 5000,
"fs_quota_gib_before": 20000, "fs_quota_gib_after": 30000,
"rate_usd_per_gpu_hour_before": 1.25, "rate_usd_per_gpu_hour_after": 1.25
}
],
"payment": {
"rate_usd_per_gpu_hour": 1.25,
"drive_rate_usd_per_gib_month": 0,
"fs_rate_usd_per_gib_month": 0,
"funding": "invoice",
"advance_usd": 29200,
"advance_remaining_usd": 29200,
"next_charge": {
"period_index": 1, "adjustment": false,
"period_start": "2026-12-01T00:00:00Z", "period_end": "2027-01-01T00:00:00Z",
"gpu_amount_usd": 29760, "storage_amount_usd": 0, "amount_usd": 29760,
"advance_applied_usd": 0, "status": "scheduled"
},
"charges": [ "… every period, same shape as next_charge …" ]
}
}
paymentis present only for the account owner. For other members (and their API keys) it is omitted, and amendments carry no rates.funding:wallet(each period is taken from the account's credit when it starts) orinvoice(each period is invoiced; pay it under Billing → Invoices).charges[].status:scheduled,invoiced,paid,covered_by_advance,past_due,waived.adjustment: truemarks a prorated charge from an amendment within a period.due_atandpaid_atappear when they apply.next_chargeis the earliest charge not yet paid, ornull.first_invoiceis present when the reservation starts with a first invoice (the advance plus period 1):{ "amount_usd": 2.34, "due_at": "…", "paid_at": "…", "issued": true }. Whilestatusisawaiting_paymentit is unpaid andchargesis empty — the schedule is laid out from the payment.issued: falsemeans it is still being created; pay it under Billing → Invoices.
GET /gpu-reservations/{id}/nodes
{
"nodes": [
{
"display_name": "node-1",
"state": "ready",
"gpus": 8,
"gpus_in_use": 6,
"workloads": [
{ "kind": "gpu_cluster", "id": 418, "name": "train-run-7", "gpus": 4 },
{ "kind": "gpu_instance", "id": 902, "name": "notebook", "gpus": 2 }
]
},
{ "display_name": "node-2", "state": "under_maintenance", "gpus": 8, "gpus_in_use": 0, "workloads": [] }
],
"workloads_unknown": false
}
state:ready,preparing(being made ready; GPUs available shortly) orunder_maintenance(being repaired or replaced; the capacity is kept on a replacement).workloads[].kind:gpu_instance,gpu_cluster,inference_instance(a model instance) orfine_tune(a fine-tuning job). Theidis the one the matching endpoint and console page use. A cluster with several replicas on one node is listed once, with their GPUs added up.- This call reads the region live. If the region cannot be reached, nodes are still returned and
workloads_unknownistrue, without GPUs in use or workloads. Poll it every few seconds at most; it is the one to poll for workload placement.
The billing field on workloads
GPU instances, GPU clusters, model instances and fine-tuning jobs that run on your reservation carry "billing": "reserved" in their API responses. Their hourly rate is 0 and no credit is held for them. The field is absent for workloads billed by the hour.
Errors when launching on a reservation
While your account has a reservation, launches and storage requests answer with these code values in addition to the overview's errors:
| Status | code | Meaning |
|---|---|---|
403 | reservation_only | The region or GPU type asked for is not in your reservation. The error text names where your reservation is |
402 | reservation_payment_due | A reservation payment is overdue; new launches are paused until it is paid |
402 | reservation_awaiting_payment | The reservation starts when its first invoice is paid; launches and new storage there wait until then |
409 | gpu_capacity | No free GPUs in your reservation for this launch, or no single node has enough free GPUs together |
409 | reservation_storage_quota | The drive or filesystem would exceed the storage included in your reservation |
409 | — | interruptible was requested; reserved capacity is never interruptible — omit the field |
Related
- Reserved GPU nodes — how reservations behave in the console
- Compute API overview