Status#
API keys are created in the console, and access is enabled per account while the interface settles — so a key alone does not open the endpoints yet. Ask for access and tell us what you intend to automate; that is what decides the order. This page is the contract we are shipping against, published so you can judge it before committing to it.
Authentication#
Send the key as a bearer token. Keys are shown once at creation, can be revoked at any time, and carry the permissions of the account that created them.
$ curl https://api.spotgpus.com/v1/instances \ -H "Authorization: Bearer sg_live_xxxxxxxxxxxxxxxx"
Keys never appear in URLs, and requests over plain HTTP are refused rather than redirected. Rotate a key by creating the new one, deploying it, then revoking the old one — both work during the overlap.
Conventions#
- Identifiers. Instances are
i-<6 hex>, volumesvol-<6 hex>, paymentssg-<24 hex>. GPU models are slugs such ash100-sxm. - Money. Every amount is in US cents as an integer. Prices per GPU-hour are decimal strings, exactly as printed on the site.
- Time. ISO 8601 in UTC, always with the
Zsuffix. - Pagination.
?limit=up to 100 and?cursor=; the response carriesnext_cursorwhen more rows exist. - Idempotency. Send
Idempotency-Key: <uuid>on anyPOST; a retry with the same key returns the first result instead of creating a second object.
Catalogue#
Query parameters
segment=datacenter|workstation|consumer, min_vram=<gb>, region=<code>, available=true.
Response
{
"data": [
{
"slug": "h100-sxm",
"name": "H100 SXM",
"vendor": "NVIDIA",
"vram_gb": 80,
"memory_type": "HBM3",
"bandwidth_gbs": 3350,
"node_sizes": [1, 2, 4, 8],
"price": {"spot": "0.550", "ondemand": "0.890", "reserved": "0.650"},
"reclaim_rate_30d": "<5%",
"available": {"us-east": 40, "us-west": 24, "eu-central": 32}
}
],
"next_cursor": null
}
Instances#
Body
{
"gpu": "h100-sxm",
"count": 1,
"tier": "spot",
"region": "us-east",
"template": "pytorch",
"volume": "vol-4b19c7",
"relaunch": true,
"name": "nightly-finetune"
}
image may replace template for your own OCI reference, with registry_auth for a private one. disk_gb creates and attaches a volume in one call. The account must hold at least one hour of the resulting rate, or the call returns 402 insufficient_balance.
Response 201
{
"ref": "i-7f3a2c",
"state": "provisioning",
"gpu": "h100-sxm", "count": 1, "tier": "spot", "region": "us-east",
"price_hour": "0.550",
"created_at": "2026-09-15T17:58:04Z"
}
Volumes#
Account#
{
"balance_cents": 12840,
"hourly_rate_cents": 55,
"runway_hours": 233,
"spend_cap_cents": 50000
}
Instance metadata#
Reachable only from inside an instance, without a key, on the link-local address. This is where a running job learns that it is about to be reclaimed.
Payloads and the handling pattern are in interruption handling.
Webhooks#
Register an HTTPS endpoint in the console. Every delivery is a POST with a JSON body and a signature header; answer 2xx within five seconds. Failed deliveries are retried with a backoff for up to an hour.
| Event | When |
|---|---|
instance.running | The instance became reachable; billing starts |
instance.reclaim_notice | 2 minutes before a spot stop |
instance.stopped | Compute billing ended; disk and address kept |
instance.relaunched | Auto-relaunch found capacity; carries the new reference |
instance.terminated | The instance is gone; any volume survives |
balance.low | Credit is below one hour of the current burn rate |
Errors#
HTTP/1.1 409 Conflict
{
"error": {
"code": "no_capacity",
"message": "No H100 is free in us-east right now.",
"retry_after": 120
}
}
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or out of range; the message names it |
| 401 | unauthorized | Missing, malformed or revoked key |
| 402 | insufficient_balance | Less than one hour of the instance rate on the account |
| 404 | not_found | Unknown reference, or an object that belongs to another account |
| 409 | no_capacity | Nothing free for that model, size and region; retry_after is a hint |
| 409 | volume_attached | The volume is in use by an instance |
| 429 | rate_limited | Too many requests; honour Retry-After |
| 500 | internal | Our fault. Retries are safe with an idempotency key |