跳到主要内容

实例

一个实例,就是一份租下的报价在跑一个模板。这些端点能做实例页面能做的一切。

部署实例

curl -s -X POST "$SUPERHEAT_API/v1/instances" \
-H "Authorization: Bearer $SUPERHEAT_KEY" \
-H "Content-Type: application/json" \
-d '{
"offer_id": "5d2f9c31-8b64-4c0e-9a77-2e0f1b6a4c11",
"template_id": "b1f4a6d2-90c7-5e33-8a2b-1d7c4e0f9a56",
"disk_gb": 60,
"label": "sft-run-14",
"ssh_key_id": "7a3c1e08-42bd-4f19-9d63-5b8e0c2a1f40",
"env_overrides": [
{"key": "HF_TOKEN", "value": "hf_...", "secret": true}
]
}'
字段类型必填说明
offer_iduuid必须仍然是 available,否则调用返回 409 OFFER_UNAVAILABLE
template_iduuid系统模板、公开模板,或你的组织拥有的模板
disk_gb整数介于 10 和 20000 之间,且不大于主机的 machine.disk_gb
label字符串,最多 64 个字符显示在控制台列表里。默认为 null
ssh_key_iduuid必须是持有该凭据的人账户上的密钥。不传的话,实例上没有授权密钥,你就 SSH 不进去。
env_overrides{key, value, secret} 数组按 key 匹配,叠加到模板的 env 之上。值为 null 的条目会被丢弃。

环境变量覆盖项会叠加在模板的 env 之上,但平台自己的覆盖层压过这两者。你无法遮蔽 JUPYTER_TOKENGPU_COUNT

响应是 201 加上实例对象。计费从工作负载真正进入 running 时开始,而不是这次调用的那一刻。

部署一跑起来就在花钱

余额只在部署时检查,不做预留。实例运行期间 GPU 时间按秒计费,停止期间磁盘按 GB 每小时计费。余额为零时,运行中的实例会被自动停止;到 −$5 时,它们会被销毁。见计费如何运作

实例字段

{
"id": "e08b5f27-1c4a-4d90-b3e6-72a9d1f45c83",
"label": "sft-run-14",
"status": "creating",
"disk_gb": 60,
"price_per_hour_microusd": 2290000,
"storage_price_per_gb_hour_microusd": 250,
"ssh_host": "sh-us-tx-01.ssh.superheat.dev",
"ssh_port": 41207,
"ssh_user": "root",
"jupyter_url": null,
"open_url": null,
"created_at": "2026-07-24T11:12:03.771Z",
"started_at": null,
"status_changed_at": "2026-07-24T11:12:03.771Z",
"destroyed_at": null,
"spend_microusd": 0,
"deployed_by": "you@example.com",
"offer": { "id": "5d2f9c31-8b64-4c0e-9a77-2e0f1b6a4c11" },
"template": { "id": "b1f4a6d2-90c7-5e33-8a2b-1d7c4e0f9a56" }
}

offertemplate 就是报价模板里记录的完整对象;这里只做了缩略展示。

字段类型含义
status字符串creatingstartingrunningstoppingstoppeddestroyingdestroyederror 之一。见实例状态
disk_gb整数你申请的磁盘,停止期间按 GB 每小时计费
price_per_hour_microusd整数租用时从报价快照下来的费率,对应整个切片
storage_price_per_gb_hour_microusd整数租用时快照下来的磁盘费率
ssh_host, ssh_port, ssh_user字符串、整数、字符串连接目标。端口从主机发布的范围里分配,绝不会是 22。
jupyter_url字符串或 nullJupyterLab 的入口地址,等 jupyter 模板上报之后才有
open_url字符串或 null模板打开按钮指向的地址,上报之后才有
created_at, started_at, status_changed_at, destroyed_at时间戳started_at 在工作负载第一次运行时被写入
spend_microusd整数这个实例迄今已结算的费用
deployed_by字符串部署它的团队成员的邮箱

列出实例

curl -s "$SUPERHEAT_API/v1/instances" \
-H "Authorization: Bearer $SUPERHEAT_KEY"

返回当前组织的 {"items": [...]},最新的在前。除非你传 include_destroyed=true,否则已销毁的实例不在其中。

获取单个实例

curl -s "$SUPERHEAT_API/v1/instances/e08b5f27-1c4a-4d90-b3e6-72a9d1f45c83" \
-H "Authorization: Bearer $SUPERHEAT_KEY"

未知的 id,以及属于别的组织的实例,都返回 404 INSTANCE_NOT_FOUND

停止、启动和销毁

请求效果允许的起始状态
POST /v1/instances/{id}/stop关掉容器,保留磁盘,并占住 GPU 槽位。状态先变为 stopping,再变为 stoppedrunning
POST /v1/instances/{id}/start在同一块磁盘上把已停止的实例拉回来。状态先变为 starting,再变为 runningstopped
DELETE /v1/instances/{id}拆掉实例并释放切片。状态先变为 destroying,再变为 destroyedrunning, stopped, error
curl -s -X POST "$SUPERHEAT_API/v1/instances/$INSTANCE_ID/stop" \
-H "Authorization: Bearer $SUPERHEAT_KEY"

这三个都会返回处于新的过渡状态的完整实例对象——状态转换是异步完成的,所以要一直轮询到状态稳定下来。

在不允许的状态下调用其中任何一个,都会返回 409 INVALID_STATE,消息里会点明当前状态,例如 Cannot start an instance while it is running。启动时还会重新检查余额,可能返回 402 INSUFFICIENT_BALANCE

销毁会删掉磁盘

DELETE 是终局的:容器、磁盘以及上面的一切都没了,报价重新回到市场上。想让数据等着你,就改用停止。见停止与销毁的区别

日志

curl -s "$SUPERHEAT_API/v1/instances/$INSTANCE_ID/logs?tail=50" \
-H "Authorization: Bearer $SUPERHEAT_KEY"
{
"lines": [
"[2026-07-24 11:12:07] superheat-agent: pulling image vastai/pytorch",
"[2026-07-24 11:12:11] superheat-agent: image ready, creating container",
"[2026-07-24 11:12:13] nvidia-smi: detected 1 GPU(s), driver 570.86",
"[2026-07-24 11:12:14] sshd: listening on 0.0.0.0:41207",
"[2026-07-24 11:12:15] superheat-agent: instance is ready"
]
}
参数取值范围默认值
tail1 到 1000200

超出该范围的值会被以 422 拒绝。在工作负载第一次跑起来之前 lines 都是空的,所以 creating 状态的实例什么都不返回。没有流式端点;请轮询这一个——控制台每三秒刷新一次。见日志

从部署到连接,端到端

这是从一个空 shell 到一个 SSH 会话的完整路径。它假定你有 jq、已经在控制台里添加了 SSH 密钥,并且余额里有钱。

1. 设好你的凭据。SSH 密钥属于你的账户而不是组织,所以列出它们需要会话令牌;其余一切都靠 API 密钥跑。

export SUPERHEAT_API="https://<your-superheat-api-host>"
export SUPERHEAT_KEY="shk_your_key_here"
AUTH=(-H "Authorization: Bearer $SUPERHEAT_KEY")

2. 找出 SSH 密钥的 id,用已登录浏览器里的会话令牌:

curl -s "$SUPERHEAT_API/v1/ssh-keys" \
-H "Authorization: Bearer $SESSION_TOKEN" \
| jq -r '.items[] | "\(.id) \(.name) \(.fingerprint)"'
7a3c1e08-42bd-4f19-9d63-5b8e0c2a1f40 laptop SHA256:Yx1r0oW2fS7Tq8kJ3mN4pB6vC9dE0gH2iK5lM8nP1qR
SSH_KEY_ID="7a3c1e08-42bd-4f19-9d63-5b8e0c2a1f40"

3. 挑最便宜的单卡 H100 切片:

OFFER_ID=$(curl -s "$SUPERHEAT_API/v1/offers?gpu_model=H100%20SXM&num_gpus=1&sort=price_asc" \
"${AUTH[@]}" | jq -r '.items[0].id')

4. 挑一个 SSH 模板:

TEMPLATE_ID=$(curl -s "$SUPERHEAT_API/v1/templates?tab=recommended&mode=ssh" \
"${AUTH[@]}" | jq -r '.items[0].id')

5. 部署:

INSTANCE_ID=$(curl -s -X POST "$SUPERHEAT_API/v1/instances" \
"${AUTH[@]}" -H "Content-Type: application/json" \
-d "{\"offer_id\":\"$OFFER_ID\",\"template_id\":\"$TEMPLATE_ID\",\"disk_gb\":60,\"label\":\"api-demo\",\"ssh_key_id\":\"$SSH_KEY_ID\"}" \
| jq -r '.id')

6. 等它变成 running

while :; do
STATUS=$(curl -s "$SUPERHEAT_API/v1/instances/$INSTANCE_ID" "${AUTH[@]}" | jq -r '.status')
echo "$STATUS"
case "$STATUS" in
running) break ;;
error|destroyed) exit 1 ;;
esac
sleep 3
done

7. 直接从实例本身拼出连接命令,而不是自己去还原它——端口是按实例分配的:

curl -s "$SUPERHEAT_API/v1/instances/$INSTANCE_ID" "${AUTH[@]}" \
| jq -r '"ssh -p \(.ssh_port) \(.ssh_user)@\(.ssh_host)"'
ssh -p 41207 root@sh-us-tx-01.ssh.superheat.dev

8. 连上去,看看 GPU:

ssh -p 41207 root@sh-us-tx-01.ssh.superheat.dev nvidia-smi

9. 中途歇一会儿就停止,彻底干完就销毁:

curl -s -X POST "$SUPERHEAT_API/v1/instances/$INSTANCE_ID/stop" "${AUTH[@]}" | jq -r '.status'
curl -s -X DELETE "$SUPERHEAT_API/v1/instances/$INSTANCE_ID" "${AUTH[@]}" | jq -r '.status'