Logo VRAMfarm VRAMfarm
FR
S’inscrire
Documentation

API VRAMfarm

Lancez des serveurs GPU depuis vos scripts et votre CI : trouvez une machine disponible, démarrez-la avec une application prête à l’emploi ou votre propre image Docker, attendez l’accès SSH, arrêtez-la. Du HTTPS et du JSON, sans SDK.

URL de base de l’APIhttps://vramfarm.com/api
  • Les réponses sont en JSON, UTF-8. Les requêtes POST exigent l’en-tête Content-Type: application/json.
  • Les montants sont en euros. price est le prix horaire du serveur entier, toutes cartes comprises, sous forme décimale avec les centimes (par exemple 0.39).
  • Les dates des réponses sont au format ISO 8601 en UTC ; le champ updated du catalogue est en millisecondes Unix.
  • Les messages d’erreur sont dans la langue de votre compte, ou dans celle de l’en-tête Accept-Language, et en anglais par défaut.

Démarrage rapide

Ce script lance un serveur RTX 4090, attend qu’il soit prêt, affiche la commande SSH et arrête le serveur, même si quelque chose échoue en cours de route.

Lancer, attendre SSH, arrêter
import os, time, requests

API = "https://vramfarm.com/api"
s = requests.Session()
s.headers["Authorization"] = f"Bearer {os.environ['GF_TOKEN']}"

r = s.post(f"{API}/instances", json={"gpu": "rtx-4090", "count": 1, "template": "pytorch"})
r.raise_for_status()
sid = r.json()["id"]
try:
    while True:
        srv = s.get(f"{API}/instances/{sid}").json()
        if srv["status"] == "running":
            break
        if srv["status"] == "stopped":
            raise RuntimeError(srv["error"])
        print(srv["stage_note"] or srv["stage"])
        time.sleep(10)
    print(srv["access"]["ssh"]["command"])
    # your work goes here: ssh, scp, requests to the app on the server
finally:
    s.post(f"{API}/instances/stop", json={"id": sid})

Authentification

Créez un token dans le tableau de bord → Paramètres → Tokens API. Un token ressemble à gf_live_… et ne s’affiche qu’une fois : conservez-le dans les secrets de votre CI ou dans la variable d’environnement GF_TOKEN. Vous pouvez révoquer vos tokens au même endroit. Jusqu’à 10 tokens peuvent être actifs.

Envoyez le token dans l’en-tête Authorization: Bearer gf_live_…. Rien d’autre n’est nécessaire : les requêtes ne sont pas signées, il n’y a ni horodatage ni recvWindow, et les cookies et l’en-tête Origin ne sont pas vérifiés pour les requêtes avec token.

import os, requests

H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}
print(requests.get("https://vramfarm.com/api/account", headers=H).json())

Un token donne accès uniquement aux méthodes de cette page. Votre mot de passe, votre clé SSH et la création de nouveaux tokens ne sont accessibles que depuis le tableau de bord ; avec un token, ces endpoints renvoient 403. Un token divulgué permet de lancer et d’arrêter des serveurs, mais pas de gérer votre compte.

Le catalogue et /health fonctionnent sans token. Mais si vous envoyez un en-tête Authorization avec un token erroné ou révoqué, tous les endpoints renvoient 401.

Appelez l’API depuis votre propre serveur, script ou CI. Les requêtes envoyées depuis un navigateur sur un autre site ne passeront pas, et n’importe quel visiteur pourrait y voir le token.

Avant votre premier lancement, ajoutez une clé SSH publique dans les paramètres du tableau de bord : elle est installée sur chaque nouveau serveur. Vous pouvez vérifier que tout est prêt avec GET /api/account.

Erreurs et limites

En cas d’erreur, vous recevez un statut HTTP et le corps {"error": "message", "code": "snake_case_code"}. Le texte de error peut être montré tel quel à une personne ; faites dépendre votre code de code, jamais du texte. Certaines réponses ajoutent une indication pour les programmes : unverified au lancement, saving à l’arrêt.

StatutQuand
400Paramètres invalides : image, disque, VRAM insuffisante, limite de serveurs
401Token erroné ou révoqué, ou compte bloqué
402Solde insuffisant ; error indique le montant nécessaire
403E-mail non confirmé, ou méthode non disponible avec un token
404Serveur introuvable ou appartenant à un autre compte ; endpoint inconnu
409Aucune machine de ce type disponible ; le dossier du serveur est encore en cours d’enregistrement
415POST sans Content-Type: application/json
429Limite de requêtes dépassée ; attendez le nombre de secondes indiqué par l’en-tête Retry-After
500Une erreur de notre côté
502Le catalogue est temporairement indisponible
503Le fournisseur de machines est surchargé ; relancez dans une minute

Limites

  • 60 requêtes par minute et par token, toutes méthodes confondues. La limite d’un token n’affecte pas les autres.
  • 10 lancements par minute et par token. Les lancements échoués comptent aussi.
  • Le catalogue est en plus limité à 60 requêtes par minute et par adresse IP.
  • Jusqu’à 4 serveurs simultanés ; le nombre exact figure dans max_active_instances. Besoin de plus ? Écrivez-nous.
  • Corps de requête jusqu’à 64 Ko.

Le statut d’un serveur change au plus toutes les quelques secondes : interrogez-le toutes les 5 à 10 secondes.

Réessayer sur 429, 502 et 503
import time, requests

def call(method, url, **kw):
    for attempt in range(5):
        r = requests.request(method, url, **kw)
        if r.status_code not in (429, 502, 503):
            return r
        time.sleep(int(r.headers.get("Retry-After", 30)))
    return r

Catalogue

Machines disponibles

GET/api/offers

La liste des machines disponibles avec leur prix en euros par heure, de la moins chère à la plus chère. Le catalogue est actualisé toutes les 10 minutes.

Paramètres de requête

ParamètreTypeDescription
gpufacultatifstringModèle de GPU, par exemple h200. Sans ce paramètre, ou avec un modèle inconnu, tous les modèles sont renvoyés. La liste des modèles se trouve sous le tableau.
countfacultatifintegerNombre de cartes dans la machine : 1, 2, 4 ou 8. Les autres valeurs sont ignorées.
allfacultatifstring1 affiche aussi les machines non vérifiées. Par défaut, seules les machines vérifiées (verified: true) sont renvoyées.

Modèles : b200 h200 h100 a100 a100-40 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. a100 correspond à 80 Go, a100-40 à 40 Go.

Champs d’une machine
idintegerÀ passer comme offer_id au lancement
gpu, gpu_namestringModèle : code pour les requêtes et nom affiché
num_gpusintegerNombre de cartes
vramintegerVRAM d’une carte, Go
cpu, cpu_cores, cpu_ghzstring, integer, numberCPU, cœurs disponibles, fréquence
ramintegerRAM, Go
disk, disk_bwintegerEspace disque disponible en Go ; vitesse du disque, Mo/s
net_down, net_upintegerRéseau, Mbit/s
countrystringPays, code ISO
reliabilitynumberFiabilité de la machine, de 0 à 1
cuda, drivernumber, stringVersion maximale de CUDA et du pilote prise en charge
dlperf, tflops, mem_bw, pcienumberPerformances : score DLPerf, TFLOPS, bande passante mémoire et PCIe
verifiedbooleanLa machine est vérifiée
pricenumberEUR par heure pour le serveur entier, disque minimal du template inclus
disk_eurnumberEUR par heure pour 1 Go de disque au-delà du volume inclus
traffic_eur, traffic_up_eurnumberEUR par Go de trafic téléchargé et envoyé
durationintegerNombre de jours pendant lesquels la machine peut encore être louée
static_ip, portsboolean, integerIP statique, nombre de ports ouverts

Si live vaut false, le catalogue est désactivé et offers est vide. updated est l’heure de la réponse en millisecondes Unix.

Erreurs

  • 401Token erroné ou révoqué
  • 429Plus de 60 requêtes par minute
  • 502Le catalogue est temporairement indisponible ; réessayez dans une minute
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.get(f"{API}/offers", headers=H, params={"gpu": "h200", "count": 4})
r.raise_for_status()
for o in r.json()["offers"][:5]:
    print(o["id"], o["gpu_name"], o["price"], "EUR/h", o["country"])
Réponse · 200
{
  "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,
      "net_down": 8000,
      "net_up": 8000,
      "country": "DE",
      "reliability": 0.998,
      "cuda": 12.8,
      "verified": true,
      "price": 33.16,
      "disk_eur": 0.00005,
      "traffic_eur": 0.007,
      "traffic_up_eur": 0.007
    }
  ]
}

Types de machines

GET/api/offer-types

Une ligne par couple « modèle × nombre de cartes » : la machine la moins chère avec une fiabilité d’au moins 0,97, et le nombre de machines de ce type disponibles. Pratique pour choisir gpu et count avant un lancement.

Aucun paramètre.

Les champs sont les mêmes que pour une machine du catalogue, avec en plus available, le nombre de machines libres de ce type, et max_dlperf, le meilleur score de performance parmi elles. La réponse est mise en cache pendant une minute.

Erreurs

  • 401Token erroné ou révoqué
  • 429Plus de 60 requêtes par minute
  • 502Le catalogue est temporairement indisponible
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

types = requests.get(f"{API}/offer-types", headers=H).json()["types"]
for t in types:
    print(f'{t["num_gpus"]}x {t["gpu_name"]}: from {t["price"]} EUR/h, {t["available"]} available')
Réponse · 200
{
  "live": true,
  "updated": 1761040000000,
  "types": [
    {
      "id": 20311822,
      "gpu": "rtx-3090",
      "gpu_name": "RTX 3090",
      "num_gpus": 1,
      "vram": 24,
      "price": 0.3,
      "reliability": 0.991,
      "available": 37,
      "max_dlperf": 41
    }
  ]
}

Serveurs

Lancer un serveur

POST/api/instances

Loue une machine et y démarre l’application choisie ou votre image Docker. La réponse arrive immédiatement ; le serveur met 2 à 5 minutes à être prêt, ou 8 à 15 avec votre propre image.

Corps de la requête, JSON

ParamètreTypeDescription
offer_idfacultatifintegerid d’une machine du catalogue. Si elle a déjà été prise, nous en choisissons une similaire du même type. offer_id ou gpu est obligatoire.
gpufacultatifstringModèle, si la machine exacte vous importe peu : nous prenons la moins chère parmi les machines fiables qui conviennent.
countfacultatifintegerNombre de cartes lors d’un choix par gpu, de 1 à 8. 1 par défaut.
templatefacultatifstringCe qu’il faut lancer, pytorch par défaut. Voir le tableau ci-dessous. Une valeur inconnue est traitée comme pytorch.
imagefacultatifstringObligatoire pour custom : une image publique, écrite comme pour docker pull.
cmdfacultatifstringPour custom : une commande à exécuter au démarrage, jusqu’à 4000 caractères.
diskfacultatifintegerDisque, en Go. Une valeur inférieure au minimum du template est relevée à ce minimum. Pas plus de 2000, ni plus que ce dont dispose la machine.
ws_restorefacultatifbooleantrue par défaut : votre dossier de travail enregistré revient sur le serveur. false donne un serveur vierge.
Templates (template)
CodeContenuDisque min.Mémoire de carte min.
pytorchPyTorch, CUDA, Jupyter60 GB
jupyterJupyter40 GB
customVotre image indiquée dans image60 GB
comfyuiComfyUI et Stable Diffusion 1.5100 GB
comfy-fluxComfyUI et Flux schnell100 GB16 GB
comfy-sdxlComfyUI et SDXL100 GB12 GB
comfy-wanComfyUI et Wan 2.2 5B, vidéo100 GB24 GB
comfy-wan14ComfyUI et Wan 2.2 14B, vidéo160 GB48 GB
comfy-qwenComfyUI et Qwen-Image100 GB24 GB
comfy-qeditComfyUI et Qwen-Image-Edit100 GB24 GB
comfy-hidreamComfyUI et HiDream-O160 GB24 GB
chatOpen WebUI et Ollama, modèle qwen3:8b80 GB12 GB
chat-proOpen WebUI et Ollama, modèle qwen3:32b100 GB24 GB
chat-mimoOpen WebUI et Ollama, modèle MiMo 9B60 GB12 GB
vllmvLLM, modèle Qwen/Qwen2.5-7B-Instruct100 GB
tts-qwen3Synthèse vocale Qwen3-TTS, Gradio40 GB12 GB
tts-voxcpmSynthèse vocale VoxCPM2, Gradio40 GB12 GB
tts-chatterboxSynthèse vocale Chatterbox, Gradio40 GB12 GB

La facturation se fait à la minute à partir du moment où le serveur passe en running, avec un minimum de 15 minutes par lancement. Votre solde doit couvrir au moins une heure de tous vos serveurs, nouveau serveur compris. Quand le solde est épuisé, les serveurs s’arrêtent et leurs disques sont effacés.

Une requête identique dans les 15 secondes renvoie le serveur déjà créé, avec "duplicate": true ; nous ne louons pas de seconde machine. Si un lancement échoue à cause du solde ou d’un e-mail non confirmé, il n’est pas mis en file d’attente pour les requêtes avec token : relancez-le vous-même.

Erreurs

  • 400Aucun GPU indiqué, image invalide, disque trop grand, VRAM insuffisante pour le template, ou déjà 4 serveurs
  • 402Solde insuffisant pour une heure ; le montant figure dans error
  • 403E-mail non confirmé ; la réponse contient "unverified": true
  • 409Aucune machine de ce type disponible
  • 429Plus de 10 lancements par minute et par token
  • 503Le fournisseur de machines est surchargé ; réessayez dans une minute
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.post(f"{API}/instances", headers=H, json={
    "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",
})
if not r.ok:
    raise SystemExit(f"{r.status_code} {r.json()['code']}: {r.json()['error']}")
print("server", r.json()["id"])
Réponse · 200
{
  "ok": true,
  "id": 1234,
  "status": "provisioning"
}

Liste des serveurs

GET/api/instances

Vos serveurs, du plus récent au plus ancien, jusqu’à 100. Par défaut : en cours, en démarrage et arrêtés au cours des 7 derniers jours.

Paramètres de requête

ParamètreTypeDescription
statusfacultatifstringprovisioning, running ou stopped : uniquement les serveurs dans cet état.

Chaque élément de instances a la même forme que la réponse de GET /api/instances/{id}.

Erreurs

  • 401Token erroné ou révoqué
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.get(f"{API}/instances", headers=H, params={"status": "running"})
for s in r.json()["instances"]:
    print(s["id"], s["gpu_name"], s["cost_eur"], "EUR")
Réponse · 200
{
  "instances": [
    { "id": 1234, "status": "running", "gpu": "h200", "gpu_count": 4, "cost_eur": 0.55, "...": "..." }
  ]
}

Serveur et accès

GET/api/instances/{id}

L’état d’un serveur. Dès que status vaut running, access contient SSH, Jupyter et l’adresse de l’application.

Paramètres de chemin

ParamètreTypeDescription
idobligatoireintegerid issu de la réponse au lancement
Champs de la réponse
statusstringprovisioning : en préparation ; running : en cours et facturé ; stopped : arrêté
stage, stage_notestring | nullUniquement pendant provisioning : l’étape (par exemple pick, loading) et ce qui se passe, dans la langue de votre compte
gpu, gpu_name, gpu_countstring, integerModèle et nombre de cartes
template, imagestringTemplate et image (pour custom)
disk_gbintegerDisque, Go
price_eur_hournumberPrix horaire du serveur entier, EUR
cost_eurnumberMontant facturé pour ce lancement, EUR ; pour un serveur en cours, jusqu’à la minute actuelle
traffic_eurnumberMontant facturé pour le trafic, EUR
specsobject | nullCaractéristiques de la machine
access.sshobject | nullhost, port, user et une command prête à l’emploi
access.jupyterstring | nullLien Jupyter avec un token
access.appstring | nullAdresse de l’application pour ComfyUI et vLLM ; pour custom, si l’image ouvre son propre port. Plus de détails dans Applications du serveur
access.workdirstringDossier de travail, /workspace
errorstring | nullPourquoi le serveur s’est arrêté de lui-même : l’image n’a pas pu être téléchargée, le solde est épuisé
created_at, started_at, stopped_atstring | nullHeure au format ISO 8601, UTC

access n’est rempli que pour un serveur en cours. La clé SSH est celle ajoutée dans les paramètres du tableau de bord. Si une machine ne démarre pas, nous en prenons une autre gratuitement ; l’id du serveur reste le même.

Travailler avec le serveur
ssh -p 31001 root@vramfarm.com nvidia-smi
scp -P 31001 root@vramfarm.com:/workspace/out.ckpt ./

Erreurs

  • 404Aucun serveur avec cet id, ou il ne vous appartient pas
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

s = requests.get(f"{API}/instances/1234", headers=H).json()
if s["status"] == "running":
    print(s["access"]["ssh"]["command"])
else:
    print(s["status"], s["stage_note"] or s["error"])
Réponse · 200
{
  "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_eur_hour": 33.16,
  "cost_eur": 0.55,
  "traffic_eur": 0,
  "specs": {
    "vram_gb": 141, "cpu": "AMD EPYC 9354", "cpu_cores": 64, "ram_gb": 512,
    "country": "DE", "cuda": 12.8, "net_down_mbps": 8000, "net_up_mbps": 8000
  },
  "access": {
    "ssh": {
      "host": "vramfarm.com",
      "port": 31001,
      "user": "root",
      "command": "ssh -p 31001 root@vramfarm.com"
    },
    "jupyter": "https://u.vramfarm.com/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
}

Arrêter un serveur

POST/api/instances/stop

Arrête le serveur ; la facturation s’arrête immédiatement. Le disque du serveur est effacé ; vous pouvez enregistrer le dossier de travail.

Corps de la requête, JSON

ParamètreTypeDescription
idobligatoireintegerid du serveur
savefacultatifbooleantrue : enregistrer d’abord /workspace, puis arrêter. Ne fonctionne pas pour custom.
forcefacultatifbooleantrue : arrêter tout de suite, même si le dossier est en cours d’enregistrement. L’enregistrement est interrompu.

Arrêter un serveur déjà arrêté renvoie {"ok":true,"already":true}. Ce n’est pas une erreur : vous pouvez placer l’appel dans un finally ou un trap à la sortie du script.

Avec "save": true, la réponse {"ok":true,"saving":true} arrive immédiatement, puis le serveur enregistre le dossier et s’arrête de lui-même, généralement en quelques minutes. Le stockage coûte 0,03 € par Go et par mois, facturé chaque jour. Votre prochain serveur récupère le dossier automatiquement, sauf si vous passez "ws_restore": false.

Erreurs

  • 404Aucun serveur avec cet id, ou il ne vous appartient pas
  • 409Le dossier est encore en cours d’enregistrement ; la réponse contient "saving": true. Patientez, ou passez "force": true
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

r = requests.post(f"{API}/instances/stop", headers=H, json={"id": 1234})
print(r.json())
Réponse · 200
{
  "ok": true
}

Compte

Compte

GET/api/account

Solde et capacité à lancer. Pratique pour vérifier avant un lancement que votre e-mail est confirmé et qu’une clé SSH est ajoutée.

Aucun paramètre.

emailstringE-mail du compte
verifiedbooleanE-mail confirmé. Sinon, un lancement renvoie 403
balance_eurnumberSolde, EUR
ssh_key_setbooleanClé SSH ajoutée. Sans clé, le serveur démarre quand même, mais vous ne pouvez y accéder que via Jupyter
active_instancesintegerNombre de serveurs en démarrage ou en cours
max_active_instancesintegerNombre de serveurs que vous pouvez faire tourner en même temps

Erreurs

  • 401Token erroné ou révoqué, ou compte bloqué
Requête
import os, requests

API = "https://vramfarm.com/api"
H = {"Authorization": f"Bearer {os.environ['GF_TOKEN']}"}

acc = requests.get(f"{API}/account", headers=H).json()
assert acc["verified"] and acc["ssh_key_set"], acc
print(acc["balance_eur"], "EUR")
Réponse · 200
{
  "email": "you@example.com",
  "verified": true,
  "balance_eur": 150.0,
  "ssh_key_set": true,
  "active_instances": 0,
  "max_active_instances": 4
}

Service

État du service

GET/api/health

Vérifie que l’API répond. Aucun token nécessaire.

Aucun paramètre.

En cas de panne, la réponse est 503 avec une brève raison dans why, par exemple {"ok":false,"why":"…"}.

Erreurs

  • 503Le service ne fonctionne pas entièrement ; la raison figure dans why
Requête
import requests

r = requests.get("https://vramfarm.com/api/health", timeout=10)
print(r.status_code, r.json())
Réponse · 200
{
  "ok": true,
  "status": "ok"
}

Applications du serveur via l’API

ComfyUI, les applications de synthèse vocale, le chat et vLLM ont chacun leur propre API. Utilisez-la pour générer des images, de l’audio et du texte depuis un script, sans ouvrir l’interface. Ces applications n’ont pas besoin de votre token VRAMfarm, et il ne leur est jamais envoyé.

Où trouver l’adresse de l’application :

  • ComfyUI et vLLM : le champ access.app de GET /api/instances/{id}, du type https://u.vramfarm.com/api/a/<key>/. Pour vLLM, elle se termine déjà par v1.
  • Chat et synthèse vocale : une adresse du type http://<host>:<port> s’affiche sur la carte du serveur dans le tableau de bord ; elle ne figure pas dans access.app. Depuis un script, un tunnel SSH est plus fiable : il fonctionne dès que SSH fonctionne.
  • Votre propre image (custom) : access.app est rempli si le conteneur ouvre un port autre que 22, 8080 et 8888.
Tunnel SSH
# SSH port from access.ssh.port; -N: tunnel only, no shell
ssh -p 31001 root@vramfarm.com -N -L 11434:127.0.0.1:11434

Gardez le tunnel ouvert pendant l’exécution de votre script : les requêtes vers localhost:11434 sont transmises au serveur. Pour la synthèse vocale, utilisez le port 7860 (-L 7860:127.0.0.1:7860), pour ComfyUI le 8188, pour vLLM le 8000. L’application démarre 5 à 10 minutes après running ; d’ici là, l’adresse renvoie 502 ou ne répond pas.

ComfyUI

Templates comfyui et comfy-*. Construisez un workflow dans l’interface et enregistrez-le via Workflow → Export (API) sous le nom workflow_api.json. Le script modifie ensuite le texte du prompt dans le workflow, l’envoie à /prompt, attend le résultat dans /history/{prompt_id} et télécharge les images via /view.

import json, time, requests

APP = "https://u.vramfarm.com/api/a/<key>/"                                   # access.app of the server
wf = json.load(open("workflow_api.json"))        # Workflow → Export (API) in ComfyUI
wf["6"]["inputs"]["text"] = "a cat in a spacesuit, photo"  # node number from your file

pid = requests.post(APP + "prompt", json={"prompt": wf}).json()["prompt_id"]
while pid not in (h := requests.get(APP + f"history/{pid}").json()):
    time.sleep(2)

for node in h[pid]["outputs"].values():
    for img in node.get("images", []):
        data = requests.get(APP + "view", params=img).content  # filename, subfolder, type
        open(img["filename"], "wb").write(data)

Synthèse vocale et autres applications Gradio

Les templates tts-qwen3, tts-voxcpm et tts-chatterbox reposent sur Gradio. En bas de la page de l’application, un lien « Use via API » liste les méthodes, leurs paramètres et des exemples prêts à l’emploi. Les noms de méthode diffèrent d’une application à l’autre : remplacez /generate dans l’exemple par le nom indiqué dans « Use via API » ou par view_api().

# pip install gradio_client
from gradio_client import Client

client = Client("http://localhost:7860/")   # through an SSH tunnel or the address from the dashboard
client.view_api()                           # list of methods and their parameters

# method name and argument order: from view_api() or "Use via API"
audio_path = client.predict("Hello! This is a speech test.", api_name="/generate")
print(audio_path)                           # the result file on your computer

Chat : Ollama et Open WebUI

Templates chat, chat-pro et chat-mimo : Open WebUI tourne au-dessus d’Ollama. Depuis un script, le plus simple est de parler directement à Ollama. Il n’écoute qu’à l’intérieur du serveur, sur 127.0.0.1:11434 : il vous faut donc un tunnel SSH comme dans l’exemple ci-dessus. Le modèle se télécharge après le lancement ; tant qu’il n’est pas chargé, Ollama répond que le modèle est introuvable.

import requests

r = requests.post("http://localhost:11434/api/chat", json={
    "model": "qwen3:8b",          # chat-pro uses qwen3:32b
    "messages": [{"role": "user", "content": "In one sentence: what is CUDA?"}],
    "stream": False,
})
print(r.json()["message"]["content"])

Ollama parle aussi le format OpenAI sur http://localhost:11434/v1/chat/completions : les bibliothèques OpenAI fonctionnent donc. Open WebUI a aussi sa propre API ; vous générez une clé pour elle dans les paramètres d’Open WebUI.

vLLM

Le template vllm démarre un serveur compatible OpenAI avec Qwen/Qwen2.5-7B-Instruct. L’adresse est access.app, qui se termine déjà par /v1. La clé n’est pas vérifiée, mais la bibliothèque OpenAI en exige une non vide : passez n’importe quelle valeur. La liste des modèles se trouve sur GET /v1/models.

# pip install openai
from openai import OpenAI

client = OpenAI(base_url="https://u.vramfarm.com/api/a/<key>/v1",  # access.app
                api_key="EMPTY")                                    # no key needed
r = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct",
    messages=[{"role": "user", "content": "Write a haiku about a graphics card"}],
)
print(r.choices[0].message.content)

Besoin d’un token ? Inscrivez-vous, confirmez votre e-mail et créez un token dans les paramètres du tableau de bord. Si quelque chose ne correspond pas à cette page, ou si vous avez besoin d’une limite plus élevée, écrivez-nous.