{"slug":"vastai-sdk","title":"vastai-sdk","summary":"Vast.ai Python SDK — high-level API for GPU instances, volumes, serverless endpoints, and billing.","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-06T17:22:04.060111Z","repo":{"url":"https://github.com/vast-ai/vast-cli","stars":221,"forks":94,"license":"MIT","updatedAt":"2026-09-22T23:59:12Z"},"bodyHtml":"<hr>\n<h2>name: vastai-sdk\ndescription: Vast.ai Python SDK — high-level API for GPU instances, volumes, serverless endpoints, and billing.\nallowed-tools: Python(vastai:*)\ncompatibility: Python 3.9+\nmetadata:\nauthor: vast-ai</h2>\n<h1>Vast.ai Python SDK (<code>vastai</code> / <code>vastai_sdk</code>)</h1>\n<p>The <code>vastai</code> package provides a Python SDK for managing GPU instances, volumes, serverless endpoints, and billing on Vast.ai. The <code>vastai_sdk</code> package is a backward-compatibility shim that re-exports <code>vastai</code>.</p>\n<h2>Installation</h2>\n<pre><code>pip install vastai\n</code></pre>\n<p>For serverless and async support:</p>\n<pre><code>pip install \"vastai[serverless]\"\n</code></pre>\n<h2>Authentication</h2>\n<p>The SDK reads the API key from <code>~/.vast_api_key</code> by default. You can also pass it explicitly:</p>\n<pre><code>from vastai import VastAI\nvast = VastAI()                        # reads ~/.vast_api_key\nvast = VastAI(api_key=\"YOUR_API_KEY\")  # explicit key\n</code></pre>\n<p>Get your API key from <a href=\"https://console.vast.ai/manage-keys/\">https://console.vast.ai/manage-keys/</a></p>\n<h2>Backward Compatibility</h2>\n<p>The old <code>vastai_sdk</code> import still works:</p>\n<pre><code>from vastai_sdk import VastAI  # equivalent to: from vastai import VastAI\n</code></pre>\n<h2>VastAI Class (High-Level SDK)</h2>\n<pre><code>from vastai import VastAI\nvast = VastAI(api_key=None, server_url=None, retry=3, raw=False, quiet=False)\n</code></pre>\n<h3>Instance Management</h3>\n<pre><code># List all your instances\ninstances = vast.show_instances()\n\n# Get a single instance\ninstance = vast.show_instance(id=12345)\n\n# Search GPU offers\noffers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus&gt;=4 reliability&gt;0.99')\n\n# Create an instance from an offer\nresult = vast.create_instance(id=&lt;offer_id&gt;, image=\"pytorch/pytorch:latest\", disk=50)\n\n# ...as a jupyter instance on a direct connection\nresult = vast.create_instance(id=&lt;offer_id&gt;, image=\"pytorch/pytorch:latest\", disk=50,\n                              jupyter=True, direct=True, jupyter_lab=True)\n\n# Lifecycle\nvast.start_instance(id=12345)\nvast.stop_instance(id=12345)\nvast.reboot_instance(id=12345)\nvast.destroy_instance(id=12345)\n\n# Label an instance\nvast.label_instance(id=12345, label=\"my-training-run\")\n\n# Get SSH connection string\nssh_url = vast.ssh_url(id=12345)   # returns \"ssh -p PORT user@host\"\nscp_url = vast.scp_url(id=12345)   # returns scp-compatible URL\n</code></pre>\n<h3>Interruptible (spot) rentals</h3>\n<p>Interruptible (spot) instances are priced below on-demand instances, but can be interrupted at any time by another user with a lower bid. Note: <code>vast.search_offers(type='bid', ...)</code> exposes <code>min_bid</code>, but <code>vast.create_instance(...)</code> defaults to <strong>on-demand at <code>dph_total</code></strong> unless you pass <code>bid_price=&lt;floor&gt;</code>. Always pass <code>bid_price</code> after a <code>type='bid'</code> search, otherwise the instance will be rented as an on-demand instance/price instead of as an interruptible.</p>\n<p>When outbid, the instance moves to <code>stopped</code> (not destroyed) and storage charges continue. Resume by raising the bid via <code>vast.change_bid(id=..., price=...)</code>.</p>\n<h3>Search</h3>\n<pre><code># Search GPU offers (use help(vast.search_offers) for full query syntax)\noffers = vast.search_offers(query='gpu_name=RTX_3090 num_gpus&gt;=2')\n\n# Search volume offers\nvolumes = vast.search_volumes(query='...')\n\n# Search network volumes\nnet_vols = vast.search_network_volumes()\n\n# Search templates\ntemplates = vast.search_templates()\n\n# Search invoices\ninvoices = vast.search_invoices()\n</code></pre>\n<h3>Data Transfer</h3>\n<pre><code># copy() takes vast URLs: \"[C.|V.]id:path\", \"cloud_service[.id]:path\", or \"local:path\"\nvast.copy(\"local:./data/\", \"C.12345:/workspace/data/\")   # Local → instance\nvast.copy(\"C.12345:/workspace/results/\", \"local:./out/\") # Instance → local\nvast.copy(\"12345:/workspace/\", \"67890:/workspace/\")      # Instance → instance (legacy format)\nvast.copy(\"s3.101:/data/\", \"C.12345:/workspace/\")        # Cloud service → instance\nvast.copy(\"V.1234:/file\", \"C.5678:/workspace/\")          # Volume → instance\nvast.copy(\"V.1234:/file\", \"s3.101:/workspace/\")          # Volume → cloud service\n\nvast.cancel_copy(dst_id=12345)                           # Cancel an in-progress copy\n\n# Cloud sync via a saved cloud connection (see the UI settings page for connection IDs)\nvast.cloud_copy(src=\"./data\", dst=\"s3://bucket/path\", instance=12345,\n                connection=&lt;conn_id&gt;, transfer=\"Instance To Cloud\")\nvast.cancel_sync(dst_id=12345)\n</code></pre>\n<p>Volume copy is currently only supported for copying to other volumes, instances, or cloud services, not local. Do not use <code>/root</code> or <code>/</code> as a destination directory — it breaks ssh permissions on the instance and future copies fail. See <a href=\"https://vast.ai/docs/gpu-instances/data-movement#constraints\">https://vast.ai/docs/gpu-instances/data-movement#constraints</a>.</p>\n<h3>Serverless Deployments</h3>\n<pre><code># List all deployments\ndeployments = vast.show_deployments()\n\n# Get a deployment\ndeployment = vast.show_deployment(id=42)\n\n# Delete a deployment\nvast.delete_deployment(id=42)\n</code></pre>\n<h3>Machine Management (Hosting)</h3>\n<pre><code>machines = vast.show_machines()\nmachine = vast.show_machine(id=10)\nvast.list_machine(id=10, price_gpu=0.30)\nvast.unlist_machine(id=10)\n</code></pre>\n<h3>SSH Keys</h3>\n<pre><code>keys = vast.show_ssh_keys()\nvast.create_ssh_key(ssh_key=\"ssh-rsa AAAA...\")\nvast.delete_ssh_key(id=5)\n</code></pre>\n<h3>Team Management</h3>\n<pre><code>members = vast.show_members()\nvast.invite_member(email=\"user@example.com\", role=\"developer\")\nvast.remove_member(id=7)\n</code></pre>\n<h2>SyncClient (Low-Level Sync)</h2>\n<p><code>SyncClient</code> provides typed, synchronous access to GPU offers and instances.</p>\n<pre><code>from vastai import SyncClient\n\nclient = SyncClient(api_key=\"YOUR_API_KEY\")  # or reads ~/.vast_api_key\n\n# Search offers with structured filters\noffers = client.search(\n    num_gpus=2,\n    gpu_name=\"RTX_4090\",\n    min_reliability=0.99,\n    max_dph_total=2.0,\n)\n\n# Create an instance (SyncClient takes an InstanceConfig, not loose kwargs)\nfrom vastai.data.instance import InstanceConfig\n\ninstance = client.create_instance(\n    offer_id=&lt;id&gt;,\n    config=InstanceConfig(image=\"pytorch/pytorch:latest\", disk=50),\n)\n\n# List your instances\ninstances = client.show_instances()  # returns list[SyncInstance]\n\n# Destroy an instance\nclient.destroy_instance(instance_or_id=12345)\n</code></pre>\n<h2>AsyncClient (Low-Level Async)</h2>\n<p><code>AsyncClient</code> provides async access to GPU offers and instances. Use as an async context manager.</p>\n<pre><code>import asyncio\nfrom vastai import AsyncClient\nfrom vastai.data.instance import InstanceConfig\n\nasync def main():\n    async with AsyncClient(api_key=\"YOUR_API_KEY\") as client:\n        # Search offers\n        offers = await client.search(num_gpus=1, gpu_name=\"A100\")\n\n        # Create instance\n        instance = await client.create_instance(\n            offer_id=&lt;id&gt;, config=InstanceConfig(image=\"ubuntu:22.04\"))\n\n        # List instances\n        instances = await client.show_instances()  # returns list[AsyncInstance]\n\n        # Destroy instance\n        await client.destroy_instance(instance_or_id=instance.id)\n\nasyncio.run(main())\n</code></pre>\n<h2>Serverless Client</h2>\n<p>For inference endpoints (requires <code>pip install \"vastai[serverless]\"</code>):</p>\n<pre><code>import asyncio\nfrom vastai import Serverless\n\nasync def main():\n    serverless = Serverless()  # reads ~/.vast_api_key\n\n    # Get an endpoint\n    endpoint = await serverless.get_endpoint(\"my-endpoint\")\n\n    # Make a request\n    response = await serverless.request(\"/v1/completions\", {\n        \"model\": \"Qwen/Qwen3-8B\",\n        \"prompt\": \"Who are you?\",\n        \"max_tokens\": 100,\n        \"temperature\": 0.7,\n    })\n\n    text = response[\"response\"][\"choices\"][0][\"text\"]\n    print(text)\n\nasyncio.run(main())\n</code></pre>\n<h2>Common Patterns</h2>\n<pre><code># Find cheapest 4x RTX 4090 and launch a job\nfrom vastai import VastAI\nvast = VastAI()\n\noffers = vast.search_offers(query='gpu_name=RTX_4090 num_gpus=4 reliability&gt;0.99')\ncheapest = min(offers, key=lambda o: o['dph_total'])\nresult = vast.create_instance(id=cheapest['id'], image=\"pytorch/pytorch:latest\", disk=100)\nprint(f\"Launched instance: {result['new_contract']}\")\n\n# Use help() to explore method signatures\nhelp(vast.search_offers)\nhelp(vast.create_instance)\n</code></pre>\n","files":[{"path":"__init__.py","sizeBytes":270,"isText":true},{"path":"SKILL.md","sizeBytes":7950,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"notes-only","suspicious":0,"notes":8,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-06T17:24:34.213164Z","sha256":"6E01AC174070F0CD6A81C057F7EC604912EB0B7CDFCA5AA8B0F7D5342465D923","sizeBytes":3268},"review":null,"source":{"repositoryUrl":"https://github.com/vast-ai/vast-cli","path":"vastai_sdk","license":"MIT","commit":"c9b69d4ec2be9644d6167ef0e0ab7eca2dd90f99","subtreeSha":"5D20925B420335C62F403CF2389377426837E81D4CAE087C038D6976623BF13B","lastSyncedAt":"2026-09-23T13:50:55.544478Z"},"reviewedAt":"2026-09-06T17:29:43.278043Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/vast-ai/vast-cli/tree/master/vastai_sdk"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install vast-ai-vast-cli@llmmart"},{"target":"git","command":"git clone https://github.com/vast-ai/vast-cli.git"}]}