# Full reference: gpu.nz API v1 > gpu.nz rents GPU servers in rubles through a REST API. Search offers, rent, manage instances, check the balance, keep SSH and API keys. Send the key in the header Authorization: Bearer gpz_… Base URL: https://gpu.nz/api/v1 ## Authentication - Private endpoints require the header Authorization: Bearer gpz_… (the key is 44 characters). - Scopes: user:read, user:write, instances:read, instances:write, billing:read. Top-ups and charges are not available through the API. - Limits: 120 requests per minute per key, 60 per minute per address without a key. Errors: {"error": {"code", "message", "details"}}. ## Quickstart 1. Create a key: console → Keys → API keys, or run `gpunz login`. 2. GET /offers?gpu=rtx-4090-24gb&order=price — find an offer and its id. 3. POST /instances with an Idempotency-Key header and the body {offer_id, template, disk_gb}. 4. GET /instances/{id} — once the status is running, read ssh.command. 5. POST /instances/{id}/stop or DELETE /instances/{id}. ## Endpoints ### Account #### GET /api/v1/me Current user. Profile of the key owner. - Access: key required · Scope: user:read Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### 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. - Access: key required · Scope: billing:read Example response: ```json { "balance_kop": 250000, "available_kop": 241250, "credit_limit_kop": 0, "burn_kop_h": 4120, "runway_hours": 58.5, "currency": "RUB" } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### GET /api/v1/transactions Account transactions. Top-ups, rental and traffic charges, bonuses. Newest first. - Access: key required · Scope: billing:read Parameters: - limit (query): integer — How many rows to return (1–200, default 50) - cursor (query): string — Cursor from the previous page's next_cursor Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields ### Catalog #### GET /api/v1/gpus GPU models. All GPU models with free GPU count and the cheapest price per card. Public, CORS enabled. - Access: public, no key Example response: ```json { "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. - Access: public, no key - Only offers available right now are listed. Page with next_cursor, not offsets. Parameters: - gpu (query): string — Comma-separated model slugs - num_gpus (query): string — GPUs per server: 1,2,4,8 (comma-separated) - min_gpus (query): integer — Minimum GPUs per server - type (query): "on_demand" | "interruptible" — on_demand (default) or interruptible - country (query): string — ISO-2 country codes, comma-separated - min_reliability (query): number — Reliability from 0 to 1 - min_vram_gb (query): number — Minimum VRAM per GPU, GB - max_price_kop_h (query): integer — At most this many kopecks per hour (whole server, for the chosen type) - verified (query): boolean — Verified datacenters only - min_cuda (query): number — Minimum CUDA version, e.g. 12.4 - min_disk_gb (query): number — Minimum disk, GB - min_inet_down_mbps (query): number — Minimum download, Mbit/s - order (query): "price" | "-price" | "dlperf" | "dlperf_per_price" | "reliability" | "vram" | "inet_down" — price (default), -price, dlperf, dlperf_per_price, reliability, vram, inet_down - limit (query): integer — How many rows to return (1–200, default 50) - cursor (query): string — Cursor from the previous page's next_cursor Example response: ```json { "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 } ``` Errors of this endpoint: - 422 validation_error: Invalid input. details.issues lists the fields - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### GET /api/v1/offers/{id} One offer. Full specification and prices. Public. - Access: public, no key Parameters: - id (path, required): string — offer id Example response: ```json { "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 } } ``` Errors of this endpoint: - 404 not_found: Not found, or it belongs to someone else - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### GET /api/v1/templates Templates. The template catalogue. With a key, your own templates are included (owner = me). - Access: with a key: your own templates too Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### POST /api/v1/templates Create an own template. Your own Docker image with ports and variables. Visible only to you. Limit: 20 templates. - Access: key required · Scope: instances:write Request body: ```json { "name": "My trainer", "image": "ghcr.io/me/trainer:1.2", "ports": [ 7860 ], "min_disk_gb": 40 } ``` Example response: ```json { "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" } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields - 409 conflict: The state does not allow it: price changed, already destroying, limit reached #### DELETE /api/v1/templates/{slug} Delete an own template. Hides the template. Instances already created from it keep running. - Access: key required · Scope: instances:write Parameters: - slug (path, required): string — Template slug Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else ### SSH keys #### GET /api/v1/ssh-keys SSH keys. Keys attached to new instances. - Access: key required · Scope: user:read Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### POST /api/v1/ssh-keys Add an SSH key. A public key from the .pub file. Never send a private key. - Access: key required · Scope: user:write Request body: ```json { "name": "laptop", "public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAc6078X+m8JF6aSSsBQjeBTnWzC726H37M3DAbeLVMg you@laptop" } ``` Example response: ```json { "id": "k_9Qw1Zm", "name": "laptop", "type": "ssh-ed25519", "fingerprint": "SHA256:5mkcWNm+GX3XK8EbRD+A6ieMSHyFHC0ysCe5CgbJRLM", "created_at": "2026-09-01T10:00:00.000Z" } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields #### DELETE /api/v1/ssh-keys/{id} Delete an SSH key. New instances will not get the key. Running ones are not changed. - Access: key required · Scope: user:write Parameters: - id (path, required): string — SSH key id Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else ### Instances #### GET /api/v1/instances Instances. Your instances. By default only live ones (not destroyed). - Access: key required · Scope: instances:read Parameters: - status (query): "active" | "all" — active (default) or all - limit (query): integer — How many rows to return (1–200, default 50) - cursor (query): string — Cursor from the previous page's next_cursor Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields #### 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). - Access: key required · Scope: instances:write - Idempotent: 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: - Idempotency-Key (header, required): string — Unique request key, up to 64 characters Request body: ```json { "offer_id": "o_4Jx9Q2", "template": "pytorch-cuda12", "disk_gb": 40, "name": "trainer" } ``` Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 404 not_found: Not found, or it belongs to someone else - 422 validation_error: Invalid input. details.issues lists the fields - 402 insufficient_funds: Not enough money for 2 hours of runtime. details.short_kop is how much - 409 conflict: The state does not allow it: price changed, already destroying, limit reached - 503 provider_unavailable: Temporary service unavailability. Retry later - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### GET /api/v1/instances/{id} Instance. State, access and cost of an instance. - Access: key required · Scope: instances:read Parameters: - id (path, required): string — instance id Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else #### PATCH /api/v1/instances/{id} Rename an instance. Only the name changes. - Access: key required · Scope: instances:write Parameters: - id (path, required): string — instance id Request body: ```json { "name": "trainer-2" } ``` Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields - 404 not_found: Not found, or it belongs to someone else #### POST /api/v1/instances/{id}/start Start. Starts a stopped instance. Requires a balance covering 2 hours of runtime. - Access: key required · Scope: instances:write Parameters: - id (path, required): string — instance id Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 402 insufficient_funds: Not enough money for 2 hours of runtime. details.short_kop is how much - 404 not_found: Not found, or it belongs to someone else - 409 conflict: The state does not allow it: price changed, already destroying, limit reached #### POST /api/v1/instances/{id}/stop Stop. Stops the instance. Only the disk is billed while stopped. - Access: key required · Scope: instances:write Parameters: - id (path, required): string — instance id Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else - 409 conflict: The state does not allow it: price changed, already destroying, limit reached #### DELETE /api/v1/instances/{id} Destroy. Irreversible: the disk and its data are removed. Status becomes destroying, then destroyed. - Access: key required · Scope: instances:write Parameters: - id (path, required): string — instance id Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else - 409 conflict: The state does not allow it: price changed, already destroying, limit reached #### GET /api/v1/instances/{id}/logs Logs. Last lines of the startup log. - Access: key required · Scope: instances:read Parameters: - id (path, required): string — instance id - tail (query): integer — How many lines (1–1000, default 200) Example response: ```json { "lines": [ "Starting container…", "Ready." ] } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else - 503 provider_unavailable: Temporary service unavailability. Retry later ### API keys #### GET /api/v1/api-keys API keys. Your active keys (no secrets). - Access: key required · Scope: user:read Example response: ```json { "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 } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### 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. - Access: key required · Scope: user:write Request body: ```json { "name": "CI", "scopes": [ "instances:read", "instances:write" ], "expires_in_days": 90 } ``` Example response: ```json { "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" } ``` Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 422 validation_error: Invalid input. details.issues lists the fields - 409 conflict: The state does not allow it: price changed, already destroying, limit reached #### DELETE /api/v1/api-keys/{id} Revoke a key. The key stops working at once. You may revoke the key you are using. - Access: key required · Scope: user:write Parameters: - id (path, required): string — key id Errors of this endpoint: - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support - 404 not_found: Not found, or it belongs to someone else ### Terminal 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. - Access: public, no key Request body: ```json { "client_name": "laptop" } ``` Example response: ```json { "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 } ``` Errors of this endpoint: - 422 validation_error: Invalid input. details.issues lists the fields - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support #### 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. - Access: public, no key - While waiting: 400 authorization_pending. Polling too fast: 400 slow_down (increase the interval). Request body: ```json { "device_code": "b1JQ3m7kZxR9aY2pD5sU8wE0tG4hK6nL1cV3fB7oM2i" } ``` Example response: ```json { "api_key": "gpz_9Kc2Lw8pQx4Rz1Tn6Vb3Mh7Jd0Fs5Ya2Ge8Xu1Pq", "key_id": "ak_5qP2Vm", "user": { "email": "you@example.com" } } ``` Errors of this endpoint: - 400 authorization_pending: Device flow: waiting for approval in the browser - 400 slow_down: Device flow: polling too often - 400 access_denied: Device flow: denied in the browser - 400 expired_token: Device flow: the code expired or was already used - 422 validation_error: Invalid input. details.issues lists the fields - 429 rate_limited: Too many requests. Retry-After says when to retry - 500 internal: Internal error. Retry later; the request id helps support ## Objects ### User Profile of the key owner - id: string — User id - email: string — E-mail, null when not set - name: string — Display name - created_at: string — Registration time - two_factor: boolean — Two-factor auth enabled - email_verified: boolean — E-mail is verified - telegram_linked: boolean — Telegram is linked ### Balance Balance in kopecks; burn rate in kopecks per hour - balance_kop: integer — Cash plus bonus, kopecks - available_kop: integer — Available now, including accrued but not yet posted usage - credit_limit_kop: integer — Credit limit - burn_kop_h: integer — Total burn across all instances, kopecks per hour - runway_hours: number — Hours left at the current burn (null when idle) - currency: "RUB" — Currency ### Transaction Wallet ledger entry - id: string — Transaction id - at: string — When it happened - type: "topup" | "usage" | "bandwidth" | "refund" | "promo_grant" | "promo_expire" | "adjustment" | "writeoff" | "reversal" — Kind of operation - amount_kop: integer — Balance change: positive is credit, negative is debit - description: string — Human description - instance_id: string — Related instance id, if any ### GpuModel GPU model with current supply - slug: string — Model slug, used in the gpu= filter - name: string — Display name - vram_gb: integer — VRAM per GPU, GB - tier: "consumer" | "workstation" | "datacenter" | "legacy" — Class - available_gpus: integer — GPUs available right now - from_kop_h: integer — Cheapest on-demand price per GPU, kopecks per hour - from_interruptible_kop_h: integer — Cheapest interruptible price per GPU, kopecks per hour ### Offer Offer: a server configuration with its price - id: string — Offer id (used in POST /instances) - available: boolean — Can be rented right now - verified: boolean — Verified datacenter - country: string — Country, ISO-2 - region: string — Region - gpu: object — GPU - cpu: object — CPU - ram_gb: integer — System RAM, GB - disk: object — Disk - network: object — Network - pcie: object — PCIe - cuda_max: number — Highest CUDA version - driver: string — Driver version - reliability: number — Reliability, 0–1 - max_duration_days: integer — Days left in the host contract - dlperf: number — Deep-learning performance index - price: object — Prices for the whole server (all GPUs), kopecks ### Template Template: image and launch mode - slug: string — Slug (used in template=) - name: string — Name - description: string — Description - image: string — Docker image - launch_mode: "ssh" | "jupyter" | "entrypoint" — Launch mode - ports: array — Container ports - env: object — Environment variables - onstart: string — Command run at start - min_disk_gb: integer — Minimum disk, GB - recommended_disk_gb: integer — Recommended disk, GB - public: boolean — Visible to everyone - owner: "gpunz" | "me" — gpunz for the catalogue, me for your own template ### TemplateCreate Own template - name: string — Name - description: string — Description - image: string — Docker image with a tag - launch_mode: "ssh" | "jupyter" | "entrypoint" — Launch mode (default ssh) - ports: array — Ports to publish - env: object — Environment variables (up to 30) - onstart: string — Command run at start - min_disk_gb: integer — Minimum disk - recommended_disk_gb: integer — Recommended disk ### SshKey Public SSH key - id: string — Key id - name: string — Name - type: string — Key type - fingerprint: string — SHA256 fingerprint - created_at: string — Added ### SshKeyCreate New SSH key - name: string — Name (optional) - public_key: string — Line from the .pub file ### Instance Instance (rental) - id: string — Instance id - name: string — Name - status: "creating" | "starting" | "running" | "stopping" | "stopped" | "destroying" | "destroyed" | "failed" | "outbid" — Current state - desired_state: "running" | "stopped" | "destroyed" — Where it is heading - type: "on_demand" | "interruptible" — Rental type - gpu: object — GPU - template: object — Template - image: string — Docker image - disk_gb: integer — Disk, GB - country: string — Country, ISO-2 - price: object — Prices, kopecks per hour - cost_so_far_kop: integer — Charged so far, kopecks - ssh: object — SSH access (null until the port is assigned) - urls: array — Web interfaces of the template - created_at: string — Created - started_at: string — First time running - stop_reason: string — Why it stopped: user, low_balance, admin, provider ### InstanceCreate Parameters of a new instance - offer_id: string — Offer id from GET /offers - template: string — Template slug - disk_gb: integer — Disk, GB - name: string — Name - ssh_key_ids: array — Keys (default: all of yours) - type: "on_demand" | "interruptible" — Type (default on_demand) - image: string — Docker image, only for the custom template - env: object — Not supported yet: send an empty object or omit it - onstart: string — Not supported yet: send null or omit it ### InstancePatch Instance changes - name: string — New name (null clears it) ### InstanceLogs Last log lines of the instance - lines: array — Lines ### ApiKey API key (without the secret) - id: string — Key id - name: string — Name - prefix: string — Start of the key, for recognition - scopes: array<"user:read" | "user:write" | "instances:read" | "instances:write" | "billing:read"> — Permissions - source: "console" | "cli" | "api" — Where it was issued - last_used_at: string — Last used - created_at: string — Created - expires_at: string — Expires (null — never) ### ApiKeyCreate New key - name: string — Name - scopes: array<"user:read" | "user:write" | "instances:read" | "instances:write" | "billing:read"> — Permissions. You cannot grant more than your key has - expires_in_days: integer — Lifetime in days (null — no expiry) ### ApiKeyCreated New key with its secret. The secret is shown once - id: string — Key id - secret: string — Secret gpz_… (save it now) - name: string — Name - prefix: string — Start of the key - scopes: array — Permissions - source: string — Where it was issued - last_used_at: string — Last used - created_at: string — Created - expires_at: string — Expires ### DeviceCode Device login codes (gpunz login) - device_code: string — Secret for the CLI, never shown to the user - user_code: string — Code the user confirms in the browser - verification_uri: string — Approval page - verification_uri_complete: string — Approval page with the code filled in - expires_in: integer — Lifetime, seconds - interval: integer — Minimum polling interval, seconds ### DeviceTokenRequest Token request by device_code - device_code: string — device_code from POST /auth/device ### DeviceToken Issued key (once) - api_key: string — Secret gpz_… - key_id: string — Key id - user: object — Owner ## Error codes - 401 unauthorized: No key, or the key is wrong, revoked or expired - 403 forbidden: The key lacks the scope, or the account is blocked - 404 not_found: Not found, or it belongs to someone else - 422 validation_error: Invalid input. details.issues lists the fields - 402 insufficient_funds: Not enough money for 2 hours of runtime. details.short_kop is how much - 409 conflict: The state does not allow it: price changed, already destroying, limit reached - 429 rate_limited: Too many requests. Retry-After says when to retry - 503 provider_unavailable: Temporary service unavailability. Retry later - 500 internal: Internal error. Retry later; the request id helps support - 400 authorization_pending: Device flow: waiting for approval in the browser - 400 slow_down: Device flow: polling too often - 400 access_denied: Device flow: denied in the browser - 400 expired_token: Device flow: the code expired or was already used