API
Everything you do in the dashboard is available over a JSON API.
- Base URL:
https://api.gysga.com/v1 - Authentication:
Authorization: Bearer gsk_...
API keys
Section titled “API keys”Create a key in Settings → API keys. The full key is shown only once — store it in a secret manager. You can have up to 50 keys and revoke any of them at any time. A key has the same rights as your account (renting spends your balance), so never put it in client-side code.
export GYSGA_API_KEY=gsk_...curl -s https://api.gysga.com/v1/me -H "Authorization: Bearer $GYSGA_API_KEY"Money and errors
Section titled “Money and errors”- Amounts are integers in micro-dollars:
1_000_000= $1.price_hour_micros: 400000means $0.40/hour. - Errors return a JSON body with a machine-readable code:
{ "error": "insufficient_funds", "message": "Add funds: the balance must cover at least one hour" }| HTTP | error |
Meaning |
|---|---|---|
| 400 | invalid, bad_request |
Invalid parameters; message explains which. |
| 401 | unauthorized |
Missing, wrong or revoked API key. |
| 402 | insufficient_funds |
The balance does not cover one hour of the server’s price. |
| 404 | not_found |
No such server in your account. |
| 409 | no_capacity |
No free GPUs of this model right now. |
| 409 | gpus_busy |
Start failed: the GPUs of this server’s machine are taken. |
| 409 | conflict |
The action is not allowed in the current status (e.g. stopping a stopped server). |
| 409 | not_running |
Proxy: the server is not running. |
| 429 | rate_limited |
Too many requests (about 20 per second per IP). |
| 502 | upstream_unavailable |
Proxy: nothing answers on that port yet, or the host is offline. |
Endpoints
Section titled “Endpoints”| Method | Path | Description |
|---|---|---|
GET |
/me |
Your account and balance. |
GET |
/gpus |
GPU models, prices and availability. |
GET |
/catalog |
GPUs, templates and models (with cache status). |
GET |
/instances |
Your servers (destroyed ones for 7 days). |
POST |
/instances |
Launch a server. |
GET |
/instances/{id} |
One server. |
PATCH |
/instances/{id} |
Rename: {"label": "..."}. |
GET |
/instances/{id}/events |
Event log, newest first. |
POST |
/instances/{id}/stop |
Stop (keeps data). |
POST |
/instances/{id}/start |
Start a stopped server. |
DELETE |
/instances/{id} |
Destroy the server and its data. |
| any | /instances/{id}/proxy/{port}/{path} |
Proxy to a port inside the server. |
Actions return 204 No Content on success.
GET /me
Section titled “GET /me”{ "referral_code": "k7m2p9qa", "created_at": "2026-09-27T10:00:00Z" }, "balance_micros": 25000000}GET /gpus
Section titled “GET /gpus”{ "gpus": [ { "model": "rtx-4090", "display_name": "NVIDIA RTX 4090", "vram_gb": 24, "price_hour_micros": 400000, "tier": "consumer", "arch": "Ada", "free_gpus": 6, "max_per_server": 4 } ]}max_per_server is the largest gpu_count you can request right now.
GET /catalog
Section titled “GET /catalog”Returns gpus (as above), templates and models. A template has id, category, name, description, image, ports, min_vram_gb, min_cuda, disk_gb, model_kinds, model_required, multi_gpu. A model has id, hf, name, kind, params, license, min_vram_gb, tier, gated, tags, description, cached, size_gb. See Templates and Models.
POST /instances
Section titled “POST /instances”| Field | Type | Required | Description |
|---|---|---|---|
gpu_model |
string | yes | e.g. rtx-4090, h100-80gb (see /gpus). |
gpu_count |
int | yes | 1–8, all on one machine. |
template |
string | yes | Template id, e.g. vllm, comfyui, pytorch, custom. |
model |
string | depends | Model id; required for vllm, sglang, embeddings, optional for comfyui. |
image |
string | custom only |
Public Docker image, e.g. ghcr.io/me/app:1.2. |
disk_gb |
int | no | 10–2000; defaults to the template’s size. |
env |
object | no | Environment variables, e.g. {"HF_TOKEN": "hf_..."}. |
label |
string | no | Your name for the server (up to 64 characters). |
curl -s https://api.gysga.com/v1/instances \ -H "Authorization: Bearer $GYSGA_API_KEY" -H "Content-Type: application/json" \ -d '{"gpu_model":"rtx-4090","gpu_count":1,"template":"vllm","model":"qwen3-8b","label":"chat-bot"}'Response 201 Created:
{ "id": "i-abc12345", "label": "chat-bot", "status": "creating", "status_message": "", "desired_state": "running", "gpu_model": "rtx-4090", "gpu_count": 1, "template": "vllm", "model": "qwen3-8b", "image": "vllm/vllm-openai:v0.30.0-cu129", "disk_gb": 60, "ports": [ { "port": 8000, "name": "OpenAI API", "kind": "http", "api": "openai", "path": "/v1/models" } ], "env": {}, "token": "k2m4...", "price_hour_micros": 400000, "machine_id": 17, "machine_online": true, "created_at": "2026-09-27T10:00:00Z"}Poll GET /instances/{id} until status is running (started_at is set then). Statuses are described in Renting → Lifecycle.
GET /instances/{id}/events
Section titled “GET /instances/{id}/events”{ "items": [ { "message": "Running", "created_at": "2026-09-27T10:03:12Z" }, { "message": "Created, waiting for the host to start the container", "created_at": "2026-09-27T10:00:00Z" } ] }Proxy to a port in your server
Section titled “Proxy to a port in your server”https://api.gysga.com/v1/instances/{id}/proxy/{port}/{path}Any method, headers and body (up to 512 MB) are forwarded to http://localhost:{port}/{path} inside the server. Streaming responses (Server-Sent Events, chunked) are passed through immediately, and WebSocket upgrades work.
- Your
Authorizationheader (the Gysga key) and cookies are removed before the request reaches the container. - If the service inside has its own key, send it as
X-Upstream-Authorization: Bearer ...; it is forwarded asAuthorization.
OpenAI SDK with vLLM
Section titled “OpenAI SDK with vLLM”Launch the vllm template with a model, then point any OpenAI client at the proxy. The model name is the Hugging Face id:
from openai import OpenAI
client = OpenAI( base_url="https://api.gysga.com/v1/instances/i-abc12345/proxy/8000/v1", api_key="gsk_...", # your Gysga API key)resp = client.chat.completions.create( model="Qwen/Qwen3-8B", messages=[{"role": "user", "content": "Hello!"}], stream=True,)for chunk in resp: print(chunk.choices[0].delta.content or "", end="")curl https://api.gysga.com/v1/instances/i-abc12345/proxy/8000/v1/chat/completions \ -H "Authorization: Bearer $GYSGA_API_KEY" -H "Content-Type: application/json" \ -d '{"model":"Qwen/Qwen3-8B","messages":[{"role":"user","content":"Hello!"}]}'For SGLang use port 30000; for embeddings call /v1/embeddings on port 8000; Ollama’s OpenAI endpoint is on port 11434.
Full example: launch, wait, use, destroy
Section titled “Full example: launch, wait, use, destroy”import time, requests
API = "https://api.gysga.com/v1"H = {"Authorization": "Bearer gsk_..."}
inst = requests.post(f"{API}/instances", headers=H, json={ "gpu_model": "rtx-4090", "gpu_count": 1, "template": "vllm", "model": "qwen3-8b",}).json()
while True: inst = requests.get(f"{API}/instances/{inst['id']}", headers=H).json() if inst["status"] == "running": break if inst["status"] == "error": raise RuntimeError(inst["status_message"]) time.sleep(10)
base = f"{API}/instances/{inst['id']}/proxy/8000"# The server may need a minute to load the model after the container starts:while requests.get(f"{base}/v1/models", headers=H).status_code != 200: time.sleep(5)
# ... use it ...
requests.delete(f"{API}/instances/{inst['id']}", headers=H)