Логотип Тераферма Тераферма Регистрация
Для разработчиков

API: запуск GPU-серверов из скриптов

Всё, что можно сделать в кабинете руками, можно сделать из пайплайна: найти свободную машину, запустить её со своим образом, дождаться готовности, зайти по SSH, остановить. Обычный HTTPS и JSON, никаких SDK не нужно.

1. Получите токен

В кабинете → Настройки → API-токены нажмите «Создать токен». Токен вида tf_live_… показывается один раз, сохраните его в секреты CI или в переменную окружения. Там же токен можно отозвать.

Токен передаётся в заголовке Authorization. Все адреса начинаются с https://teraferma.io/api. Ответы в JSON, ошибки тоже: {"error": "текст по-русски"}.

export TF_TOKEN=tf_live_xxxxxxxxxxxxxxxxxxxxxxxx

curl -s https://teraferma.io/api/account -H "Authorization: Bearer $TF_TOKEN"
# {"email":"you@example.com","verified":true,"balance_rub":12500,"ssh_key_set":true,"active_instances":0,"max_active_instances":4}

Перед первым запуском проверьте две вещи: verified: true (почта подтверждена) и ssh_key_set: true. Публичный SSH-ключ добавляется один раз в настройках кабинета и автоматически попадает на каждый новый сервер. Без ключа сервер запустится, но зайти на него можно будет только через Jupyter.

Токен даёт доступ только к каталогу, запуску, статусу и остановке ваших серверов. Пароль, SSH-ключ, выплаты и выпуск новых токенов остаются в кабинете, так что утёкший токен не даст управлять аккаунтом.

2. Найдите свободные машины

GET /api/offers возвращает свободные машины с ценами в рублях за час. Фильтры: gpu — модель, count — число карт (1, 2, 4 или 8), sort — price, speed или reliability. Каталог обновляется раз в 10 минут.

curl -s "https://teraferma.io/api/offers?gpu=h200&count=4" -H "Authorization: Bearer $TF_TOKEN"
{"live":true,"updated":1761040000000,"offers":[
  {"id":18273645,"gpu":"h200","gpu_name":"H200","num_gpus":4,"vram":141,"cpu":"AMD EPYC 9354","cpu_cores":64,"ram":512,
   "disk":2000,"country":"US","reliability":0.998,"cuda":12.8,"net_down":8000,"net_up":8000,"price":1862,"disk_rub":0.004,"traffic_rub":0.6,…},
  …]}

Что важно в ответе: id — его вы передаёте в запуск, price — ₽/час за весь сервер, disk — сколько ГБ диска можно взять на этой машине, vram — видеопамять одной карты, reliability — надёжность хоста.

Модели (параметр gpu): b200, h200, h100, a100, l40s, l40, l4, rtx-pro-6000, rtx-a6000, rtx-a5000, rtx-a4000, rtx-5090, rtx-5080, rtx-5070-ti, rtx-4090, rtx-4080, rtx-4060-ti, rtx-3090, rtx-3080, rtx-3060.

3. Запустите сервер

POST /api/instances. Можно указать конкретную машину (offer_id) или только требования (gpu + count), тогда мы сами возьмём самую дешёвую надёжную машину нужного типа. Если указанную машину заняли, пока вы думали, мы тоже возьмём похожую.

ПолеЧто это
offer_idid машины из каталога. Или вместо него:
gpu, countмодель и число карт, например "h200" и 4
templatepytorch (по умолчанию), jupyter, comfyui, vllm или custom — свой Docker-образ
imageдля custom: публичный образ как в docker pull, например nvidia/cuda:12.4.1-devel-ubuntu22.04
cmdдля custom: команда при старте, до 4000 символов. Длинный скрипт лучше положить в образ
diskдиск в ГБ, от минимума шаблона (60 для pytorch и custom) до 2000. Диск сверх 60 ГБ стоит немного дороже
curl -s https://teraferma.io/api/instances \
  -H "Authorization: Bearer $TF_TOKEN" -H "Content-Type: application/json" \
  -d '{"gpu":"h200","count":4,"template":"custom","image":"nvidia/cuda:12.4.1-devel-ubuntu22.04","disk":200,
       "cmd":"pip install -q torch && python /workspace/train.py"}'
# {"ok":true,"id":1234,"status":"provisioning"}

Деньги списываются только с момента, когда сервер стал running. На балансе должно быть не меньше часа работы всех ваших серверов. Минимальное списание за запуск — 15 минут. Одновременно можно держать до 4 серверов; нужно больше — напишите в поддержку.

4. Дождитесь готовности и возьмите SSH

GET /api/instances/<id>. Пока сервер готовится, status равен provisioning, а в stage и stage_note написано, что сейчас происходит. Обычно это 2–5 минут, со своим образом 8–15: машина скачивает образ. Если машина не завелась, мы сами бесплатно берём другую, вам ничего делать не нужно.

curl -s https://teraferma.io/api/instances/1234 -H "Authorization: Bearer $TF_TOKEN"
{"id":1234,"status":"running","stage":null,"stage_note":null,
 "gpu":"h200","gpu_name":"H200","gpu_count":4,"template":"custom","image":"nvidia/cuda:12.4.1-devel-ubuntu22.04","disk_gb":200,
 "price_rub_hour":1862,"cost_rub":31.03,"traffic_rub":0,
 "specs":{"vram_gb":141,"cpu":"AMD EPYC 9354","cpu_cores":64,"ram_gb":512,"country":"US","cuda":12.8,"net_down_mbps":8000,"net_up_mbps":8000},
 "access":{"ssh":{"host":"teraferma.io","port":31001,"user":"root","command":"ssh -p 31001 root@teraferma.io"},
           "jupyter":"https://u.teraferma.io/api/j/…/lab?token=…","app":null,"workdir":"/workspace"},
 "error":null,"created_at":"2026-10-21T10:00:00.000Z","started_at":"2026-10-21T10:04:12.000Z","stopped_at":null}

Когда status стал running, в access.ssh.command лежит готовая команда. Ключ — тот, что вы добавили в кабинете. Рабочая папка на сервере — /workspace; результаты скачайте до остановки, диск после неё удаляется.

ssh -p 31001 root@teraferma.io nvidia-smi
scp -P 31001 root@teraferma.io:/workspace/out.ckpt ./

Если сервер остановился сам, status будет stopped, а в error — причина (например, не скачался образ или кончился баланс). Список всех серверов: GET /api/instances, по умолчанию активные и остановленные за неделю; ?status=running — только работающие.

5. Остановите

curl -s https://teraferma.io/api/instances/stop \
  -H "Authorization: Bearer $TF_TOKEN" -H "Content-Type: application/json" -d '{"id":1234}'
# {"ok":true}

Списание прекращается сразу. Повторная остановка уже остановленного сервера вернёт {"ok":true,"already":true}, это не ошибка, можно вызывать в trap на выходе из скрипта.

Скрипт целиком

Запускает 4×H200 со своим образом, ждёт SSH, выполняет команду и обязательно останавливает сервер, даже если команда упала. Нужны curl и jq.

#!/usr/bin/env bash
set -euo pipefail
API=https://teraferma.io/api; H="Authorization: Bearer $TF_TOKEN"

ID=$(curl -sf "$API/instances" -H "$H" -H "Content-Type: application/json" \
  -d '{"gpu":"h200","count":4,"template":"custom","image":"nvidia/cuda:12.4.1-devel-ubuntu22.04","disk":200}' | jq -r .id)
echo "сервер #$ID запускается"
trap 'curl -sf "$API/instances/stop" -H "$H" -H "Content-Type: application/json" -d "{\"id\":$ID}" >/dev/null; echo "сервер #$ID остановлен"' EXIT

for i in $(seq 1 120); do                       # до 20 минут
  S=$(curl -sf "$API/instances/$ID" -H "$H")
  ST=$(jq -r .status <<<"$S")
  [ "$ST" = running ] && break
  [ "$ST" = stopped ] && { echo "не запустился: $(jq -r .error <<<"$S")"; exit 1; }
  echo "  $(jq -r '.stage_note // .stage' <<<"$S")"; sleep 10
done
[ "$ST" = running ] || { echo "не дождались"; exit 1; }

SSH=$(jq -r .access.ssh.command <<<"$S")      # ssh -p 310xx root@teraferma.io
$SSH -o StrictHostKeyChecking=accept-new nvidia-smi --query-gpu=name,memory.total --format=csv
$SSH 'cd /workspace && python train.py'
scp -P "$(jq -r .access.ssh.port <<<"$S")" root@teraferma.io:/workspace/out.ckpt ./

Ошибки и лимиты

КодКогда
401Токена нет, он неверный или отозван
402Не хватает баланса: в error написано, сколько нужно
403Почта не подтверждена, или метод недоступен по токену (например, смена пароля)
404Сервер с таким id не ваш или не существует
409Свободных машин этого типа сейчас нет: попробуйте другую модель или повторите через несколько минут
429Слишком часто: не больше 60 запросов в минуту на токен, запусков — 10 в минуту. В заголовке Retry-After — сколько подождать

Опрашивать статус чаще раза в 5–10 секунд не имеет смысла: он меняется не быстрее. Если что-то непонятно или нужен лимит больше, напишите нам, ответим быстро.

Нужен токен?

Зарегистрируйтесь, подтвердите почту и создайте токен в настройках кабинета.