Claude Skill

vastai-sdk

Vast.ai Python SDK — high-level API for GPU instances, volumes, serverless endpoints, and billing.

LLM Mart · 0 points · 10 views 16 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download vast-ai-vast-cli-vastai_sdk-125cdd8.zip · 3 KB

Install

skills CLI npx skills add https://github.com/vast-ai/vast-cli/tree/master/vastai_sdk
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install vast-ai-vast-cli@llmmart
Git git clone https://github.com/vast-ai/vast-cli.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole vast-ai/vast-cli collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

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 VastAI
vast = VastAI()                        # reads ~/.vast_api_key
vast = 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 VastAI
vast = VastAI(api_key=None, server_url=None, retry=3, raw=False, quiet=False)

Instance Management

# List all your instances
instances = vast.show_instances()

# Get a single instance
instance = vast.show_instance(id=12345)

# Search GPU offers
offers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus>=4 reliability>0.99')

# Create an instance from an offer
result = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50)

# ...as a jupyter instance on a direct connection
result = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50,
                              jupyter=True, direct=True, jupyter_lab=True)

# Lifecycle
vast.start_instance(id=12345)
vast.stop_instance(id=12345)
vast.reboot_instance(id=12345)
vast.destroy_instance(id=12345)

# Label an instance
vast.label_instance(id=12345, label="my-training-run")

# Get SSH connection string
ssh_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 offers
volumes = vast.search_volumes(query='...')

# Search network volumes
net_vols = vast.search_network_volumes()

# Search templates
templates = vast.search_templates()

# Search invoices
invoices = 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 → instance
vast.copy("C.12345:/workspace/results/", "local:./out/") # Instance → local
vast.copy("12345:/workspace/", "67890:/workspace/")      # Instance → instance (legacy format)
vast.copy("s3.101:/data/", "C.12345:/workspace/")        # Cloud service → instance
vast.copy("V.1234:/file", "C.5678:/workspace/")          # Volume → instance
vast.copy("V.1234:/file", "s3.101:/workspace/")          # Volume → cloud service

vast.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 deployments
deployments = vast.show_deployments()

# Get a deployment
deployment = vast.show_deployment(id=42)

# Delete a deployment
vast.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 SyncClient

client = SyncClient(api_key="YOUR_API_KEY")  # or reads ~/.vast_api_key

# Search offers with structured filters
offers = 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 InstanceConfig

instance = client.create_instance(
    offer_id=<id>,
    config=InstanceConfig(image="pytorch/pytorch:latest", disk=50),
)

# List your instances
instances = client.show_instances()  # returns list[SyncInstance]

# Destroy an instance
client.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 asyncio
from vastai import AsyncClient
from vastai.data.instance import InstanceConfig

async def main():
    async with AsyncClient(api_key="YOUR_API_KEY") as client:
        # Search offers
        offers = await client.search(num_gpus=1, gpu_name="A100")

        # Create instance
        instance = await client.create_instance(
            offer_id=<id>, config=InstanceConfig(image="ubuntu:22.04"))

        # List instances
        instances = await client.show_instances()  # returns list[AsyncInstance]

        # Destroy instance
        await client.destroy_instance(instance_or_id=instance.id)

asyncio.run(main())

Serverless Client

For inference endpoints (requires pip install "vastai[serverless]"):

import asyncio
from vastai import Serverless

async def main():
    serverless = Serverless()  # reads ~/.vast_api_key

    # Get an endpoint
    endpoint = await serverless.get_endpoint("my-endpoint")

    # Make a request
    response = 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 job
from vastai import VastAI
vast = 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 signatures
help(vast.search_offers)
help(vast.create_instance)
Files (vast-cli)
  • SKILL.md 7.8 KB
    ---
    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:
      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
    
    ```bash
    pip install vastai
    ```
    
    For serverless and async support:
    ```bash
    pip install "vastai[serverless]"
    ```
    
    ## Authentication
    
    The SDK reads the API key from `~/.vast_api_key` by default. You can also pass it explicitly:
    
    ```python
    from vastai import VastAI
    vast = VastAI()                        # reads ~/.vast_api_key
    vast = 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:
    
    ```python
    from vastai_sdk import VastAI  # equivalent to: from vastai import VastAI
    ```
    
    ## VastAI Class (High-Level SDK)
    
    ```python
    from vastai import VastAI
    vast = VastAI(api_key=None, server_url=None, retry=3, raw=False, quiet=False)
    ```
    
    ### Instance Management
    
    ```python
    # List all your instances
    instances = vast.show_instances()
    
    # Get a single instance
    instance = vast.show_instance(id=12345)
    
    # Search GPU offers
    offers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus>=4 reliability>0.99')
    
    # Create an instance from an offer
    result = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50)
    
    # ...as a jupyter instance on a direct connection
    result = vast.create_instance(id=<offer_id>, image="pytorch/pytorch:latest", disk=50,
                                  jupyter=True, direct=True, jupyter_lab=True)
    
    # Lifecycle
    vast.start_instance(id=12345)
    vast.stop_instance(id=12345)
    vast.reboot_instance(id=12345)
    vast.destroy_instance(id=12345)
    
    # Label an instance
    vast.label_instance(id=12345, label="my-training-run")
    
    # Get SSH connection string
    ssh_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
    
    ```python
    # 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 offers
    volumes = vast.search_volumes(query='...')
    
    # Search network volumes
    net_vols = vast.search_network_volumes()
    
    # Search templates
    templates = vast.search_templates()
    
    # Search invoices
    invoices = vast.search_invoices()
    ```
    
    ### Data Transfer
    
    ```python
    # copy() takes vast URLs: "[C.|V.]id:path", "cloud_service[.id]:path", or "local:path"
    vast.copy("local:./data/", "C.12345:/workspace/data/")   # Local → instance
    vast.copy("C.12345:/workspace/results/", "local:./out/") # Instance → local
    vast.copy("12345:/workspace/", "67890:/workspace/")      # Instance → instance (legacy format)
    vast.copy("s3.101:/data/", "C.12345:/workspace/")        # Cloud service → instance
    vast.copy("V.1234:/file", "C.5678:/workspace/")          # Volume → instance
    vast.copy("V.1234:/file", "s3.101:/workspace/")          # Volume → cloud service
    
    vast.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
    
    ```python
    # List all deployments
    deployments = vast.show_deployments()
    
    # Get a deployment
    deployment = vast.show_deployment(id=42)
    
    # Delete a deployment
    vast.delete_deployment(id=42)
    ```
    
    ### Machine Management (Hosting)
    
    ```python
    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
    
    ```python
    keys = vast.show_ssh_keys()
    vast.create_ssh_key(ssh_key="ssh-rsa AAAA...")
    vast.delete_ssh_key(id=5)
    ```
    
    ### Team Management
    
    ```python
    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.
    
    ```python
    from vastai import SyncClient
    
    client = SyncClient(api_key="YOUR_API_KEY")  # or reads ~/.vast_api_key
    
    # Search offers with structured filters
    offers = 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 InstanceConfig
    
    instance = client.create_instance(
        offer_id=<id>,
        config=InstanceConfig(image="pytorch/pytorch:latest", disk=50),
    )
    
    # List your instances
    instances = client.show_instances()  # returns list[SyncInstance]
    
    # Destroy an instance
    client.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.
    
    ```python
    import asyncio
    from vastai import AsyncClient
    from vastai.data.instance import InstanceConfig
    
    async def main():
        async with AsyncClient(api_key="YOUR_API_KEY") as client:
            # Search offers
            offers = await client.search(num_gpus=1, gpu_name="A100")
    
            # Create instance
            instance = await client.create_instance(
                offer_id=<id>, config=InstanceConfig(image="ubuntu:22.04"))
    
            # List instances
            instances = await client.show_instances()  # returns list[AsyncInstance]
    
            # Destroy instance
            await client.destroy_instance(instance_or_id=instance.id)
    
    asyncio.run(main())
    ```
    
    ## Serverless Client
    
    For inference endpoints (requires `pip install "vastai[serverless]"`):
    
    ```python
    import asyncio
    from vastai import Serverless
    
    async def main():
        serverless = Serverless()  # reads ~/.vast_api_key
    
        # Get an endpoint
        endpoint = await serverless.get_endpoint("my-endpoint")
    
        # Make a request
        response = 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
    
    ```python
    # Find cheapest 4x RTX 4090 and launch a job
    from vastai import VastAI
    vast = 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 signatures
    help(vast.search_offers)
    help(vast.create_instance)
    ```
    
  • __init__.py 270 B
    # vastai_sdk/__init__.py
    
    # Backward-compatibility shim: allow "import vastai_sdk" to reference "vastai"
    import sys
    import importlib
    
    # Import the real package
    _vastai = importlib.import_module("vastai")
    
    # Register it under the old name
    sys.modules[__name__] = _vastai
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related