Skill v1.0.1
currentAutomated scan100/100+3 new
name: vastai-sdk description: Vast.ai Python SDK — high-level API for GPU instances, volumes, serverless endpoints, and billing. allowed-tools: Python(vastai:*) compatibility: Python 3.9+ metadata: version: "1.0.1" author: vast-ai
Vast.ai Python SDK (vastai / vastai_sdk)
The vastai package provides a Python SDK for managing GPU instances, volumes, serverless endpoints, and billing on Vast.ai. The vastai_sdk package is a backward-compatibility shim that re-exports vastai.
Installation
pip install vastai
For serverless and async support:
pip install "vastai[serverless]"
Authentication
The SDK reads the API key from ~/.vast_api_key by default. You can also pass it explicitly:
from vastai import VastAIvast = VastAI() # reads ~/.vast_api_keyvast = VastAI(api_key="YOUR_API_KEY") # explicit key
Get your API key from https://console.vast.ai/manage-keys/
Backward Compatibility
The old vastai_sdk import still works:
from vastai_sdk import VastAI # equivalent to: from vastai import VastAI
VastAI Class (High-Level SDK)
from vastai import VastAIvast = VastAI(api_key=None, server_url=None, retry=3, raw=False, quiet=False)
Instance Management
# List all your instancesinstances = vast.show_instances()# Get a single instanceinstance = vast.show_instance(id=12345)# Search GPU offersoffers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus>=4 reliability>0.99')# Create an instance from an offerresult = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50)# ...as a jupyter instance on a direct connectionresult = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50,jupyter=True, direct=True, jupyter_lab=True)# Lifecyclevast.start_instance(id=12345)vast.stop_instance(id=12345)vast.reboot_instance(id=12345)vast.destroy_instance(id=12345)# Label an instancevast.label_instance(id=12345, label="my-training-run")# Get SSH connection stringssh_url = vast.ssh_url(id=12345) # returns "ssh -p PORT user@host"scp_url = vast.scp_url(id=12345) # returns scp-compatible URL
Interruptible (spot) rentals
Interruptible (spot) instances are priced below on-demand instances, but can be interrupted at any time by another user with a lower bid. Note: vast.search_offers(type='bid', ...) exposes min_bid, but vast.create_instance(...) defaults to on-demand at `dph_total` unless you pass bid_price=<floor>. Always pass bid_price after a type='bid' search, otherwise the instance will be rented as an on-demand instance/price instead of as an interruptible.
When outbid, the instance moves to stopped (not destroyed) and storage charges continue. Resume by raising the bid via vast.change_bid(id=..., price=...).
Search
# Search GPU offers (use help(vast.search_offers) for full query syntax)offers = vast.search_offers(query='gpu_name=RTX_3090 num_gpus>=2')# Search volume offersvolumes = vast.search_volumes(query='...')# Search network volumesnet_vols = vast.search_network_volumes()# Search templatestemplates = vast.search_templates()# Search invoicesinvoices = vast.search_invoices()
Data Transfer
# copy() takes vast URLs: "[C.|V.]id:path", "cloud_service[.id]:path", or "local:path"vast.copy("local:./data/", "C.12345:/workspace/data/") # Local → instancevast.copy("C.12345:/workspace/results/", "local:./out/") # Instance → localvast.copy("12345:/workspace/", "67890:/workspace/") # Instance → instance (legacy format)vast.copy("s3.101:/data/", "C.12345:/workspace/") # Cloud service → instancevast.copy("V.1234:/file", "C.5678:/workspace/") # Volume → instancevast.copy("V.1234:/file", "s3.101:/workspace/") # Volume → cloud servicevast.cancel_copy(dst_id=12345) # Cancel an in-progress copy# Cloud sync via a saved cloud connection (see the UI settings page for connection IDs)vast.cloud_copy(src="./data", dst="s3://bucket/path", instance=12345,connection=<conn_id>, transfer="Instance To Cloud")vast.cancel_sync(dst_id=12345)
Volume copy is currently only supported for copying to other volumes, instances, or cloud services, not local. Do not use /root or / as a destination directory — it breaks ssh permissions on the instance and future copies fail. See https://vast.ai/docs/gpu-instances/data-movement#constraints.
Serverless Deployments
# List all deploymentsdeployments = vast.show_deployments()# Get a deploymentdeployment = vast.show_deployment(id=42)# Delete a deploymentvast.delete_deployment(id=42)
Machine Management (Hosting)
machines = vast.show_machines()machine = vast.show_machine(id=10)vast.list_machine(id=10, price_gpu=0.30)vast.unlist_machine(id=10)
SSH Keys
keys = vast.show_ssh_keys()vast.create_ssh_key(ssh_key="ssh-rsa AAAA...")vast.delete_ssh_key(id=5)
Team Management
members = vast.show_members()vast.invite_member(email="user@example.com", role="developer")vast.remove_member(id=7)
SyncClient (Low-Level Sync)
SyncClient provides typed, synchronous access to GPU offers and instances.
from vastai import SyncClientclient = SyncClient(api_key="YOUR_API_KEY") # or reads ~/.vast_api_key# Search offers with structured filtersoffers = client.search(num_gpus=2,gpu_name="RTX_4090",min_reliability=0.99,max_dph_total=2.0,)# Create an instance (SyncClient takes an InstanceConfig, not loose kwargs)from vastai.data.instance import InstanceConfiginstance = client.create_instance(offer_id=<id>,config=InstanceConfig(image="pytorch/pytorch:latest", disk=50),)# List your instancesinstances = client.show_instances() # returns list[SyncInstance]# Destroy an instanceclient.destroy_instance(instance_or_id=12345)
AsyncClient (Low-Level Async)
AsyncClient provides async access to GPU offers and instances. Use as an async context manager.
import asynciofrom vastai import AsyncClientfrom vastai.data.instance import InstanceConfigasync def main():async with AsyncClient(api_key="YOUR_API_KEY") as client:# Search offersoffers = await client.search(num_gpus=1, gpu_name="A100")# Create instanceinstance = await client.create_instance(offer_id=<id>, config=InstanceConfig(image="ubuntu:22.04"))# List instancesinstances = await client.show_instances() # returns list[AsyncInstance]# Destroy instanceawait client.destroy_instance(instance_or_id=instance.id)asyncio.run(main())
Serverless Client
For inference endpoints (requires pip install "vastai[serverless]"):
import asynciofrom vastai import Serverlessasync def main():serverless = Serverless() # reads ~/.vast_api_key# Get an endpointendpoint = await serverless.get_endpoint("my-endpoint")# Make a requestresponse = await serverless.request("/v1/completions", {"model": "Qwen/Qwen3-8B","prompt": "Who are you?","max_tokens": 100,"temperature": 0.7,})text = response["response"]["choices"][0]["text"]print(text)asyncio.run(main())
Common Patterns
# Find cheapest 4x RTX 4090 and launch a jobfrom vastai import VastAIvast = VastAI()offers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus=4 reliability>0.99')cheapest = min(offers, key=lambda o: o['dph_total'])result = vast.create_instance(id=cheapest['id'], image="pytorch/pytorch:latest", disk=100)print(f"Launched instance: {result['new_contract']}")# Use help() to explore method signatureshelp(vast.search_offers)help(vast.create_instance)