# RunPod Adapter

**Interface:** `runpodctl` CLI (v2.9.0) + REST API. **Kind:** managed instances (pods).
Everything below marked *(verified)* was exercised live on 2026-08-12.

## Install & auth

`runpodctl config` is deprecated in v2.9.0 — auth lives in `~/.runpod/config.toml`:

```bash
# install (non-root): GitHub release → ~/.local/bin, checksum-verified
VERSION=$(curl -s https://api.github.com/repos/runpod/runpodctl/releases/latest | grep tag_name | head -1 | sed 's/.*"tag_name": "//;s/".*//')
cd /tmp && curl -sSL -o runpodctl.tar.gz "https://github.com/runpod/runpodctl/releases/download/${VERSION}/runpodctl-linux-amd64.tar.gz"
curl -sSL -o checksums.txt "https://github.com/runpod/runpodctl/releases/download/${VERSION}/checksums_${VERSION#v}_sha256.txt"
grep linux-amd64 checksums.txt | awk '{print $1"  runpodctl.tar.gz"}' | sha256sum -c -   # → OK
tar xzf runpodctl.tar.gz runpodctl && install -m 0755 runpodctl ~/.local/bin/runpodctl

# auth: `runpodctl doctor` (also creates + uploads the SSH key pair you need
# for pod access — it lives in ~/.runpod/ssh/), or write the key yourself:
printf "apikey = '%s'\napiurl = 'https://api.runpod.io/graphql'\n" "$RUNPOD_API_KEY" > ~/.runpod/config.toml
chmod 600 ~/.runpod/config.toml
runpodctl pod list        # verify — exits 0 (empty list is fine)
```

## GPU ids *(verified)*

`--gpu-id` takes the exact `.gpuId` string from `runpodctl gpu list`, NOT the
display name:

| Display name | `--gpu-id` value |
| --- | --- |
| RTX PRO 6000 | `NVIDIA RTX PRO 6000 Blackwell Server Edition` |
| RTX 5090 | `NVIDIA GeForce RTX 5090` |
| RTX 4090 | `NVIDIA GeForce RTX 4090` |
| H100 SXM | `NVIDIA H100 80GB SXM` |

## Provision — the capacity protocol *(verified)*

Stock status from `gpu list` **overstates availability**: a DC showing
"Medium" rejected every community create in the live session. Only a
successful create proves stock; failed creates don't bill.

1. Try COMMUNITY across the DC rotation, **one DC per attempt** —
   `--data-center-ids` accepts a comma list but the graphql API only uses the
   first id (the CLI even prints a note).
2. Decode failures:
   - `There are no longer any instances available with the requested
     specifications` → **no stock** for GPU+cloud in that DC. Next DC.
   - `This machine does not have the resources to deploy your pod` → pool
     exists, **spec doesn't fit** — usually container disk (official ComfyUI
     templates default to 150GB). Shrink to 60–80GB, retry the same DC.
3. Fall back to SECURE. Session outcome: every COMMUNITY DC rejected;
   SECURE US-NC-2 rejected on resources; **SECURE US-NC-1 at 60GB landed**.

The H3-lane create *(the provision tool's default)*:

```bash
runpodctl pod create --name lvrged-h3 \
  --image runpod/comfyui:cuda13.0 \
  --gpu-id "NVIDIA RTX PRO 6000 Blackwell Server Edition" \
  --cloud-type SECURE --data-center-ids US-NC-1 \
  --container-disk-in-gb 80 --volume-in-gb 0 --ports "22/tcp,8188/http"
```

### Create-flag gotchas *(all verified the hard way)*

- **Custom images publish NO ports.** Without `--ports "22/tcp,8188/http"`
  the pod comes up SSH-unreachable and `pod get` returns
  `pod not ready: pod does not publish 22/tcp`. The fix-after-the-fact
  (`pod update --ports`) **replaces the whole list and restarts the
  container** — in the session it restarted mid image pull.
- **`--volume-in-gb 0` always.** Network volumes DC-lock the install; with
  thin stock, that turns every future pod start into waiting for one DC.
  Container disk ~$0.04/hr vs volume $21/mo/300GB is a wash; the price is
  ~15 min of HF re-download per fresh pod.
- Template-based create (`--template-id cw3nka7d08`) gets you the cu128
  image — ~2x slower for H3 INT8 and no real SageAttention. Image-based
  create with the cu130 image is the lane.

## Wait for ready *(verified)*

A 13GB image pull takes minutes. `runtimeStatus: running` + connection
refused = still **Extracting**. Poll:

```bash
for i in $(seq 1 30); do
  runpodctl pod get <id> | jq -e '.ssh.ip' >/dev/null 2>&1 && break; sleep 15
done
runpodctl pod get <id> | jq -r '.ssh.ssh_command'
# stream boot/system logs while waiting:
curl -s "https://api.runpod.io/v2/pods/<id>/logs?stream=false" -H "Authorization: Bearer $RUNPOD_API_KEY" | tail -5
```

Then tunnel 8188 (the public HTTP port frequently refuses even when mapped —
see the comfyui skill) and treat `http://127.0.0.1:8188` as the endpoint.

## Pause / resume / restart / destroy *(verified)*

```bash
runpodctl pod stop <id>     # pause: GPU billing off; status EXITED
runpodctl pod start <id>    # resume: billing on; SSH host/port usually change
runpodctl pod restart <id>  # apply comfyui_args.txt changes (supervisor relaunches)
runpodctl pod delete <id>   # destroy — artifacts off first
```

- **EXITED pods vanish from `pod list`** — keep the pod id in the registry
  and use `pod get <id>`.
- Treat container-disk survival across stop/start as unverified — check the
  weights dir on resume before assuming a warm start.
- Pods bill from creation: a stuck image pull still costs.
- A $0 account balance kills pods and deletes disks — keep a $5–10 buffer.

## Reference

- API docs: https://docs.runpod.io/reference (pods, templates, gpu-types, pod logs)
- Pricing snapshot: docs/pricing/runpod.md — PRO 6000 community $1.69 /
  secure $2.09 *(verified)*; verify live before committing spend.
