GPU availability updates every minute
gpu.nz
ContentsFor developers

API reference

Every v1 endpoint: parameters, request and response examples, errors and the scopes they need. The same schema as /api/v1/openapi.json.

https://gpu.nz/api/v1JSON · UTF-8 · snake_case

Authentication and keys

Send the key on every private request in the header: Authorization: Bearer gpz_… A key is 44 characters: the gpz_ prefix and 40 letters and digits.

A key gives access to your account only. Browser sessions do not work with the API, on purpose.

Scopes: user:read and user:write cover the profile, SSH keys and API keys; instances:read and instances:write cover servers and your own templates; billing:read covers the balance and transactions. Top-ups and charges are not possible through the API: payments happen only in the console.

The secret is shown once, when the key is created. Keep it in an environment variable or a secret manager, not in code.

Revoke a key in the console or with DELETE /api-keys/{id}. A key cannot grant scopes that your own key does not have.

Authorization: Bearer gpz_…

Environment variable: GPUNZ_API_KEY

Errors

Every error has an HTTP status and the same body: {"error": {"code": "…", "message": "…", "details": {…}}}. The code is stable, so branch on it. The message follows Accept-Language (Russian by default).

{
  "error": {
    "code": "insufficient_funds",
    "message": "Insufficient funds: 120 RUB short. Top up your balance.",
    "details": { "short_kop": 12000 }
  }
}
StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
404not_foundNot found, or it belongs to someone else
422validation_errorInvalid input. details.issues lists the fields
402insufficient_fundsNot enough money for 2 hours of runtime. details.short_kop is how much
409conflictThe state does not allow it: price changed, already destroying, limit reached
429rate_limitedToo many requests. Retry-After says when to retry
503provider_unavailableTemporary service unavailability. Retry later
500internalInternal error. Retry later; the request id helps support
400authorization_pendingDevice flow: waiting for approval in the browser
400slow_downDevice flow: polling too often
400access_deniedDevice flow: denied in the browser
400expired_tokenDevice flow: the code expired or was already used

Retry 5xx and 429 responses with exponential backoff. POST /instances is safe to retry because of the Idempotency-Key.

Limits

120 requests per minute per key, and 60 per minute per address without a key. The X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers show the budget. On 429, wait for Retry-After.

Lists take ?limit= (default 50, maximum 200). Get the next page with next_cursor. There are no offsets: the cursor stays stable while prices change.

Money is whole kopecks (fields *_kop); hourly prices are kopecks per hour (*_kop_h); currency RUB. Times are UTC in RFC 3339.

Public GETs (/gpus, /offers, /templates) send CORS headers and are cached for 60 seconds; everything else is Cache-Control: no-store.

Cursors are opaque: do not parse them or build them yourself.

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 2

{ "data": [...], "next_cursor": "eyJ…" }

Interruptible instances

An interruptible server costs less, but it can be stopped when the market price rises above your bid. The outbid status means it was interrupted.

GET /offers with type=interruptible lists such offers, and GET /gpus returns from_interruptible_kop_h. price.interruptible_kop_h is the price of the whole server in kopecks per hour.

An interruptible server is created with the same POST /instances and type: interruptible. When the market price rises above your bid, the server becomes outbid: the GPU is not billed while the disk is. Starting it places a new bid.

Account

Profile, balance and transactions

GET/api/v1/me

Current user

Profile of the key owner.

API keyScope: user:read

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1/me' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "id": "u_01J9Z3K2Q7",
  "email": "you@example.com",
  "name": "Egor",
  "created_at": "2026-09-01T10:00:00.000Z",
  "two_factor": false,
  "email_verified": true,
  "telegram_linked": false
}
GET/api/v1/balance

Balance and burn rate

Balance, available amount, burn rate per hour, and how many hours the money lasts at the current burn.

API keyScope: billing:read

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1/balance' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "balance_kop": 250000,
  "available_kop": 241250,
  "credit_limit_kop": 0,
  "burn_kop_h": 4120,
  "runway_hours": 58.5,
  "currency": "RUB"
}
GET/api/v1/transactions

Account transactions

Top-ups, rental and traffic charges, bonuses. Newest first.

API keyScope: billing:read

Parameters

NameTypeRequiredDescription
limitqueryintegernoHow many rows to return (1–200, default 50)
cursorquerystringnoCursor from the previous page's next_cursor

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields

Request

curl -X GET 'https://gpu.nz/api/v1/transactions' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "data": [
    {
      "id": "t_01J9Z4",
      "at": "2026-10-10T11:00:00.000Z",
      "type": "usage",
      "amount_kop": -1850,
      "description": "Instance rental",
      "instance_id": "i_8f2KQ1xZ"
    }
  ],
  "next_cursor": null
}

Catalog

GPUs, offers and templates

GET/api/v1/gpus

GPU models

All GPU models with free GPU count and the cheapest price per card. Public, CORS enabled.

Public, no key needed

Request

curl -X GET 'https://gpu.nz/api/v1/gpus'

Response

{
  "data": [
    {
      "slug": "rtx-4090-24gb",
      "name": "RTX 4090",
      "vram_gb": 24,
      "tier": "consumer",
      "available_gpus": 42,
      "from_kop_h": 2650,
      "from_interruptible_kop_h": 1190
    }
  ],
  "next_cursor": null
}
GET/api/v1/offers

Search offers

Servers available to rent, with filters and sorting. Prices are for the whole server, kopecks per hour. Public.

Public, no key needed
  • Only offers available right now are listed. Page with next_cursor, not offsets.

Parameters

NameTypeRequiredDescription
gpuquerystringnoComma-separated model slugs
num_gpusquerystringnoGPUs per server: 1,2,4,8 (comma-separated)
min_gpusqueryintegernoMinimum GPUs per server
typequery"on_demand" | "interruptible"noon_demand (default) or interruptible
countryquerystringnoISO-2 country codes, comma-separated
min_reliabilityquerynumbernoReliability from 0 to 1
min_vram_gbquerynumbernoMinimum VRAM per GPU, GB
max_price_kop_hqueryintegernoAt most this many kopecks per hour (whole server, for the chosen type)
verifiedquerybooleannoVerified datacenters only
min_cudaquerynumbernoMinimum CUDA version, e.g. 12.4
min_disk_gbquerynumbernoMinimum disk, GB
min_inet_down_mbpsquerynumbernoMinimum download, Mbit/s
orderquery"price" | "-price" | "dlperf" | "dlperf_per_price" | "reliability" | "vram" | "inet_down"noprice (default), -price, dlperf, dlperf_per_price, reliability, vram, inet_down
limitqueryintegernoHow many rows to return (1–200, default 50)
cursorquerystringnoCursor from the previous page's next_cursor

Errors

StatusCodeMeaning
422validation_errorInvalid input. details.issues lists the fields
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET \
  'https://gpu.nz/api/v1/offers?gpu=rtx-4090-24gb%2Crtx-3090-24gb&country=DE%2CNL&limit=5'

Response

{
  "data": [
    {
      "id": "o_4Jx9Q2",
      "available": true,
      "verified": true,
      "country": "DE",
      "region": "Hesse",
      "gpu": {
        "slug": "rtx-4090-24gb",
        "name": "RTX 4090",
        "count": 2,
        "vram_gb": 24,
        "total_tflops": 165.2,
        "mem_bw_gbs": 1008
      },
      "cpu": {
        "name": "AMD EPYC 7543",
        "cores": 16
      },
      "ram_gb": 128,
      "disk": {
        "max_gb": 1500,
        "bw_mbps": 2400,
        "name": null
      },
      "network": {
        "up_mbps": 900,
        "down_mbps": 950,
        "ports": 4
      },
      "pcie": {
        "gen": 4,
        "bw_gbs": 31.5
      },
      "cuda_max": 12.8,
      "driver": "550.120",
      "reliability": 0.9987,
      "max_duration_days": 120,
      "dlperf": 88.4,
      "price": {
        "on_demand_kop_h": 5280,
        "interruptible_kop_h": 2380,
        "storage_kop_gb_month": 900,
        "traffic_kop_gb": 0
      }
    }
  ],
  "next_cursor": null
}
GET/api/v1/offers/{id}

One offer

Full specification and prices. Public.

Public, no key needed

Parameters

NameTypeRequiredDescription
idpathstringyesoffer id

Errors

StatusCodeMeaning
404not_foundNot found, or it belongs to someone else
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1o_4Jx9Q2'

Response

{
  "id": "o_4Jx9Q2",
  "available": true,
  "verified": true,
  "country": "DE",
  "region": "Hesse",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 2,
    "vram_gb": 24,
    "total_tflops": 165.2,
    "mem_bw_gbs": 1008
  },
  "cpu": {
    "name": "AMD EPYC 7543",
    "cores": 16
  },
  "ram_gb": 128,
  "disk": {
    "max_gb": 1500,
    "bw_mbps": 2400,
    "name": null
  },
  "network": {
    "up_mbps": 900,
    "down_mbps": 950,
    "ports": 4
  },
  "pcie": {
    "gen": 4,
    "bw_gbs": 31.5
  },
  "cuda_max": 12.8,
  "driver": "550.120",
  "reliability": 0.9987,
  "max_duration_days": 120,
  "dlperf": 88.4,
  "price": {
    "on_demand_kop_h": 5280,
    "interruptible_kop_h": 2380,
    "storage_kop_gb_month": 900,
    "traffic_kop_gb": 0
  }
}
GET/api/v1/templates

Templates

The template catalogue. With a key, your own templates are included (owner = me).

With a key: your own templates too. Without: the catalogue

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1/templates' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "data": [
    {
      "slug": "pytorch-cuda12",
      "name": "PyTorch + CUDA 12",
      "description": "PyTorch 2.5 with CUDA 12.4 and Jupyter",
      "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
      "launch_mode": "ssh",
      "ports": [
        8888
      ],
      "env": {},
      "onstart": null,
      "min_disk_gb": 20,
      "recommended_disk_gb": 40,
      "public": true,
      "owner": "gpunz"
    }
  ],
  "next_cursor": null
}
POST/api/v1/templates

Create an own template

Your own Docker image with ports and variables. Visible only to you. Limit: 20 templates.

API keyScope: instances:write

Request body

NameTypeRequiredDescription
namestringyesName
descriptionstringnoDescription
imagestringyesDocker image with a tag
launch_mode"ssh" | "jupyter" | "entrypoint"noLaunch mode (default ssh)
portsarray<integer>noPorts to publish
envobjectnoEnvironment variables (up to 30)
onstartstringnoCommand run at start
min_disk_gbintegernoMinimum disk
recommended_disk_gbintegernoRecommended disk

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields
409conflictThe state does not allow it: price changed, already destroying, limit reached

Request

curl -X POST 'https://gpu.nz/api/v1/templates' \
  -H "Authorization: Bearer $GPUNZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "My trainer",
  "image": "ghcr.io/me/trainer:1.2",
  "ports": [
    7860
  ],
  "min_disk_gb": 40
}'

Response

{
  "slug": "pytorch-cuda12",
  "name": "PyTorch + CUDA 12",
  "description": "PyTorch 2.5 with CUDA 12.4 and Jupyter",
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "launch_mode": "ssh",
  "ports": [
    8888
  ],
  "env": {},
  "onstart": null,
  "min_disk_gb": 20,
  "recommended_disk_gb": 40,
  "public": true,
  "owner": "gpunz"
}
DELETE/api/v1/templates/{slug}

Delete an own template

Hides the template. Instances already created from it keep running.

API keyScope: instances:write

Parameters

NameTypeRequiredDescription
slugpathstringyesTemplate slug

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else

Request

curl -X DELETE 'https://gpu.nz/api/v1pytorch-cuda12' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

SSH keys

Keys for server access

GET/api/v1/ssh-keys

SSH keys

Keys attached to new instances.

API keyScope: user:read

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1/ssh-keys' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "data": [
    {
      "id": "k_9Qw1Zm",
      "name": "laptop",
      "type": "ssh-ed25519",
      "fingerprint": "SHA256:5mkcWNm+GX3XK8EbRD+A6ieMSHyFHC0ysCe5CgbJRLM",
      "created_at": "2026-09-01T10:00:00.000Z"
    }
  ],
  "next_cursor": null
}
POST/api/v1/ssh-keys

Add an SSH key

A public key from the .pub file. Never send a private key.

API keyScope: user:write

Request body

NameTypeRequiredDescription
namestringnoName (optional)
public_keystringyesLine from the .pub file

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields

Request

curl -X POST 'https://gpu.nz/api/v1/ssh-keys' \
  -H "Authorization: Bearer $GPUNZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "laptop",
  "public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAc6078X+m8JF6aSSsBQjeBTnWzC726H37M3DAbeLVMg you@laptop"
}'

Response

{
  "id": "k_9Qw1Zm",
  "name": "laptop",
  "type": "ssh-ed25519",
  "fingerprint": "SHA256:5mkcWNm+GX3XK8EbRD+A6ieMSHyFHC0ysCe5CgbJRLM",
  "created_at": "2026-09-01T10:00:00.000Z"
}
DELETE/api/v1/ssh-keys/{id}

Delete an SSH key

New instances will not get the key. Running ones are not changed.

API keyScope: user:write

Parameters

NameTypeRequiredDescription
idpathstringyesSSH key id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else

Request

curl -X DELETE 'https://gpu.nz/api/v1k_9Qw1Zm' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Instances

Rental, control and logs

GET/api/v1/instances

Instances

Your instances. By default only live ones (not destroyed).

API keyScope: instances:read

Parameters

NameTypeRequiredDescription
statusquery"active" | "all"noactive (default) or all
limitqueryintegernoHow many rows to return (1–200, default 50)
cursorquerystringnoCursor from the previous page's next_cursor

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields

Request

curl -X GET 'https://gpu.nz/api/v1/instances' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "data": [
    {
      "id": "i_8f2KQ1xZ",
      "name": "trainer",
      "status": "running",
      "desired_state": "running",
      "type": "on_demand",
      "gpu": {
        "slug": "rtx-4090-24gb",
        "name": "RTX 4090",
        "count": 1,
        "vram_gb": 24
      },
      "template": {
        "slug": "pytorch-cuda12",
        "name": "PyTorch + CUDA 12"
      },
      "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
      "disk_gb": 40,
      "country": "DE",
      "price": {
        "running_kop_h": 2640,
        "stopped_kop_h": 24,
        "traffic_kop_gb": 0
      },
      "cost_so_far_kop": 1850,
      "ssh": {
        "host": "203.0.113.10",
        "port": 40122,
        "user": "root",
        "command": "ssh -p 40122 root@203.0.113.10"
      },
      "urls": [
        {
          "label": "8888",
          "url": "http://203.0.113.10:41001/"
        }
      ],
      "created_at": "2026-10-10T11:00:00.000Z",
      "started_at": "2026-10-10T11:02:00.000Z",
      "stop_reason": null
    }
  ],
  "next_cursor": null
}
POST/api/v1/instances

Create an instance

Quotes the offer, locks the price and creates the instance. Send an Idempotency-Key header: a repeat with the same key does not create a second instance and returns the existing one (200).

API keyScope: instances:write

Idempotent: a repeat with the same Idempotency-Key returns the same object

  • 402 insufficient_funds: details.short_kop is how many kopecks are missing for the 2-hour runway.
  • 403 forbidden with details.reason = email_not_verified: confirm your e-mail in the account.
  • Interruptible instance: type: interruptible. When the price rises it becomes outbid (GPU not billed); start places a new bid.

Parameters

NameTypeRequiredDescription
Idempotency-KeyheaderstringyesUnique request key, up to 64 characters

Request body

NameTypeRequiredDescription
offer_idstringyesOffer id from GET /offers
templatestringyesTemplate slug
disk_gbintegeryesDisk, GB
namestringnoName
ssh_key_idsarray<string>noKeys (default: all of yours)
type"on_demand" | "interruptible"noType (default on_demand)
imagestringnoDocker image, only for the custom template
envobjectnoNot supported yet: send an empty object or omit it
onstartstringnoNot supported yet: send null or omit it

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
404not_foundNot found, or it belongs to someone else
422validation_errorInvalid input. details.issues lists the fields
402insufficient_fundsNot enough money for 2 hours of runtime. details.short_kop is how much
409conflictThe state does not allow it: price changed, already destroying, limit reached
503provider_unavailableTemporary service unavailability. Retry later
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X POST 'https://gpu.nz/api/v1/instances' \
  -H "Authorization: Bearer $GPUNZ_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "offer_id": "o_4Jx9Q2",
  "template": "pytorch-cuda12",
  "disk_gb": 40,
  "name": "trainer"
}'

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
GET/api/v1/instances/{id}

Instance

State, access and cost of an instance.

API keyScope: instances:read

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else

Request

curl -X GET 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
PATCH/api/v1/instances/{id}

Rename an instance

Only the name changes.

API keyScope: instances:write

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id

Request body

NameTypeRequiredDescription
namestringnullyesNew name (null clears it)

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields
404not_foundNot found, or it belongs to someone else

Request

curl -X PATCH 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "trainer-2"
}'

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
POST/api/v1/instances/{id}/start

Start

Starts a stopped instance. Requires a balance covering 2 hours of runtime.

API keyScope: instances:write

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
402insufficient_fundsNot enough money for 2 hours of runtime. details.short_kop is how much
404not_foundNot found, or it belongs to someone else
409conflictThe state does not allow it: price changed, already destroying, limit reached

Request

curl -X POST 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
POST/api/v1/instances/{id}/stop

Stop

Stops the instance. Only the disk is billed while stopped.

API keyScope: instances:write

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else
409conflictThe state does not allow it: price changed, already destroying, limit reached

Request

curl -X POST 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
DELETE/api/v1/instances/{id}

Destroy

Irreversible: the disk and its data are removed. Status becomes destroying, then destroyed.

API keyScope: instances:write

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else
409conflictThe state does not allow it: price changed, already destroying, limit reached

Request

curl -X DELETE 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "id": "i_8f2KQ1xZ",
  "name": "trainer",
  "status": "running",
  "desired_state": "running",
  "type": "on_demand",
  "gpu": {
    "slug": "rtx-4090-24gb",
    "name": "RTX 4090",
    "count": 1,
    "vram_gb": 24
  },
  "template": {
    "slug": "pytorch-cuda12",
    "name": "PyTorch + CUDA 12"
  },
  "image": "pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime",
  "disk_gb": 40,
  "country": "DE",
  "price": {
    "running_kop_h": 2640,
    "stopped_kop_h": 24,
    "traffic_kop_gb": 0
  },
  "cost_so_far_kop": 1850,
  "ssh": {
    "host": "203.0.113.10",
    "port": 40122,
    "user": "root",
    "command": "ssh -p 40122 root@203.0.113.10"
  },
  "urls": [
    {
      "label": "8888",
      "url": "http://203.0.113.10:41001/"
    }
  ],
  "created_at": "2026-10-10T11:00:00.000Z",
  "started_at": "2026-10-10T11:02:00.000Z",
  "stop_reason": null
}
GET/api/v1/instances/{id}/logs

Logs

Last lines of the startup log.

API keyScope: instances:read

Parameters

NameTypeRequiredDescription
idpathstringyesinstance id
tailqueryintegernoHow many lines (1–1000, default 200)

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else
503provider_unavailableTemporary service unavailability. Retry later

Request

curl -X GET 'https://gpu.nz/api/v1i_8f2KQ1xZ' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "lines": [
    "Starting container…",
    "Ready."
  ]
}

API keys

Issue and revoke keys

GET/api/v1/api-keys

API keys

Your active keys (no secrets).

API keyScope: user:read

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X GET 'https://gpu.nz/api/v1/api-keys' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Response

{
  "data": [
    {
      "id": "ak_3hT8Lw",
      "name": "CI",
      "prefix": "gpz_3fA9",
      "scopes": [
        "instances:read",
        "instances:write"
      ],
      "source": "console",
      "last_used_at": "2026-10-10T11:30:00.000Z",
      "created_at": "2026-10-01T09:00:00.000Z",
      "expires_at": null
    }
  ],
  "next_cursor": null
}
POST/api/v1/api-keys

Create a key

The secret is returned only in this response. You cannot grant permissions your key does not have.

API keyScope: user:write

Request body

NameTypeRequiredDescription
namestringyesName
scopesarray<"user:read" | "user:write" | "instances:read" | "instances:write" | "billing:read">yesPermissions. You cannot grant more than your key has
expires_in_daysintegernullnoLifetime in days (null — no expiry)

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
422validation_errorInvalid input. details.issues lists the fields
409conflictThe state does not allow it: price changed, already destroying, limit reached

Request

curl -X POST 'https://gpu.nz/api/v1/api-keys' \
  -H "Authorization: Bearer $GPUNZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "CI",
  "scopes": [
    "instances:read",
    "instances:write"
  ],
  "expires_in_days": 90
}'

Response

{
  "id": "ak_3hT8Lw",
  "secret": "gpz_3fA9xK2mQp7vL0dR8sT4yW1bN6hJ5cE9fG2aZ8kP",
  "name": "CI",
  "prefix": "gpz_3fA9",
  "scopes": [
    "instances:read",
    "instances:write"
  ],
  "source": "api",
  "last_used_at": null,
  "created_at": "2026-10-10T09:00:00.000Z",
  "expires_at": "2027-01-08T09:00:00.000Z"
}
DELETE/api/v1/api-keys/{id}

Revoke a key

The key stops working at once. You may revoke the key you are using.

API keyScope: user:write

Parameters

NameTypeRequiredDescription
idpathstringyeskey id

Errors

StatusCodeMeaning
401unauthorizedNo key, or the key is wrong, revoked or expired
403forbiddenThe key lacks the scope, or the account is blocked
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support
404not_foundNot found, or it belongs to someone else

Request

curl -X DELETE 'https://gpu.nz/api/v1ak_3hT8Lw' \
  -H "Authorization: Bearer $GPUNZ_API_KEY"

Terminal login

Device flow for gpunz login

POST/api/v1/auth/device

Terminal login: start

Issues a device_code for the CLI and a short user_code for the browser. Codes live 10 minutes. Used by gpunz login.

Public, no key needed

Errors

StatusCodeMeaning
422validation_errorInvalid input. details.issues lists the fields
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X POST 'https://gpu.nz/api/v1/auth/device' \
  -H "Content-Type: application/json" \
  -d '{
  "client_name": "laptop"
}'

Response

{
  "device_code": "b1JQ3m7kZxR9aY2pD5sU8wE0tG4hK6nL1cV3fB7oM2i",
  "user_code": "KQZD-7WXM",
  "verification_uri": "https://gpu.nz/console/cli/auth",
  "verification_uri_complete": "https://gpu.nz/console/cli/auth?code=KQZD-7WXM",
  "expires_in": 600,
  "interval": 3
}
POST/api/v1/auth/device/token

Terminal login: get the key

The CLI polls every interval seconds until the user approves the code in the browser. The key is issued once.

Public, no key needed
  • While waiting: 400 authorization_pending. Polling too fast: 400 slow_down (increase the interval).

Request body

NameTypeRequiredDescription
device_codestringyesdevice_code from POST /auth/device

Errors

StatusCodeMeaning
400authorization_pendingDevice flow: waiting for approval in the browser
400slow_downDevice flow: polling too often
400access_deniedDevice flow: denied in the browser
400expired_tokenDevice flow: the code expired or was already used
422validation_errorInvalid input. details.issues lists the fields
429rate_limitedToo many requests. Retry-After says when to retry
500internalInternal error. Retry later; the request id helps support

Request

curl -X POST 'https://gpu.nz/api/v1/auth/device/token' \
  -H "Content-Type: application/json" \
  -d '{
  "device_code": "b1JQ3m7kZxR9aY2pD5sU8wE0tG4hK6nL1cV3fB7oM2i"
}'

Response

{
  "api_key": "gpz_9Kc2Lw8pQx4Rz1Tn6Vb3Mh7Jd0Fs5Ya2Ge8Xu1Pq",
  "key_id": "ak_5qP2Vm",
  "user": {
    "email": "you@example.com"
  }
}

Objects

Fields that can be null are marked.

User

Profile of the key owner

NameTypeRequiredDescription
idstringyesUser id
emailstringnullnoE-mail, null when not set
namestringyesDisplay name
created_atstringyesRegistration time
two_factorbooleannoTwo-factor auth enabled
email_verifiedbooleannoE-mail is verified
telegram_linkedbooleannoTelegram is linked

Balance

Balance in kopecks; burn rate in kopecks per hour

NameTypeRequiredDescription
balance_kopintegernoCash plus bonus, kopecks
available_kopintegernoAvailable now, including accrued but not yet posted usage
credit_limit_kopintegernoCredit limit
burn_kop_hintegernoTotal burn across all instances, kopecks per hour
runway_hoursnumbernullnoHours left at the current burn (null when idle)
currency"RUB"noCurrency

Transaction

Wallet ledger entry

NameTypeRequiredDescription
idstringnoTransaction id
atstringnoWhen it happened
type"topup" | "usage" | "bandwidth" | "refund" | "promo_grant" | "promo_expire" | "adjustment" | "writeoff" | "reversal"noKind of operation
amount_kopintegernoBalance change: positive is credit, negative is debit
descriptionstringnoHuman description
instance_idstringnullnoRelated instance id, if any

GpuModel

GPU model with current supply

NameTypeRequiredDescription
slugstringnoModel slug, used in the gpu= filter
namestringnoDisplay name
vram_gbintegernoVRAM per GPU, GB
tier"consumer" | "workstation" | "datacenter" | "legacy"noClass
available_gpusintegernoGPUs available right now
from_kop_hintegernullnoCheapest on-demand price per GPU, kopecks per hour
from_interruptible_kop_hintegernullnoCheapest interruptible price per GPU, kopecks per hour

Offer

Offer: a server configuration with its price

NameTypeRequiredDescription
idstringyesOffer id (used in POST /instances)
availablebooleanyesCan be rented right now
verifiedbooleannoVerified datacenter
countrystringnullnoCountry, ISO-2
regionstringnullnoRegion
gpuobjectyesGPU
cpuobjectnoCPU
ram_gbintegernullnoSystem RAM, GB
diskobjectnoDisk
networkobjectnoNetwork
pcieobjectnoPCIe
cuda_maxnumbernullnoHighest CUDA version
driverstringnullnoDriver version
reliabilitynumbernullnoReliability, 0–1
max_duration_daysintegernullnoDays left in the host contract
dlperfnumbernullnoDeep-learning performance index
priceobjectyesPrices for the whole server (all GPUs), kopecks

Template

Template: image and launch mode

NameTypeRequiredDescription
slugstringnoSlug (used in template=)
namestringnoName
descriptionstringnoDescription
imagestringnoDocker image
launch_mode"ssh" | "jupyter" | "entrypoint"noLaunch mode
portsarray<integer>noContainer ports
envobjectnoEnvironment variables
onstartstringnullnoCommand run at start
min_disk_gbintegernoMinimum disk, GB
recommended_disk_gbintegernoRecommended disk, GB
publicbooleannoVisible to everyone
owner"gpunz" | "me"nogpunz for the catalogue, me for your own template

TemplateCreate

Own template

NameTypeRequiredDescription
namestringyesName
descriptionstringnoDescription
imagestringyesDocker image with a tag
launch_mode"ssh" | "jupyter" | "entrypoint"noLaunch mode (default ssh)
portsarray<integer>noPorts to publish
envobjectnoEnvironment variables (up to 30)
onstartstringnoCommand run at start
min_disk_gbintegernoMinimum disk
recommended_disk_gbintegernoRecommended disk

SshKey

Public SSH key

NameTypeRequiredDescription
idstringnoKey id
namestringnoName
typestringnoKey type
fingerprintstringnoSHA256 fingerprint
created_atstringnoAdded

SshKeyCreate

New SSH key

NameTypeRequiredDescription
namestringnoName (optional)
public_keystringyesLine from the .pub file

Instance

Instance (rental)

NameTypeRequiredDescription
idstringyesInstance id
namestringnullnoName
status"creating" | "starting" | "running" | "stopping" | "stopped" | "destroying" | "destroyed" | "failed" | "outbid"yesCurrent state
desired_state"running" | "stopped" | "destroyed"noWhere it is heading
type"on_demand" | "interruptible"yesRental type
gpuobjectyesGPU
templateobjectnoTemplate
imagestringnoDocker image
disk_gbintegernoDisk, GB
countrystringnullnoCountry, ISO-2
priceobjectyesPrices, kopecks per hour
cost_so_far_kopintegernoCharged so far, kopecks
sshobjectnullnoSSH access (null until the port is assigned)
urlsarray<object>noWeb interfaces of the template
created_atstringnoCreated
started_atstringnullnoFirst time running
stop_reasonstringnullnoWhy it stopped: user, low_balance, admin, provider

InstanceCreate

Parameters of a new instance

NameTypeRequiredDescription
offer_idstringyesOffer id from GET /offers
templatestringyesTemplate slug
disk_gbintegeryesDisk, GB
namestringnoName
ssh_key_idsarray<string>noKeys (default: all of yours)
type"on_demand" | "interruptible"noType (default on_demand)
imagestringnoDocker image, only for the custom template
envobjectnoNot supported yet: send an empty object or omit it
onstartstringnoNot supported yet: send null or omit it

InstancePatch

Instance changes

NameTypeRequiredDescription
namestringnullyesNew name (null clears it)

InstanceLogs

Last log lines of the instance

NameTypeRequiredDescription
linesarray<string>noLines

ApiKey

API key (without the secret)

NameTypeRequiredDescription
idstringnoKey id
namestringnoName
prefixstringnoStart of the key, for recognition
scopesarray<"user:read" | "user:write" | "instances:read" | "instances:write" | "billing:read">noPermissions
source"console" | "cli" | "api"noWhere it was issued
last_used_atstringnullnoLast used
created_atstringnoCreated
expires_atstringnullnoExpires (null — never)

ApiKeyCreate

New key

NameTypeRequiredDescription
namestringyesName
scopesarray<"user:read" | "user:write" | "instances:read" | "instances:write" | "billing:read">yesPermissions. You cannot grant more than your key has
expires_in_daysintegernullnoLifetime in days (null — no expiry)

ApiKeyCreated

New key with its secret. The secret is shown once

NameTypeRequiredDescription
idstringnoKey id
secretstringnoSecret gpz_… (save it now)
namestringnoName
prefixstringnoStart of the key
scopesarray<string>noPermissions
sourcestringnoWhere it was issued
last_used_atstringnullnoLast used
created_atstringnoCreated
expires_atstringnullnoExpires

DeviceCode

Device login codes (gpunz login)

NameTypeRequiredDescription
device_codestringnoSecret for the CLI, never shown to the user
user_codestringnoCode the user confirms in the browser
verification_uristringnoApproval page
verification_uri_completestringnoApproval page with the code filled in
expires_inintegernoLifetime, seconds
intervalintegernoMinimum polling interval, seconds

DeviceTokenRequest

Token request by device_code

NameTypeRequiredDescription
device_codestringyesdevice_code from POST /auth/device

DeviceToken

Issued key (once)

NameTypeRequiredDescription
api_keystringnoSecret gpz_…
key_idstringnoKey id
userobjectnoOwner